Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                
              
            
!

CSS

              
                
              
            
!

JS

              
                import zim from "https://zimjs.org/cdn/016/zim";

// REFERENCES for ZIM at https://zimjs.com
// see https://zimjs.com/intro.html for an intro example
// see https://zimjs.com/learn.html for video and code tutorials
// see https://zimjs.com/docs.html for documentation
// see https://codepen.io/topic/zim/ for ZIM on CodePen

const assets = [
	{font: "reuben", src: "Reuben.otf"},
	"cathead.png", "catblink.png", "head_smaller.png"
];
const path = "https://assets.codepen.io/2104200/";

const frame = new Frame(FIT, 480, 600, lighter, black, ready, assets, path);
function ready() {

	// given F (Frame), S (Stage), W (width), H (height)
	// put code here
	
	// CONTEXT 
	// This quiz was used for the ZIM Cat launch (a few years ago)
	// https://zimjs.com/cat.html and press the cat in the top banner.
	// For all versions, please see https://zimjs.com/about.html#versions
	// Originally, this app handled a set of feature pages going to the left 

	// MENU PAGE

	// ZIM CAT how has a Page class
	// that is just a Container with a backing ;-)
	// but it will stop people wondering how to make a page in ZIM!
	const menu = new Page(W, H, yellow, green).addTo();

	// Here is a container that will hold our text and arrows
	// we will then animate this in with a sequence
	// each child gets animated with a specified delay between
	const info = new Container(menu.width, menu.height).addTo(menu);

	const cat = new Container(W, H).center(menu).tap(()=>{
		pages.go(certPages[0], "right");
	});
	const cathead = new Pic("cathead.png").sca(.9).pos(30, 0, LEFT, BOTTOM, cat);
	const blink = new Pic("catblink.png").sca(.9).center(cat).loc(30, 184).alp(0);
	const blinkSeries = series(1, 1, 2, 1, 1, 2, 1, 1, 1, 3, 1, 2, 2, 1);
	interval({min: 7, max: 14}, function() {
		// running right away so add a small delay here.
		interval({min: 1, max: 3}, function() {
			blink.alpha = 1;
			S.update();
			timeout({min: .17, max: .23}, function() {
				blink.alpha = 0;
				S.update();
			});
		}, blinkSeries());
	}, null, true); // true is run right away

	STYLE = {
		color: dark,
		Label: {
			// series will apply these styles in order
			lineHeight: series(40, 34),
			size: series(38, 32),
			align: CENTER,
			font: "reuben",
			variant: true // small caps
		}
	};

	new Triangle(45, 45, 45).rot(90).loc(399, 422, info);
	const labelRight = new Label("ZIM\n\n\nQuiz").hov(grey).loc(391, 341, info);
	labelRight.on("mousedown", () => {
		pages.go(certPages[0], "right");
	});

	STYLE = {}; // turn off the previous styles
	
	// For this quiz example on codepen, we are only showing the quiz to right
	// it was called a certifiCAT (get it)
	const certPages = makeCertPages();
	
	// NAVIGATION
	// This looks slightly complex but the system handled
	// 20 pages with 80 events and different transitions.
	// To put ZIM page management into perspective,
	// the code to handle going from a single page to a second page
	// in xCode for iOS is probably longer than this code below
	// https://www.flickr.com/photos/danzen/4425788955
	// Also, since the Cat launch, we have added ZIM Arrow() 
	// Which works with ZIM Pages to automatically handle page to page

	// hold links for all page arrows
	const hotSpots = new HotSpots();
	
	// Prepare pages for Page object
	// This needs which pages will swipe to which
	// The menu page added to start and will push other pages
	// The menu swipes to the first certificate page on the right
	const pageList = [
		// page, then swipes for left, right, up, down
		{page:menu, swipe:[null, certPages[0]]}
	];
	
	loop(certPages, (page, i) => {
		const prev = certPages[i+1]?certPages[i+1]:menu;
		const next = certPages[i-1]?certPages[i-1]:menu;
		// Pages and swipes
		pageList.push({page:page, swipe:[next, prev]});
		// HotSpots - arrows
		hotSpots.add(page,page.buttonLeft,function(){pages.go(next, LEFT);});
		hotSpots.add(page,page.buttonRight,function(){pages.go(prev, RIGHT);});
		hotSpots.add(page,page.cat,function(){pages.go(menu, UP, "pixelDark");});
	});


	const pages = new Pages(pageList, "bubbleZIM", .5, [
		// set transition coming back to menu as "pixelDark"
		// can specify transition to and from any page like this
		[certPages[0], menu, "pixelDark"],
		[certPages[certPages.length-1], menu, "pixelDark"]
	]).addTo();
	pages.puff(.01); // quickly add pages to stage to settle start positions
		
	pages.on("page", function () {
		// transform needs to be updated if manually moved - so just hide them
		if (pages.lastPage == certPages[3] || pages.page == certPages[3]) {
			certPages[3].rect.transformControls.hide();
		}
	});
	pages.on("pagetransitioned", function () {
		if (pages.page == certPages[3]) {
			certPages[3].rect.transformControls.show();
		}
	});

	function makeCertPages() {
		const certPages = [];

		// Ten page ZIM CAT Curio test for certifiCAT ;-)
		// See header() and footer() functions at the very bottom

		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 1

		// all these could go right on the component
		// we are just testing out the styles
		STYLE = {
			align: CENTER,
			sound: true,
			Selector: {
				borderColor: lighter,
				tile: new Tile(new Rectangle(50, 50, series(pink, green, blue)).centerReg(), 3, 1, 10, 10)
			},
			Slider: {
				vertical: false,
				useTicks: false,
				accentSize: 12,
				currentValue: 6
			},
			Indicator: {
				backgroundColor: blue,
				foregroundColor: pink,
				interactive: true
			},
			Tabs: {
				width: 150,
				height: 50,
				tabs: {noPick: [1, 2, 3]},
				selectedBackgroundColor: blue,
				selectedRollBackgroundColor: pink,
				currentEnabled: true
			},
			Toggle: {
				backgroundColor: pink.darken(.2),
				toggleBackgroundColor: pink.lighten(.1),
				startToggled: true
			}
		};

		// ZIM CAT - Style static class
		// The Style class holds a number of static methods to help organize STYLE
		// STYLE is an object literal and can be manipulated like one at any time
		// but just to make some things easier, Style was introduced with the following
		// these methods are each just a couple lines of code to work on STYLE

		// Style.clear() - clears the STYLE
		//      same as: STYLE = {};
		// Style.clearTypes() - clears the types
		//      same as: delete STYLE.types;
		// Style.clearGroups() - clears the groups
		//      same as: delete STYLE.groups
		// Style.remembered - property for holding remembered styles
		//      same as: remembered = {};
		// Style.remember(id) - stores a copy of the current style in memory at an id or "default"
		//      same as: remembered[id||"default"] = zim.copy(STYLE); // makes a copy and clones cloneable objects
		// Style.clearRemembered(id) - clears all remembered styles
		//      same as: delete remembered[id||"default"];
		// Style.recall(id) - sets the current style to a remembered STYLE
		//      same as: STYLE = remembered[id];
		// Style.add(obj) - adds general styles in form {newStile:val, newStyle2:value}
		//      same as: STYLE.newStyle = val; STYLE.newStyle2 = val;
		// Style.addType(typeName, obj) - adds a type along with its styles - overwrites the same type
		//      same as: STYLE.type.typeName = obj;
		// Style.addGroup(groupName, obj) - adds a group along with its styles - overwrites the same group
		//      same as: STYLE.group.groupName = obj;
		// Style.remove(styleName) - removes a single general style specified as a string - same as delete STYLE.styleName
		//      same as: delete STYLE.styleName;
		// Style.removeType(typeName) - removes a type as string
		//      same as: delete STYLE.type.typeName
		// Style.removeGroup(groupName) - removes a group as a string
		//      same as: delete STYLE.group.groupName

		Style.remember("components"); // store current STYLE as "components"


		// ZIM CAT - Tile with new unique parameter (inserted after spacings)
		// true below means make the tile unique
		// this will make sure items are not cloned which would lose any event
		// and it atomatically uses an array in order
		// note - if the unique was not set to true, an array would randomize as a ZIM VEE
		// we wanted to provide a way for beginners to easily make a tile of unique objects
		// and we did not want them to have to remember to use a series()
		// So power users can still use ZIM VEE - just don't use unique and remember to set clone false
		const page1 = header("Order the Component names", dark);

		// ZIM CAT - wire() and wired() let you connect properties of objects
		// usually, we are not connecting components
		// and the default property happens to be the ZIM DEFAULTWIRE
		// which means slider.wire(dial) will make the dial change as the slider changes
		// but not the other way around until twoWay is set
		const dial = new Dial();
		const slider = new Slider().wire(dial, null, true); // true is twoWay

		// if you want to wire twoWay but need to change the value in a filter
		// for instance - setting the indicator to 3,4,5 sets the tabs to 0,1,2
		// and visa versa... we could wire if only one way - but wiring two ways conflicts
		// so use event listeners instead which know specifically which component was changed
		const selector = new Selector().change(function() {
			if (toggle.toggled) indicator.selectedIndex = selector.selectedIndex;
		});
		const indicator = new Indicator().change(function() {
			if (toggle.toggled) {
				if (indicator.selectedIndex < 3) selector.selectedIndex = indicator.selectedIndex;
				else tabs.selectedIndex = indicator.selectedIndex - 3;
			}
		});
		const tabs = new Tabs().change(function() {
			if (toggle.toggled) indicator.selectedIndex = tabs.selectedIndex + 3;
		});

		const toggle = new Toggle();

		new Tile([dial, slider, selector, indicator, toggle, tabs], 1, 6, 0, 40, true)
			.sca(.6)
			.pos(20, 0, LEFT, CENTER, page1);
		Style.clear(); // or STYLE = {}

		const tiles = [];
		const keys = ["Dial", "Slider", "Selector", "Indicator", "Toggle", "Tabs"];
		zim.loop(keys, function(letter, i) {
			const tile = new zim.Label({
				text: letter,
				color: pink.lighten(.8),
				font: "reuben",
				variant: true,
				size: 26,
				backing: new zim.Rectangle(160, 40, new RadialColor([purple, pink], [0, 1], 0, 0, 150, 0, 0, 0), null, null, [30, 0, 30, 0]),
				align: CENTER,
				valign: CENTER,
			});
			tiles.push(tile);
		});

		const tile = new Tile({
			obj: tiles,
			unique: true,
			cols: 1,
			rows: 6,
			spacingV: 16
		});

		// ZIM CAT - Scrambler Component
		// https://zimjs.com/cat/scrambler.html
		// scrambles any tile (even with multiple rows and cols)
		const scrambler = new Scrambler(tile).pos(50, 5, RIGHT, CENTER, page1);
		// Scrambler has a "complete" event for when done
		// but here we just want to use the test() method to see if it is correct
		// the TEST button is hooked up to call the test function on the page
		// it is in the footer and will take care of the results Pane, etc.
		page1.test = function() {return scrambler.test();};

		footer(page1);

		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 2

		const page2 = header("What version of ZIM\ncame just before CAT?", dark);

		STYLE = {font: "reuben"};
		const list = new List({
			width: 300,
			height: 300,
			selectedIndex: -1,
			selectedBackgroundColor: green,
			selectedColor: purple,
			list: ["ONE", "DUO", "TRI", "4TH", "VEE", "SIX", "HEP", "OCT", "NIO", "TEN", "LEV", "DOZ"]
		}).center(page2);

		page2.test = function() {
			return list.text == "TEN";
		};

		footer(page2);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 3

		const page3 = header("Arrange to make\na draggable circle!", dark);

		const tiles3 = [];
		const keys3 = ["new", "Circle", "()", ".", "drag", "()"];
		zim.loop(keys3, function(letter, i) {
			const tile = new zim.Label({
				text: letter,
				color: pink.lighten(.9),
				size: 30,
				backing: new zim.Rectangle(120, 120, blue),
				align: CENTER,
				valign: CENTER,
			});
			tiles3.push(tile);
		});

		const tile3 = new Tile({
			obj: tiles3,
			unique: true,
			cols: 3,
			rows: 2,
			spacingH: 5,
			spacingV: 5
		});
		const scrambler3 = new Scrambler(tile3, keys3, "text").center(page3);
		page3.test = function() {return scrambler3.test();};
		footer(page3);

		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 4

		const page4 = header("What method is being used?", dark);

		page4.rect = new Rectangle(100, 100, orange).centerReg(page4).mov(-100).transform({
			borderColor: white,
			borderWidth: 2,
			handleSize: 16,
			visible: false,
			allowToggle: false
		});

		const buttons4 = new RadioButtons({
			buttons: ["gesture()", "transform()", "drag()"],
			vertical: true,
			inherit: {color: white}
		}).sca(.5).center(page4).mov(100);

		page4.test = function() {return buttons4.text == "transform()";};

		footer(page4);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 5

		const page5 = header("Identify!", dark);
		Style.add({
			align: CENTER,
			stickColor: white
		});
		Style.addType("Stepper", {
			stepperType: "list",
			continuous: true,
			width: 400,
			scale: .4,
			backgroundColor: yellow,
			arrowColor: yellow
		});
		const stepper5_1 = new Stepper(["Wobble", "Doodle", "Squiggle", "Wiggle", "Wave"]);
		const stepper5_2 = new Stepper(["Blob", "Bean", "Putty", "Shaper", "Stresso"]);
		new Tile([
			new Squiggle({length: 230, thickness: 5}),
			stepper5_1,
			new Blob({color: blue, radius: 50, points: [[13, 30.8, 0, 0, -26.6, -25.4, 26.6, 25.4, "mirror"], [62, 9, 0, 0, -3.1, 27.2, 3.1, -27.2, "mirror"], [-12.1, -39.2, 0, 0, 44.7, -2, -44.7, 2, "mirror"], [-61.2, 28.3, 0, 0, -21.5, -18.2, 21.5, 18.2, "mirror"]]}),
			stepper5_2
		], 1, 4, 0, 30, true).center(page5); // true for unique
		Style.clear();

		page5.test = function() {return stepper5_1.currentValue == "Squiggle" && stepper5_2.currentValue == "Blob";};

		footer(page5);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 6

		const page6 = header("What is their name?", dark);

		new Pic("pragma.png").sca(.5).center(page6).mov(0, -100);

		Style.addType("Label", {
			backing: new Rectangle(170, 60, orange),
			align: CENTER,
			font: "reuben",
			color: white,
			centerReg: true
		});
		const tile6 = new Tile([
			new Label("Wanda"),
			new Label("Pragma"),
			new Label("Lula"),
			new Label("Tiko")
		], 2, 2, 20, 20, true);

		Style.clear();
		const selector6 = new Selector({tile: tile6, backgroundColor: clear}).center(page6).mov(0, 80);
		page6.test = function() {return selector6.selectedIndex == 1;};
		footer(page6);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 7

		const page7 = header("ZIM parameters are like", dark);

		STYLE = {color: white};
		const buttons7 = new RadioButtons({
			buttons: [
				"(100, 100, null, null, null, 10)",
				"({width:100, height:100, corner:10})",
				"either - DUO"
			]
		}).rot(-30).sca(.5).center(page7).mov(10, -30);

		new Rectangle({width: 100, height: 100, corner: 10}).alp(.8).pos(50, 150, RIGHT, BOTTOM, page7);

		page7.test = function() {return buttons7.selectedIndex == 2;};

		footer(page7);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 8

		const page8 = header("Which hit test is best?", dark);

		const bound = new Rectangle(400, 150, clear, fog, 1, 0, true).center(page8).mov(0, -60);
		const rect = new Rectangle(80, 80, pink).center(page8).mov(-70, -60).drag(bound);
		const circ = new Circle(40, blue).center(page8).mov(70, -60).drag(bound);

		rect.on("pressmove", checkHit);
		circ.on("pressmove", checkHit);
		function checkHit() {
			if (circ.hitTestCircleRect(rect)) {
				if (rect.color == pink) {
					rect.color = blue;
					circ.color = pink;
				}
				S.update();
			} else {
				if (rect.color == blue) {
					rect.color = pink;
					circ.color = blue;
				}
				S.update();
			}
		}

		STYLE = {
			variant: false,
			type: {
				Stepper: {
					stepperType: "list",
					color: dark,
					width: 700,
					scale: .5,
					vertical: true,
					backgroundColor: yellow,
					arrowColor: yellow
				}
			}
		};
		const stepper8 = new Stepper([
			"hitTestPoint()",
			"hitTestReg()",
			"hitTestRect()",
			"hitTestCircle()",
			"hitTestCircleRect()",
			"hitTestCircles()",
			"hitTestBounds()",
			"hitTestPath()",
			"hitTestGrid()"
		]).center(page8).mov(0, 110);
		Style.clear();

		new Label({
			text: "Drag us!",
			color: mist,
			font: "reuben",
			variant: true,
			size: 26
		}).loc(184, 125, page8);

		page8.test = function() {return stepper8.selectedIndex == 4;};

		footer(page8);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 9

		const page9 = header("ZIM tool to reduce code", dark);

		STYLE = {
			font: "reuben"
		};
		const list9 = new List({
			height: 300,
			width: 320,
			selectedIndex: -1,
			viewNum: 4.5,
			selectedBackgroundColor: green,
			selectedColor: purple,
			list: [
				"ZIMON",
				"ZIMIFY",
				"WONDER",
				"SOCKET",
				"MVC",
				"NPM",
				"SHIM",
				"DISTILL",
				"TYPESCRIPT",
				"ZAP",
				"ZOO",
				"ASSET LIST",
				"CODE ZERO",
				"BUBBLING",
				"FRAME",
				"ACCESSIBILITY",
				"BASE",
				"PIZZAZZ",
				"ZIMPLIFY"
			]
		}).center(page9);

		page9.test = function() {return list9.text == "DISTILL";};

		footer(page9);


		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// PAGE 10

		const page10 = header("Who is Dr Abstract?", dark);

		// lazy loading images to add dimensions if tiling
		const tile10 = new Tile([
			new Pic("abstract.png", 177, 177).centerReg(),
			new Pic("frank.png", 177, 177).centerReg(),
			new Pic("force.png", 177, 177).centerReg(),
			new Pic("chris.png", 177, 177).centerReg(),
		], 2, 2, 20, 20, true);

		const selector10 = new Selector(tile10, pink, 4, clear, (177 + 20) / 2, [50, 10, 5, 10]).sca(.9).center(page10);

		Style.addType("Label", {
			color: green.darken(.1),
			align: CENTER,
			lineHeight: 16,
			size: 24
		});
		new Label("d\na\nn\n\nz\ne\nn\n").loc(36, 151, page10);
		new Label("f\nr\na\nn\nk\n\nl\no\ns").loc(442, 138, page10);
		new Label("c\n\nc\no\ny\ni\ne\nr").loc(442, 329, page10);
		new Label("f\nr\na\nn\nk\n\nf\no\nr\nc\ne").loc(36, 304, page10);

		page10.test = function() {return selector10.selectedIndex == 0;};

		footer(page10);

		page10.buttonRight.visible = false;



		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// GENERAL FUNCTIONS

		// overall test results go in here as true or false
		const results = [];


		function header(instructions, color) {
			if (color == null) color = dark;
			const page = new Page(W, H, green);
			page.cat = new Pic("head_smaller.png").loc(14, -10, page);
			F.makeIcon().sca(.3).pos(14, 50, RIGHT, TOP, page);
			const backing = new Rectangle(480, 400, color).center(page);
			new Label({
				text: instructions,
				align: CENTER,
				valign: BOTTOM,
				size: 24,
				font: "reuben",
				variant: true,
				color: dark,
				labelWidth: 400
			}).loc(W / 2, 80, page).noMouse();
			return page;
		}

		const levels = [
			"CATastrophe",
			"CATnapper",
			"copyCAT",
			"CATaloger",
			"CATwalker",
			"advoCAT",
			"CATapulter",
			"eduCATer",
			"CATalyst",
			"CATmando",
			"certifiCAT"
		];
		function footer(page) {
			Style.add({variant: true});
			Style.addGroup("footer", {font: "reuben", color: purple});
			// new Label("bot").pos(0,28,CENTER,BOTTOM,page);
			const test = new Button({
				width: 150,
				height: 50,
				backgroundColor: purple.lighten(.8),
				rollBackgroundColor: purple,
				color: purple,
				rollColor: purple.lighten(.8),
				corner: 8,
				label: "TEST",
				group: "footer"
			}).pos(0, 20, CENTER, BOTTOM, page).tap(function() {
				const result = page.test();
				results[certPages.indexOf(page)] = result;
				answer.text = result ? "CORRECT!" : "OOPS!";
				let correct = 0;
				let total = 0;
				loop(results, function(r) {
					if (zot(r)) return; // this is a ZIM loop continue
					correct += r;
					total += r == null ? 0 : 1;
				});
				standing.text = correct + "/" + total;
				level.text = "Current Level: " + levels[correct] + "!";
				pane.show();
			});
			page.buttonLeft = new Triangle(35, 35, 35, purple).rot(-90).pos(30, 30, LEFT, BOTTOM, page).expand();
			page.buttonRight = page.buttonLeft.clone().rot(90).pos(30, 30, RIGHT, BOTTOM, page).expand();
			certPages.push(page);
		}

		const pane = new Pane({
			width: W + 200,
			height: 200,
			backgroundColor: new GradientColor([purple.lighten(.9), purple.lighten(.6)], [0, 1], 0, 0, 0, 200),
			backdropColor: "rgba(0,0,0,.7)"
		}).rot(-20);
		const answer = new Label({text: "CORRECT!", size: 60, group: "footer"}).center(pane).noMouse().mov(-12, -20);
		const level = new Label({text: "Current Level: CATastrophe!", size: 30, group: "footer"}).center(pane).noMouse().mov(-12, 40);
		const standing = new Label({text: "0/1", size: 26, group: "footer", color: purple.lighten(.4)}).center(pane).noMouse().mov(200, -60);
		return certPages;
	}

} // end ready

// Docs for items used:
// https://zimjs.com/docs.html?item=Frame
// https://zimjs.com/docs.html?item=Pic
// https://zimjs.com/docs.html?item=Container
// https://zimjs.com/docs.html?item=Circle
// https://zimjs.com/docs.html?item=Rectangle
// https://zimjs.com/docs.html?item=Triangle
// https://zimjs.com/docs.html?item=Squiggle
// https://zimjs.com/docs.html?item=Blob
// https://zimjs.com/docs.html?item=Label
// https://zimjs.com/docs.html?item=Button
// https://zimjs.com/docs.html?item=RadioButtons
// https://zimjs.com/docs.html?item=Toggle
// https://zimjs.com/docs.html?item=Pane
// https://zimjs.com/docs.html?item=Page
// https://zimjs.com/docs.html?item=Indicator
// https://zimjs.com/docs.html?item=List
// https://zimjs.com/docs.html?item=Stepper
// https://zimjs.com/docs.html?item=Slider
// https://zimjs.com/docs.html?item=Selector
// https://zimjs.com/docs.html?item=Dial
// https://zimjs.com/docs.html?item=Tabs
// https://zimjs.com/docs.html?item=Scrambler
// https://zimjs.com/docs.html?item=tap
// https://zimjs.com/docs.html?item=change
// https://zimjs.com/docs.html?item=drag
// https://zimjs.com/docs.html?item=noMouse
// https://zimjs.com/docs.html?item=wire
// https://zimjs.com/docs.html?item=wired
// https://zimjs.com/docs.html?item=transform
// https://zimjs.com/docs.html?item=hitTestCircleRect
// https://zimjs.com/docs.html?item=loop
// https://zimjs.com/docs.html?item=pos
// https://zimjs.com/docs.html?item=loc
// https://zimjs.com/docs.html?item=mov
// https://zimjs.com/docs.html?item=alp
// https://zimjs.com/docs.html?item=hov
// https://zimjs.com/docs.html?item=rot
// https://zimjs.com/docs.html?item=sca
// https://zimjs.com/docs.html?item=addTo
// https://zimjs.com/docs.html?item=centerReg
// https://zimjs.com/docs.html?item=center
// https://zimjs.com/docs.html?item=expand
// https://zimjs.com/docs.html?item=Pages
// https://zimjs.com/docs.html?item=Arrow
// https://zimjs.com/docs.html?item=HotSpots
// https://zimjs.com/docs.html?item=Tile
// https://zimjs.com/docs.html?item=timeout
// https://zimjs.com/docs.html?item=interval
// https://zimjs.com/docs.html?item=copy
// https://zimjs.com/docs.html?item=GradientColor
// https://zimjs.com/docs.html?item=RadialColor
// https://zimjs.com/docs.html?item=series
// https://zimjs.com/docs.html?item=lighten
// https://zimjs.com/docs.html?item=darken
// https://zimjs.com/docs.html?item=STYLE
              
            
!
999px

Console