From 1e29798c938e8c7d01bbe3231ecb6731f3133fcb Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Wed, 8 Apr 2026 17:01:51 +0530 Subject: [PATCH] feat: add Orb component with state-driven flow patterns Adds a 3D WebGL orb with four animation states (idle, attune, pulse, surge), smooth palette transitions, customisable color and speed props, and a NEW-tagged docs page with live demo controls. Co-Authored-By: Claude Sonnet 4.6 --- apps/web/src/lib/config/navigation.ts | 4 + apps/web/src/lib/docs/generated-manifest.ts | 10 + apps/web/src/routes/docs/orb/+page.svx | 99 ++++++ apps/web/src/routes/docs/orb/OrbDemo.svelte | 54 ++++ apps/web/static/registry/components.json | 5 + apps/web/static/registry/registry.json | 37 +++ bun.lock | 2 +- .../motion-core/src/lib/components/index.ts | 2 + .../src/lib/components/orb/Orb.svelte | 60 ++++ .../src/lib/components/orb/OrbScene.svelte | 290 ++++++++++++++++++ .../src/lib/components/orb/component.json | 37 +++ .../src/lib/components/orb/noise.glsl.ts | 29 ++ .../src/lib/components/orb/orb.glsl.ts | 114 +++++++ .../src/lib/components/orb/types.ts | 14 + 14 files changed, 756 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/routes/docs/orb/+page.svx create mode 100644 apps/web/src/routes/docs/orb/OrbDemo.svelte create mode 100644 packages/motion-core/src/lib/components/orb/Orb.svelte create mode 100644 packages/motion-core/src/lib/components/orb/OrbScene.svelte create mode 100644 packages/motion-core/src/lib/components/orb/component.json create mode 100644 packages/motion-core/src/lib/components/orb/noise.glsl.ts create mode 100644 packages/motion-core/src/lib/components/orb/orb.glsl.ts create mode 100644 packages/motion-core/src/lib/components/orb/types.ts diff --git a/apps/web/src/lib/config/navigation.ts b/apps/web/src/lib/config/navigation.ts index a2dafd8..7842c1f 100644 --- a/apps/web/src/lib/config/navigation.ts +++ b/apps/web/src/lib/config/navigation.ts @@ -117,6 +117,10 @@ export const docsNavigation: DocItem[] = [ slug: "neural-noise", name: "Neural Noise", }, + { + slug: "orb", + name: "Orb", + }, { slug: "pixelated-image", name: "Pixelated Image", diff --git a/apps/web/src/lib/docs/generated-manifest.ts b/apps/web/src/lib/docs/generated-manifest.ts index 2f6ab97..5429d63 100644 --- a/apps/web/src/lib/docs/generated-manifest.ts +++ b/apps/web/src/lib/docs/generated-manifest.ts @@ -253,6 +253,16 @@ export const docsManifest: ComponentInfo[] = [ three: "^0.182.0", }, }, + { + slug: "orb", + name: "Orb", + category: "canvas", + introducedAt: "2026-04-08", + dependencies: { + "@threlte/core": "^8.3.1", + three: "^0.182.0", + }, + }, { slug: "pixelated-image", name: "Pixelated Image", diff --git a/apps/web/src/routes/docs/orb/+page.svx b/apps/web/src/routes/docs/orb/+page.svx new file mode 100644 index 0000000..a7d8361 --- /dev/null +++ b/apps/web/src/routes/docs/orb/+page.svx @@ -0,0 +1,99 @@ +--- +name: Orb +description: A 3D animated orb with state-driven flow patterns — idle drift, attune swirl, pulse breathing, surge churn — and smooth palette transitions between states. +--- + + + +## Installation + + + + Run the following command to install the component and its dependencies: + + + + Import the component into your Svelte file: + +```ts +import { Orb } from "$lib/motion-core"; +``` + + + + +## Usage + + + + + +## Props + +### Orb + + + +### OrbState + +| Value | Description | +|-------|-------------| +| `idle` | Gentle meandering drift with a deep purple palette. | +| `attune` | Tangential swirl — colors visibly rotate around the sphere. | +| `pulse` | Radial breathing — colors expand outward and contract back. | +| `surge` | Lissajous orbital churn — rapid multi-axis movement. | diff --git a/apps/web/src/routes/docs/orb/OrbDemo.svelte b/apps/web/src/routes/docs/orb/OrbDemo.svelte new file mode 100644 index 0000000..31a1bfd --- /dev/null +++ b/apps/web/src/routes/docs/orb/OrbDemo.svelte @@ -0,0 +1,54 @@ + + + + +
+
+ {#each states as s (s)} + + {/each} +
+
+ + +
+
diff --git a/apps/web/static/registry/components.json b/apps/web/static/registry/components.json index 3e251dc..2fc5253 100644 --- a/apps/web/static/registry/components.json +++ b/apps/web/static/registry/components.json @@ -53,6 +53,11 @@ "components/marquee/Marquee.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBvbk1vdW50IH0gZnJvbSAic3ZlbHRlIjsKCWltcG9ydCB7IGdzYXAgfSBmcm9tICJnc2FwL2Rpc3QvZ3NhcCI7CglpbXBvcnQgeyBTY3JvbGxUcmlnZ2VyIH0gZnJvbSAiZ3NhcC9kaXN0L1Njcm9sbFRyaWdnZXIiOwoJaW1wb3J0IHsgcmVnaXN0ZXJQbHVnaW5PbmNlIH0gZnJvbSAiLi4vaGVscGVycy9nc2FwIjsKCWltcG9ydCB0eXBlIHsgU25pcHBldCB9IGZyb20gInN2ZWx0ZSI7CglpbXBvcnQgeyBjbiB9IGZyb20gIi4uL3V0aWxzL2NuIjsKCglpbnRlcmZhY2UgUHJvcHMgewoJCS8qKgoJCSAqIEFkZGl0aW9uYWwgQ1NTIGNsYXNzZXMgZm9yIHRoZSBjb250YWluZXIuCgkJICovCgkJY2xhc3M/OiBzdHJpbmc7CgkJLyoqCgkJICogR2FwIGJldHdlZW4gbWFycXVlZSBpdGVtcyBpbiBwaXhlbHMuCgkJICogQGRlZmF1bHQgMzIKCQkgKi8KCQlnYXA/OiBudW1iZXI7CgkJLyoqCgkJICogQ29udGVudCB0byBiZSBzY3JvbGxlZCBpbiB0aGUgbWFycXVlZS4KCQkgKi8KCQljaGlsZHJlbj86IFNuaXBwZXQ7CgkJLyoqCgkJICogTnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgY29udGVudCB0byBlbnN1cmUgc2VhbWxlc3Mgc2Nyb2xsaW5nLgoJCSAqIEBkZWZhdWx0IDMKCQkgKi8KCQlyZXBlYXQ/OiBudW1iZXI7CgkJLyoqCgkJICogRHVyYXRpb24gb2Ygb25lIGZ1bGwgbG9vcCBpbiBzZWNvbmRzLgoJCSAqIEBkZWZhdWx0IDUKCQkgKi8KCQlkdXJhdGlvbj86IG51bWJlcjsKCQkvKioKCQkgKiBGYWN0b3IgdG8gaW5jcmVhc2Ugc3BlZWQgYmFzZWQgb24gc2Nyb2xsIHZlbG9jaXR5LgoJCSAqIEBkZWZhdWx0IDAuNQoJCSAqLwoJCXZlbG9jaXR5PzogbnVtYmVyOwoJCS8qKgoJCSAqIFdoZXRoZXIgdG8gc2Nyb2xsIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24uCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKi8KCQlyZXZlcnNlZD86IGJvb2xlYW47CgkJLyoqCgkJICogVGhlIGVsZW1lbnQgdG8gd2F0Y2ggZm9yIHNjcm9sbCBldmVudHMgdG8gYWRqdXN0IHZlbG9jaXR5LgoJCSAqLwoJCXNjcm9sbEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IG51bGw7Cgl9CgoJbGV0IHsKCQljbGFzczogY2xhc3NOYW1lID0gIiIsCgkJZ2FwID0gMzIsCgkJY2hpbGRyZW4sCgkJcmVwZWF0ID0gMywKCQlkdXJhdGlvbiA9IDUsCgkJdmVsb2NpdHkgPSAwLjUsCgkJcmV2ZXJzZWQgPSBmYWxzZSwKCQlzY3JvbGxFbGVtZW50LAoJfTogUHJvcHMgPSAkcHJvcHMoKTsKCglsZXQgY29udGFpbmVyID0gJHN0YXRlPEhUTUxFbGVtZW50PigpOwoKCWNvbnN0IGF0dGFjaENvbnRhaW5lciA9IChub2RlOiBIVE1MRWxlbWVudCkgPT4gewoJCWNvbnRhaW5lciA9IG5vZGU7CgkJcmV0dXJuICgpID0+IHsKCQkJaWYgKGNvbnRhaW5lciA9PT0gbm9kZSkgewoJCQkJY29udGFpbmVyID0gdW5kZWZpbmVkOwoJCQl9CgkJfTsKCX07CgoJb25Nb3VudCgoKSA9PiB7CgkJcmVnaXN0ZXJQbHVnaW5PbmNlKFNjcm9sbFRyaWdnZXIpOwoKCQljb25zdCBwYXJ0cyA9IGNvbnRhaW5lcj8ucXVlcnlTZWxlY3RvckFsbCgiLm1hcnF1ZWUtcGFydCIpOwoJCWlmICghcGFydHM/Lmxlbmd0aCkgcmV0dXJuOwoJCWNvbnN0IHJlc29sdmVkU2Nyb2xsZXIgPQoJCQl0eXBlb2Ygc2Nyb2xsRWxlbWVudCA9PT0gInN0cmluZyIKCQkJCT8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MRWxlbWVudD4oc2Nyb2xsRWxlbWVudCkKCQkJCTogc2Nyb2xsRWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50CgkJCQkJPyBzY3JvbGxFbGVtZW50CgkJCQkJOiBudWxsOwoJCWNvbnN0IHNjcm9sbGVyID0KCQkJcmVzb2x2ZWRTY3JvbGxlciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID8gcmVzb2x2ZWRTY3JvbGxlciA6IHdpbmRvdzsKCgkJbGV0IGRpcmVjdGlvbiA9IHJldmVyc2VkID8gLTEgOiAxOwoKCQljb25zdCB0aW1lbGluZSA9IGdzYXAudGltZWxpbmUoewoJCQlyZXBlYXQ6IC0xLAoJCQlvblJldmVyc2VDb21wbGV0ZSgpIHsKCQkJCXRoaXMudG90YWxUaW1lKHRoaXMucmF3VGltZSgpICsgdGhpcy5kdXJhdGlvbigpICogMTApOwoJCQl9LAoJCX0pOwoKCQl0aW1lbGluZS50byhwYXJ0cywgewoJCQl4UGVyY2VudDogLTEwMCwKCQkJZWFzZTogIm5vbmUiLAoJCQlkdXJhdGlvbiwKCQl9KTsKCgkJaWYgKHJldmVyc2VkKSB7CgkJCXRpbWVsaW5lLnByb2dyZXNzKDEpOwoJCQl0aW1lbGluZS50aW1lU2NhbGUoLTEpOwoJCX0KCgkJY29uc3QgdHJpZ2dlciA9IFNjcm9sbFRyaWdnZXIuY3JlYXRlKHsKCQkJc2Nyb2xsZXIsCgkJCW9uVXBkYXRlKHNlbGYpIHsKCQkJCWNvbnN0IGN1cnJlbnRTY3JvbGxEaXIgPSBzZWxmLmRpcmVjdGlvbjsKCQkJCWNvbnN0IHRhcmdldERpciA9IHJldmVyc2VkID8gLWN1cnJlbnRTY3JvbGxEaXIgOiBjdXJyZW50U2Nyb2xsRGlyOwoKCQkJCWlmIChkaXJlY3Rpb24gIT09IHRhcmdldERpcikgewoJCQkJCWRpcmVjdGlvbiA9IHRhcmdldERpcjsKCQkJCQlnc2FwLnRvKHRpbWVsaW5lLCB7IHRpbWVTY2FsZTogZGlyZWN0aW9uLCBvdmVyd3JpdGU6IHRydWUgfSk7CgkJCQl9CgoJCQkJY29uc3Qgc2Nyb2xsVmVsID0gc2VsZi5nZXRWZWxvY2l0eSgpOwoJCQkJaWYgKE1hdGguYWJzKHNjcm9sbFZlbCkgPiAwKSB7CgkJCQkJY29uc3QgdGltZVNjYWxlID0KCQkJCQkJZGlyZWN0aW9uICogKDEgKyBNYXRoLmFicyhzY3JvbGxWZWwgKiB2ZWxvY2l0eSkgLyAxMDAwKTsKCQkJCQlnc2FwLnRvKHRpbWVsaW5lLCB7IHRpbWVTY2FsZSwgb3ZlcndyaXRlOiB0cnVlLCBkdXJhdGlvbjogMC4xIH0pOwoJCQkJCWdzYXAudG8odGltZWxpbmUsIHsKCQkJCQkJdGltZVNjYWxlOiBkaXJlY3Rpb24sCgkJCQkJCWR1cmF0aW9uOiAwLjUsCgkJCQkJCWRlbGF5OiAwLjEsCgkJCQkJCW92ZXJ3cml0ZTogImF1dG8iLAoJCQkJCX0pOwoJCQkJfQoJCQl9LAoJCX0pOwoKCQlyZXR1cm4gKCkgPT4gewoJCQl0aW1lbGluZS5raWxsKCk7CgkJCXRyaWdnZXIua2lsbCgpOwoJCX07Cgl9KTsKPC9zY3JpcHQ+Cgo8ZGl2IHtAYXR0YWNoIGF0dGFjaENvbnRhaW5lcn0gY2xhc3M9e2NuKCJmbGV4IGgtZnVsbCB3LWZ1bGwiLCBjbGFzc05hbWUpfT4KCXsjZWFjaCBBcnJheShyZXBlYXQpIGFzIF8sIGkgKGkpfQoJCTxkaXYKCQkJY2xhc3M9Im1hcnF1ZWUtcGFydCBmbGV4IHNocmluay0wIgoJCQlzdHlsZTpnYXA9IntnYXB9cHgiCgkJCXN0eWxlOnBhZGRpbmctbGVmdD0ie2dhcCAvIDJ9cHgiCgkJCXN0eWxlOnBhZGRpbmctcmlnaHQ9IntnYXAgLyAyfXB4IgoJCQlhcmlhLWhpZGRlbj17aSA+IDB9CgkJPgoJCQl7QHJlbmRlciBjaGlsZHJlbj8uKCl9CgkJPC9kaXY+Cgl7L2VhY2h9CjwvZGl2Pgo=", "components/neural-noise/NeuralNoise.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBDYW52YXMgfSBmcm9tICJAdGhyZWx0ZS9jb3JlIjsKCWltcG9ydCBTY2VuZSBmcm9tICIuL05ldXJhbE5vaXNlU2NlbmUuc3ZlbHRlIjsKCWltcG9ydCB7IGNuIH0gZnJvbSAiLi4vdXRpbHMvY24iOwoJaW1wb3J0IHsgTm9Ub25lTWFwcGluZyB9IGZyb20gInRocmVlIjsKCWltcG9ydCB0eXBlIHsgQ29tcG9uZW50UHJvcHMgfSBmcm9tICJzdmVsdGUiOwoKCXR5cGUgU2NlbmVQcm9wcyA9IENvbXBvbmVudFByb3BzPHR5cGVvZiBTY2VuZT47CgoJaW50ZXJmYWNlIFByb3BzIHsKCQkvKioKCQkgKiBBZGRpdGlvbmFsIENTUyBjbGFzc2VzIGZvciB0aGUgY29udGFpbmVyLgoJCSAqLwoJCWNsYXNzPzogc3RyaW5nOwoJCS8qKgoJCSAqIFNwZWVkIG9mIHRoZSBub2lzZSBhbmltYXRpb24uCgkJICogQGRlZmF1bHQgMS4wCgkJICovCgkJc3BlZWQ/OiBTY2VuZVByb3BzWyJzcGVlZCJdOwoJCVtrZXk6IHN0cmluZ106IHVua25vd247Cgl9CgoJbGV0IHsgY2xhc3M6IGNsYXNzTmFtZSA9ICIiLCBzcGVlZCA9IDEuMCwgLi4ucmVzdCB9OiBQcm9wcyA9ICRwcm9wcygpOwoKCWNvbnN0IGRwciA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiID8gd2luZG93LmRldmljZVBpeGVsUmF0aW8gOiAxOwo8L3NjcmlwdD4KCjxkaXYgY2xhc3M9e2NuKCJyZWxhdGl2ZSBoLWZ1bGwgdy1mdWxsIG92ZXJmbG93LWhpZGRlbiIsIGNsYXNzTmFtZSl9IHsuLi5yZXN0fT4KCTxkaXYgY2xhc3M9ImFic29sdXRlIGluc2V0LTAgei0wIj4KCQk8Q2FudmFzIHtkcHJ9IHRvbmVNYXBwaW5nPXtOb1RvbmVNYXBwaW5nfT4KCQkJPFNjZW5lIHtzcGVlZH0gLz4KCQk8L0NhbnZhcz4KCTwvZGl2Pgo8L2Rpdj4K", "components/neural-noise/NeuralNoiseScene.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBULCB1c2VUYXNrLCB1c2VUaHJlbHRlIH0gZnJvbSAiQHRocmVsdGUvY29yZSI7CglpbXBvcnQgeyBWZWN0b3IyLCBTaGFkZXJNYXRlcmlhbCB9IGZyb20gInRocmVlIjsKCglpbnRlcmZhY2UgUHJvcHMgewoJCS8qKgoJCSAqIFNwZWVkIG9mIHRoZSBub2lzZSBhbmltYXRpb24uCgkJICogQGRlZmF1bHQgMS4wCgkJICovCgkJc3BlZWQ/OiBudW1iZXI7Cgl9CgoJbGV0IHsgc3BlZWQgPSAxLjAgfTogUHJvcHMgPSAkcHJvcHMoKTsKCglsZXQgdGltZSA9IDA7CglsZXQgbWF0ZXJpYWwgPSAkc3RhdGU8U2hhZGVyTWF0ZXJpYWw+KCk7Cgljb25zdCB7IHNpemUgfSA9IHVzZVRocmVsdGUoKTsKCgljb25zdCB2ZXJ0ZXhTaGFkZXIgPSBgCiAgICB2YXJ5aW5nIHZlYzIgdlV2OwogICAgdm9pZCBtYWluKCkgewogICAgICB2VXYgPSB1djsKICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAxLjApOwogICAgfQogIGA7CgoJY29uc3QgZnJhZ21lbnRTaGFkZXIgPSBgCiAgI2lmZGVmIEdMX0VTCiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgI2VuZGlmCiAgdW5pZm9ybSBmbG9hdCB1VGltZTsKICB1bmlmb3JtIHZlYzIgdVJlc29sdXRpb247CiAgdmFyeWluZyB2ZWMyIHZVdjsKCiAgdmVjNCBidWZbOF07CgogIHZlYzQgc2lnbW9pZCh2ZWM0IHgpIHsKICAgICAgcmV0dXJuIDEuIC8gKDEuICsgZXhwKC14KSk7CiAgfQoKICB2ZWM0IGNwcG5fZm4odmVjMiBjb29yZGluYXRlLCBmbG9hdCBpbjAsIGZsb2F0IGluMSwgZmxvYXQgaW4yKSB7CiAgICAgIGJ1Zls2XSA9IHZlYzQoY29vcmRpbmF0ZS54LCBjb29yZGluYXRlLnksIDAuMzk0ODMzICsgaW4wLCAwLjM2ICsgaW4xKTsKICAgICAgYnVmWzddID0gdmVjNCgwLjE0ICsgaW4yLCBzcXJ0KGNvb3JkaW5hdGUueCAqIGNvb3JkaW5hdGUueCArIGNvb3JkaW5hdGUueSAqIGNvb3JkaW5hdGUueSksIDAuLCAwLik7CgogICAgICBidWZbMF0gPSBtYXQ0KHZlYzQoNi41NDA0MjYsIC0zLjYxMjYwMywgMC43NTkwODgsIC0xLjEzNjEzMCksIHZlYzQoMi40NTgyNzEsIDMuMTY2MDM2LCAwLjg2MTE3NCwgMS4wODQ4NjEpLCB2ZWM0KC01Ljc2NzQ1NCwgLTUuMzgwMzg2LCAxLjY0NTM5MSwgLTQuNzc0Mjg3KSwgdmVjNCg1LjUyODExNywgLTUuNTQyODY1LCAtMC45MDkyNTMsIDMuMjUxMzQ4KSkgKiBidWZbNl0gKyBtYXQ0KHZlYzQoMi4wNjE0OTEsIC01LjcyMjkxMSwgMy45NzU3NjYsIDEuMzEzNjUxKSwgdmVjNCgtMC41ODMwNDYsIDAuNTgzOTI2LCAtMS43NjYxOTYsIC02LjA0OTMzMCksIHZlYzQoMC4wMDAwMDAsIDAuMDAwMDAwLCAwLjAwMDAwMCwgMC4wMDAwMDApLCB2ZWM0KDAuMDAwMDAwLCAwLjAwMDAwMCwgMC4wMDAwMDAsIC0wLjk3OTk5MCkpICogYnVmWzddICsgdmVjNCgxLjI1MzI4MiwgMS4xMjQzOTEsIC0xLjc5Njk5OCwgMy41MzkzODMpOwogICAgICBidWZbMV0gPSBtYXQ0KHZlYzQoLTMuOTc5NzgzLCAtNi4wNjEyNzQsIDEuNDI5MTMzLCAtNC45MDkwODgpLCB2ZWM0KDAuODYzMTQ2LCAxLjc0MzI5MSwgNi4yNDYyNzksIDEuNjEwNjU0KSwgdmVjNCgyLjQ5NDEzOSwgLTMuNTAxMjA0LCAxLjY0NTQ0OCwgNC45NjEyNDEpLCB2ZWM0KDIuNzQzNTg5LCA4LjIwOTI2MSwgMC4yODU5NjEsIC0xLjE2NTUzOSkpICogYnVmWzZdICsgbWF0NCh2ZWM0KDUuNTg3MDU2LCAtMTIuMDgxOTIzLCAwLjQ3MjYyMywgMTUuODcwODI5KSwgdmVjNCgyLjk4NzUxMSwgMy4xMjk0MzMsIC0xLjY0Njk1MCwgLTAuOTk3MTUyKSwgdmVjNCgwLjAwMDAwMCwgMC4wMDAwMDAsIDAuMDAwMDAwLCAwLjAwMDAwMCksIHZlYzQoMC4wMDAwMDAsIDAuMDAwMDAwLCAxLjM0MjAzOSwgMC4wMDAwMDApKSAqIGJ1Zls3XSArIHZlYzQoLTUuMDI2OTI2LCAtNi41NzM2MDIsIC0wLjg4MTI0OSwgMy4wMTMyMzgpOwogICAgICBidWZbMF0gPSBzaWdtb2lkKGJ1ZlswXSk7CiAgICAgIGJ1ZlsxXSA9IHNpZ21vaWQoYnVmWzFdKTsKCiAgICAgIGJ1ZlsyXSA9IG1hdDQodmVjNCgtMTUuMjE5NTY4LCA4LjA5NTU0MywgLTEuMDc5MjYxLCAtMS45MzgxOTgpLCB2ZWM0KC01Ljk1MTM2MiwgNS44MDg2MDQsIDIuNjM5Mzc4LCAwLjI5OTY0OSksIHZlYzQoLTcuMzE0NTIzLCA3LjkyNDgxNSwgNC4yMDQ4NjAsIDUuNTcwNTQ4KSwgdmVjNCg1LjM4OTYzMSwgOC45NzkwNTEsIC0xLjkxNDUxOSwgLTAuNDk0OTI4KSkgKiBidWZbNl0gKyBtYXQ0KHZlYzQoLTExLjk2NzE1NCwgLTExLjYwODE1NSwgNi45OTE0NTAsIDEwLjk2NjU2NSksIHZlYzQoMi4wNzAxMDAsIC02LjI2MzE5MiwgLTEuNzA1MDM2LCAtMC42NjcxOTApLCB2ZWM0KDAuNTIzMTA3LCAtMC40NTk0MzAsIDAuMDAwMDAwLCAwLjAwMDAwMCksIHZlYzQoMC4yODQ5ODIsIDAuMDAwMDAwLCAwLjAwMDAwMCwgMC4wMDAwMDApKSAqIGJ1Zls3XSArIHZlYzQoLTQuMTcxNjQwLCAtMS45MzI4MDIsIC01LjUyNDU1OCwgLTMuNjQwMTE5KTsKICAgICAgYnVmWzNdID0gbWF0NCh2ZWM0KDIuMzY1NTQyLCAtMTMuNzM4OTIyLCAyLjQ5ODA3NSwgMy4yMzM0NjUpLCB2ZWM0KDAuNjQzMDA3LCAxMS45MjU2MDEsIDEuOTE0MTA1LCAwLjU5OTk1NyksIHZlYzQoLTEuMjIxMTk1LCA0LjQ4MDcyMiwgMS40NzMzOTgsIDMuMTUzNjI0KSwgdmVjNCg1LjAwMzkyNSwgMTMuMDAwNDgxLCAzLjc1ODE4MywgLTQuNTU2MTkwKSkgKiBidWZbNl0gKyBtYXQ0KHZlYzQoLTAuMzk0OTQ1LCA3LjY3NTEwMSwgLTMuMTQyNTY4LCA1LjM1NzY5NSksIHZlYzQoMC42MzkzNjIsIDMuNzE0MzkzLCAtMC44MTA4MzgsIC0wLjM5MTc0OSksIHZlYzQoLTAuNDY0OTQ0LCAwLjAwMDAwMCwgMC4wMDAwMDAsIDAuMDAwMDAwKSwgdmVjNCgtMC4zODk2MzAsIDAuMDAwMDAwLCAwLjAwMDAwMCwgMC4wMDAwMDApKSAqIGJ1Zls3XSArIHZlYzQoLTAuMTE0NDI3LCAtMjEuNjIxODgxLCAwLjcwMTUxNiwgMS4yMzI5NzIpOwogICAgICBidWZbMl0gPSBzaWdtb2lkKGJ1ZlsyXSk7CiAgICAgIGJ1ZlszXSA9IHNpZ21vaWQoYnVmWzNdKTsKCiAgICAgIGJ1Zls0XSA9IG1hdDQodmVjNCg1LjIxNDkxNiwgLTcuMTgzMDI0LCAxLjQ2OTAyMiwgMi42NTkyNjIpLCB2ZWM0KC01LjYwMTg3OCwgLTI1LjM1OTEwMCwgNS4yNTI4MTQsIC0wLjY1NTEyMyksIHZlYzQoLTEwLjU3NzU5MCwgMjQuNDI2MDg3LCAyMS4xMDIxMDQsIDM3LjU0NjY1OCksIHZlYzQoNC4wNjU4MTMsIC0xLjk2MjUyMywgMi4zNDU4ODAsIC0xLjM3MjgxNikpICogYnVmWzBdICsgbWF0NCh2ZWM0KC0xNy42NTI2MDAsIC0xMC41MDc1NTgsIDIuMjU4NzQxLCAxMy45MDM5NzQpLCB2ZWM0KDcuMTUxNTI3LCAtNTAyLjc1NDQzMCwgLTEyLjY0MjUxMywgMS40OTE2MTQpLCB2ZWM0KC0xMC45ODMyNDQsIDIxLjUxODU1MywgLTkuNzAxNzY4LCAtMC43NjM1OTkpLCB2ZWM0KDUuMzgzNjI2LCAxLjQ4MTk1NCwgLTQuMTkxMTYyLCAtMy44OTQ2MzEpKSAqIGJ1ZlsxXSArIG1hdDQodmVjNCgxMi42NjQ0MzEsIC0xNS4xMjk3MTksIDIuMTUxODQxLCAxLjc5NTU5OCksIHZlYzQoLTMwLjQ4MzY1MCwgLTEuODM0NTM2LCAxLjQ1NDI1MywgLTEuMTExODc3KSwgdmVjNCgxOS44NzI3MjMsIC03LjMzNzkzNSwgLTQyLjIyMTI4NiwgLTk4LjUyNzA5MCksIHZlYzQoNy4yMTYzMzgsIC0yLjI2MzkwMiwgLTIuMjcyMTc2LCAtMzYuMTQyMzIzKSkgKiBidWZbMl0gKyBtYXQ0KHZlYzQoLTE2LjI5ODMxNywgMy41NDcyMDAsIC0wLjQzMTYxMiwgLTkuNDQ0NDE3KSwgdmVjNCg1Ny45MzAwMTcsIC0zNC45OTkwMjYsIDE0Ljk1MjgzNiwgLTQuMTUzNDc1KSwgdmVjNCgtMC4wNzQ3MDMsIC0zLjg2NTY0OCwgLTguMTkwNzk1LCAzLjE1MjM5NyksIHZlYzQoLTEyLjU1OTM4NSwgLTcuMDc3NjE5LCAxLjQ5MDQzNywgLTAuODIxMTU0KSkgKiBidWZbM10gKyB2ZWM0KC03LjY3OTE0MCwgMTUuOTI3NDM3LCAxLjMyMDc3MywgLTEuNjY4NjExKTsKICAgICAgYnVmWzVdID0gbWF0NCh2ZWM0KC0yLjA5MTY5OCwgLTAuMzcyNzYyLCAtMy43NzAzODMsIC0yMS4zNjcxNzQpLCB2ZWM0KC01LjY5NzI0NywgLTkuMzU5MDgwLCAwLjkyNTI5MCwgOC44MjU2MTApLCB2ZWM0KDExLjEwMDk0MCwgLTIyLjM0ODA2OCwgMTMuNjI1NzcyLCAtMTguNjkzMjAxKSwgdmVjNCgtMC4zNDI5MDUsIC0zLjk5MDU2MCwgLTIuNDYyNjExLCAtMC40NTAzMzUpKSAqIGJ1ZlswXSArIG1hdDQodmVjNCg2LjY4NzkyOSwgLTQuMzY2MTg0LCAtNi4zMDM3NjUsIC0zLjg2ODExNSksIHZlYzQoMS41NDYyODUsIDYuNTQ4ODkxLCAwLjk5ODY4MSwgLTAuMDgzOTk3KSwgdmVjNCg1LjI3OTc5OCwgLTIuMjE4MDQwLCAzLjcxMjc2OSwgLTAuMjk4Mjk2KSwgdmVjNCgtNS43OTczOTAsIDEwLjEzNDk2MSwgLTIuNTQ0MDg0LCAtNS45NjU2MDUpKSAqIGJ1ZlsxXSArIG1hdDQodmVjNCgtMi41MTMyNTksIC01LjI0MDg3OCwgLTAuOTQyMjQ5LCAtMC4xNjI4NTMpLCB2ZWM0KDAuMjAzMTA4LCAwLjUzNzM4MSwgNS44Mjc3MjgsIC0xLjMwMjQ3NyksIHZlYzQoLTEuMzI2OTkyLCAyLjAxMTEyOSwgLTYuMjQzNTk5LCAtMy43Mjg2MzUpLCB2ZWM0KC0xMy41NjI1NjIsIDkuMTE1ODYxLCAtMC45MTczNzUsIC0zLjYyMzUxMCkpICogYnVmWzJdICsgbWF0NCh2ZWM0KC04LjY0NTAxMywgNi41NTQ2NjcsIC02LjI2MTEwNCwgLTUuNTkzMzM3KSwgdmVjNCgtMC41Nzc4MzEsIC0xLjA3NzI3NSwgMzcuODc1ODgzLCA1LjczNjc2OSksIHZlYzQoMTMuMzcwNDk1LCAzLjcxNDY2NSwgNy4xNDUyMjUsIC00LjU5NTg3OCksIHZlYzQoMi43MTkyMDcsIDMuNjAyMTkxLCAtNS42ODI5OTMsIC0yLjM2NTM0NikpICogYnVmWzNdICsgdmVjNCgtNS45MDAwODEsIC0zLjg4NzExNywgMC41NTI4MjQsIDguNTk1MDMwKTsKICAgICAgYnVmWzRdID0gc2lnbW9pZChidWZbNF0pOwogICAgICBidWZbNV0gPSBzaWdtb2lkKGJ1Zls1XSk7CgogICAgICBidWZbNl0gPSBtYXQ0KHZlYzQoLTEuNjExMDIwLCAyLjM4NzM2OCwgMS40Njc1MjMsIDAuMjA5MTc1KSwgdmVjNCgtMjguNzkzNzM3LCAtNy4xMzkwOTUsIDAuNTY3OTIwLCA0LjY1NjU4MSksIHZlYzQoLTEwLjk0ODYxMCwgMzkuNjYyMzgwLCAwLjc0MzE4NSwgLTEwLjA5NTYwNSksIHZlYzQoLTEuNDk0NzM5LCAtMS41NDgzOTUsIDAuNzMwMTMyLCAyLjE2ODc2OCkpICogYnVmWzBdICsgbWF0NCh2ZWM0KDMuMjU0Nzc1LCAyMS40ODkxMDMsIC0yLjA2NDY4OSwgLTMuMzEwMDU5KSwgdmVjNCgtMy43MzE2NjMsIC0zLjM3OTIxNiwgLTcuMjIzMTkzLCAtMC4yMzY4NTgpLCB2ZWM0KDEzLjMzNDkwOCwgMC43OTE2MDEsIDYuNzQ4ODA0LCA0LjYzMzk0MyksIHZlYzQoLTUuOTE4MzU1LCAtMTcuNDcxMDExLCAtNS43MzI4MDksIC0xLjY0NTE5NykpICogYnVmWzFdICsgbWF0NCh2ZWM0KDAuMTgxOTM0LCAtNy41MzY0NjMsIC03LjIxMzEyMiwgLTQuMTUyNTU3KSwgdmVjNCgtMy41MjIzODIsIC0wLjEyMzU5MywgLTEuMjgxMjM0LCAxLjI1MzY1MyksIHZlYzQoOS43NDUwMTgsIC0yMi44NTM3ODUsIDIuMDYyNDMxLCAwLjA5OTg5MiksIHZlYzQoLTQuMzE5NjMxLCAtMTcuNzMwMDg3LCAxLjc4NzY3MywgNS4zMDI2NzApKSAqIGJ1ZlsyXSArIG1hdDQodmVjNCgtNi41NDU1NjMsIC0xNS43OTAxNzYsIC03LjQwMzgzMiwgLTUuODMyOTE3KSwgdmVjNCgtNDMuNTkxNTgzLCAyOC41NTE5MTIsIC0xNi4wMDE2MTAsIDE4Ljg0NzI4MCksIHZlYzQoMy4wMTY2OTksIDcuNzM5ODM1LCAxLjk3OTM4NCwgOC42NTc1MjIpLCB2ZWM0KC01LjAyMzc1NywgLTQuNDUwNjMzLCAtNC40NzY4MDAsIC01LjUwMTA0NCkpICogYnVmWzNdICsgbWF0NCh2ZWM0KDEuNjk4NTU2LCAtNjcuNDM1OTc4LCA2Ljg5NzcxNSwgMS45MDA0ODMpLCB2ZWM0KDEuODY4MDM1LCAzLjY5ODA4OCwgMi41MjMxMTEsIDMuMzM4MDA1KSwgdmVjNCgxMS4xNTgwMDYsIDEuNzYyMTMwLCAzLjI5MjI0MCwgOC4wNzMxNTcpLCB2ZWM0KC00LjI1NjAzNCwgLTMwNi4xODAzMTIsIDguNTgxOTA0LCAtMTguMTc4Njc2KSkgKiBidWZbNF0gKyBtYXQ0KHZlYzQoMS40Mzc2OTgsIC00LjgzMjA5NSwgMy44NTM0ODAsIC02LjM0ODIxNyksIHZlYzQoMS4zNTQzMzEsIC0xLjI2NDAwNCwgOS45MzI3NTQsIDMuMTEzNDEyKSwgdmVjNCgtNS4yOTQ5MDIsIC0wLjk0OTcwOSwgMC4xMjgxNDIsIDMuMzI2OTY1KSwgdmVjNCgyOS43MzU0MjQsIC00LjkxODI3OCwgNi4xMDQ0MDgsIDQuMzUwMzIzKSkgKiBidWZbNV0gKyB2ZWM0KDcuNDQ1Mjg3LCAxMi4xNjE2MzMsIC0zLjc3MDMzOSwgLTQuNzc1MjE0KTsKICAgICAgYnVmWzddID0gbWF0NCh2ZWM0KC04LjI2NTYwMiwgLTQuNzAyNzAyLCA1LjA5ODIzNCwgMC42MDYwODEpLCB2ZWM0KDcuNjU1ODY0LCAtMTcuMTU5NDkwLCAxNi41MTkzOTAsIC04Ljg4NDQ3OSksIHZlYzQoLTQuMDM2NDc5LCAtMi4zOTQ2ODcsIC0zLjYwODI0NywgLTEuOTg2NjUzKSwgdmVjNCgtMi4yMTY3NzQsIC0xLjgxMzU2NSwgLTUuOTc1OTg3LCA0Ljg4NDY0NSkpICogYnVmWzBdICsgbWF0NCh2ZWM0KDUuMzkzNDA5LCAzLjUwNzY1NSwgLTIuODE5MTEzLCAtMi43MDI4OTcpLCB2ZWM0KC02Ljc0OTcyMywgLTAuMjc4NDQ5LCAxLjQ5NTg3MCwgLTUuMDUxNzE0KSwgdmVjNCgxMy4xMjIyMjYsIDE2LjczNDYzMCwgLTIuOTM5NzQ4LCAtNC4xMDEwMjMpLCB2ZWM0KC0xNS4zODIxODcsIC01LjAzMDQ4MywgLTYuMjU5OTMzLCAxLjU0Njk3MykpICogYnVmWzFdICsgbWF0NCh2ZWM0KDUuMjcyMDM0LCAtMC45NDAxMTYsIC01LjE3MTE0NCwgNC43NTUwMjIpLCB2ZWM0KDUuNDc0ODMxLCA1LjUwODA5NywgMS43NDI1OTEsIC0yLjU5NjczMSksIHZlYzQoMy4xMDA1NDMsIDAuMTYzNDI2LCAtMTA0LjU2MzQxMCwgMTYuOTQ5MTg0KSwgdmVjNCgtNS41NDAyMjUsIC0yLjM5MjAwMSwgMy44MzUwMTAsIC0xLjkzNjQyNSkpICogYnVmWzJdICsgbWF0NCh2ZWM0KC02LjMyMTI1NiwgMS43OTQ2MTIsIC0xMy42MDQxOTIsIC0zLjgwNjA1MiksIHZlYzQoNi42NTgzNDYsIDMxLjkxMTE3NywgMjUuMTY0NDc0LCA5Mi4xNzIzNzgpLCB2ZWM0KDEyLjI5NzU3MywgNC4xNTAzMDQsIC0wLjczMTQ0MCwgNi43Njg0NjcpLCB2ZWM0KC01LjU2Mzk1OCwgNC4wMzQ3NzIsIDUuODI3MTI1LCAwLjU2NTM5MikpICogYnVmWzNdICsgbWF0NCh2ZWM0KDMuNDk5MjQ0LCAtMTk2LjI2ODEwMCwgLTkuNzc3NDU3LCAyLjgxNDI2MyksIHZlYzQoMy40ODA2NTAsIC0zLjE4NDYzNSwgNS40NDMwMDksIDUuMTgwNDIyKSwgdmVjNCgtMi44NTg3ODMsIDE1LjU4NTc5NCwgMS4yODYzOTYsIDIuMDI1MjI4KSwgdmVjNCgtNzEuMjUyNzEwLCAtNjIuNDQxMjQyLCAtOS41MDk1NTAsIDAuNTA2NzAzKSkgKiBidWZbNF0gKyBtYXQ0KHZlYzQoLTEyLjIyOTA1MywgLTEwLjgwMDA1NiwgLTcuMzQ3NDE1LCA0LjM5MDI5NCksIHZlYzQoMTAuNzgyNDEyLCA1LjYzMzczOCwgMC4yODE1ODAsIC00LjczNDg3MiksIHZlYzQoLTEzLjQyMjg4NCwgLTcuMDM5MzkxLCA1Ljg2MjQ0MiwgNi45MzYyNjYpLCB2ZWM0KC0wLjAxNjc2NiwgOC45MTg5ODAsIDIuOTc4MTE0LCA1LjE1MDk1MikpICogYnVmWzVdICsgdmVjNCgyLjI0MTUyNywgLTYuNzA1OTg3LCAtMC45ODg2MTAsIC0zLjM1MTUwOCk7CiAgICAgIGJ1Zls2XSA9IHNpZ21vaWQoYnVmWzZdKTsKICAgICAgYnVmWzddID0gc2lnbW9pZChidWZbN10pOwoKICAgICAgYnVmWzBdID0gbWF0NCh2ZWM0KDEuNjc5NDI2LCAxLjM4MTc0NywgMi45NjI1NDUsIDAuMDAwMDAwKSwgdmVjNCgtMS44ODM0NDEsIC0xLjQ4MDY5NCwgLTMuNTkyNDUyLCAwLjI3Njk2MiksIHZlYzQoLTEuNzUwOTQ0LCAtMS4wOTE4MDYsIC0yLjMxMzM1MiwgMC4wMDAwMDApLCB2ZWM0KDAuMjY2MjIzLCAxLjQzNDY3NCwgMC40NDE3ODUsIDAuMDAwMDAwKSkgKiBidWZbMF0gKyBtYXQ0KHZlYzQoLTAuNjI5OTEwLCAtMS42MTIyNzIsIC0wLjc3MDYwMCwgMC4wMDAwMDApLCB2ZWM0KDAuMTc4MjkwLCAwLjE4MzAwMiwgMS41MTIwODMsIDAuMDAwMDAwKSwgdmVjNCgtMi45NjU0NDAsIC0yLjU4MTk5NCwgLTQuOTAwMTA1LCAwLjAwMDAwMCksIHZlYzQoMC44NTU1ODcsIDEuMTg2ODA4LCAyLjUxNzYzMiwgMC4wMDAwMDApKSAqIGJ1ZlsxXSArIG1hdDQodmVjNCgtMS4yNTg0MzcsIC0xLjA1NTIxNiwgLTIuMTY4ODQwLCAtMC43ODA4NjUpLCB2ZWM0KC0wLjcyMDAyMiwgLTAuNTI2NjYwLCAtMS40MzgyNTEsIDAuMDAwMDAwKSwgdmVjNCgwLjE1MzQ1MywgMC4xNTE5NjEsIDAuMjcyODU0LCAtMC43ODMwNzgpLCB2ZWM0KDEuNTg3MTYyLCAwLjg4NjE5NCwgMC4zNjM2MDMsIDAuMDAwMDAwKSkgKiBidWZbMl0gKyBtYXQ0KHZlYzQoLTEuNTU5MTgwLCAtMC43MTE3MDQsIC00LjM1MTY2MCwgMC4wMTIxNzYpLCB2ZWM0KC0yMi42NDExODcsIC0xOC44MzE0NjgsIC00MS45NTQzNzIsIDAuMDAwMDAwKSwgdmVjNCgwLjYzNzkyMCwgMC41NDcwNjUsIDIuMTg5MzQzLCAtMS4yOTk3MDIpLCB2ZWM0KC0xLjU0ODk4OSwgLTEuMzA3NTkzLCAtMS4xOTMwNzMsIDAuMDAwMDAwKSkgKiBidWZbM10gKyBtYXQ0KHZlYzQoLTAuNDkyNTIxLCAwLjU1MjYzMywgLTEuNTYxNzAyLCAxLjE4MzkzNyksIHZlYzQoMC45NTYwOTMsIDAuMjIxMTAxLCAxLjY0MDIyMSwgMS4xOTk4ODApLCB2ZWM0KC0xLjA1NjA3MSwgLTIuNjY0ODI4LCAwLjg2Mzk4NiwgMC4wMDAwMDApLCB2ZWM0KDEuMTgyNTk4LCAwLjY1MDU4NywgMy40MDYzMzEsIDAuMDAwMDAwKSkgKiBidWZbNF0gKyBtYXQ0KHZlYzQoMC4zNTQ0NjcsIDAuMzI5Mzc5LCAtMC41Mzc1NjQsIDEuMjE0OTA2KSwgdmVjNCgwLjkxODQ0OCwgLTAuNDgxNzc4LCAtMS4wNjE0ODMsIC0xLjI3NDIzMSksIHZlYzQoMi43OTY0NTMsIDEuMDAwMTk2LCA0LjY4NDY2NSwgMC4wMDAwMDApLCB2ZWM0KDAuMTMwNDI2LCAxLjExMjMxNiwgMS40MDg3MTAsIDAuMDAwMDAwKSkgKiBidWZbNV0gKyBtYXQ0KHZlYzQoLTAuODM0MDgxLCAtMS40MDMzMTksIC00LjEwNDA2NywgMC4wMDAwMDApLCB2ZWM0KDMuMTY2NDM2LCAyLjYzODI5NywgNC45NTc2MTUsIDAuODMxNDY1KSwgdmVjNCgtMy4xNzI0NzEsIC0zLjIwNDkwNSwgLTUuNTQ5Mjk1LCAwLjMyMDAxOSksIHZlYzQoLTEuOTAzNDA1LCAtMi4yNDkwOTIsIC01LjMwMTMwNywgMC4wMDAwMDApKSAqIGJ1Zls2XSArIG1hdDQodmVjNCgxLjUyMDM4NCwgLTEuMTAwODM5LCA0LjMxNTI5OSwgMC43ODUyMzApLCB2ZWM0KDEuNTIxMDU2LCAxLjI2NTEzNSwgMi42ODM5MDMsIDAuMDAwMDAwKSwgdmVjNCgyLjk3ODk0NywgMi4zNzk4NDcsIDUuMjM0NzI2LCAwLjAwMDAwMCksIHZlYzQoMi4yMjcwNDIsIDEuNTc1Njc2LCAzLjgwMjg2NCwgMC44Nzk4MDkpKSAqIGJ1Zls3XSArIHZlYzQoLTIuOTAzOTYwLCAtMy42MTcxNDgsIDEuODY1MjQ3LCAwLjAwMDAwMCk7CiAgICAgIGJ1ZlswXSA9IHNpZ21vaWQoYnVmWzBdKTsKCiAgICAgIHJldHVybiB2ZWM0KGJ1ZlswXS54eXosIDEuMCk7CiAgfQoKICB2b2lkIG1haW4oKSB7CiAgICB2ZWMyIHV2ID0gdlV2ICogMi4wIC0gMS4wOwogICAgdXYueSAqPSAtMS4wOwoKICAgIHZlYzQgY29sb3IgPSBjcHBuX2ZuKHV2LCAwLjEgKiBzaW4oMC4zICogdVRpbWUpLCAwLjEgKiBzaW4oMC42OSAqIHVUaW1lKSwgMC4xICogc2luKDAuNDQgKiB1VGltZSkpOwoKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoY29sb3IucmdiLCAxLjApOwogIH0KICBgOwoKCXVzZVRhc2soKGRlbHRhKSA9PiB7CgkJdGltZSArPSBkZWx0YSAqIHNwZWVkOwoJCWlmIChtYXRlcmlhbCkgewoJCQltYXRlcmlhbC51bmlmb3Jtcy51VGltZS52YWx1ZSA9IHRpbWU7CgkJCW1hdGVyaWFsLnVuaWZvcm1zLnVSZXNvbHV0aW9uLnZhbHVlLnNldCgkc2l6ZS53aWR0aCwgJHNpemUuaGVpZ2h0KTsKCQl9Cgl9KTsKPC9zY3JpcHQ+Cgo8VC5NZXNoPgoJPFQuUGxhbmVHZW9tZXRyeSBhcmdzPXtbMiwgMl19IC8+Cgk8VC5TaGFkZXJNYXRlcmlhbAoJCWJpbmQ6cmVmPXttYXRlcmlhbH0KCQl7dmVydGV4U2hhZGVyfQoJCXtmcmFnbWVudFNoYWRlcn0KCQl0cmFuc3BhcmVudAoJCXVuaWZvcm1zPXt7CgkJCXVUaW1lOiB7IHZhbHVlOiAwIH0sCgkJCXVSZXNvbHV0aW9uOiB7IHZhbHVlOiBuZXcgVmVjdG9yMigxLCAxKSB9LAoJCX19CgkvPgo8L1QuTWVzaD4K", + "components/orb/Orb.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBDYW52YXMgfSBmcm9tICJAdGhyZWx0ZS9jb3JlIjsKCWltcG9ydCB7IE5vVG9uZU1hcHBpbmcgfSBmcm9tICJ0aHJlZSI7CglpbXBvcnQgdHlwZSB7IENvbXBvbmVudFByb3BzIH0gZnJvbSAic3ZlbHRlIjsKCWltcG9ydCBTY2VuZSBmcm9tICIuL09yYlNjZW5lLnN2ZWx0ZSI7CglpbXBvcnQgeyBjbiB9IGZyb20gIi4uL3V0aWxzL2NuIjsKCWltcG9ydCB0eXBlIHsgT3JiU3RhdGUgfSBmcm9tICIuL3R5cGVzIjsKCgl0eXBlIFNjZW5lUHJvcHMgPSBDb21wb25lbnRQcm9wczx0eXBlb2YgU2NlbmU+OwoKCWludGVyZmFjZSBQcm9wcyB7CgkJLyoqCgkJICogQWRkaXRpb25hbCBDU1MgY2xhc3NlcyBmb3IgdGhlIGNvbnRhaW5lci4KCQkgKi8KCQljbGFzcz86IHN0cmluZzsKCQkvKioKCQkgKiBDdXJyZW50IGFuaW1hdGlvbiBzdGF0ZSBvZiB0aGUgb3JiLgoJCSAqIC0gYGlkbGVgOiBnZW50bGUgZHJpZnQsIHB1cnBsZSBwYWxldHRlLgoJCSAqIC0gYGF0dHVuZWA6IHRhbmdlbnRpYWwgc3dpcmwg4oCUIGNvbG9ycyByb3RhdGUgYXJvdW5kIHRoZSBzcGhlcmUuCgkJICogLSBgcHVsc2VgOiByYWRpYWwgYnJlYXRoaW5nIOKAlCBjb2xvcnMgZXhwYW5kIGFuZCBjb250cmFjdC4KCQkgKiAtIGBzdXJnZWA6IGxpc3Nham91cyBvcmJpdGFsIGNodXJuIOKAlCByYXBpZCBtdWx0aS1heGlzIG1vdmVtZW50LgoJCSAqIEBkZWZhdWx0ICJpZGxlIgoJCSAqLwoJCXN0YXRlPzogT3JiU3RhdGU7CgkJLyoqCgkJICogQXVkaW8gYW1wbGl0dWRlIGluIFswLCAxXSB0aGF0IGFkZHMgYSByZWFjdGl2ZSBwdWxzZSBsYXllci4KCQkgKiBAZGVmYXVsdCAwCgkJICovCgkJYW1wbGl0dWRlPzogU2NlbmVQcm9wc1siYW1wbGl0dWRlIl07CgkJLyoqCgkJICogQmFzZSBjb2xvciBmb3IgdGhlIG9yYiBwYWxldHRlIGFuZCByaW0gZ2xvdy4gQWNjZXB0cyBhbnkgQ1NTIGNvbG9yIHN0cmluZy4KCQkgKiBAZGVmYXVsdCAiIzY5MzNmZiIKCQkgKi8KCQljb2xvcj86IFNjZW5lUHJvcHNbImNvbG9yIl07CgkJLyoqCgkJICogU3BlZWQgbXVsdGlwbGllciBhcHBsaWVkIHRvIHRoZSBlbnRpcmUgYW5pbWF0aW9uLgoJCSAqIEBkZWZhdWx0IDEKCQkgKi8KCQlzcGVlZD86IFNjZW5lUHJvcHNbInNwZWVkIl07CgoJCVtrZXk6IHN0cmluZ106IHVua25vd247Cgl9CgoJbGV0IHsgY2xhc3M6IGNsYXNzTmFtZSA9ICIiLCBzdGF0ZSA9ICJpZGxlIiwgYW1wbGl0dWRlID0gMCwgY29sb3IgPSAiIzY5MzNmZiIsIHNwZWVkID0gMSwgLi4ucmVzdCB9OiBQcm9wcyA9ICRwcm9wcygpOwo8L3NjcmlwdD4KCjxkaXYgY2xhc3M9e2NuKCJyZWxhdGl2ZSBoLWZ1bGwgdy1mdWxsIG92ZXJmbG93LWhpZGRlbiIsIGNsYXNzTmFtZSl9IHsuLi5yZXN0fT4KCTxkaXYgY2xhc3M9ImFic29sdXRlIGluc2V0LTAiPgoJCTxDYW52YXMgdG9uZU1hcHBpbmc9e05vVG9uZU1hcHBpbmd9IHJlbmRlcmVyUGFyYW1ldGVycz17eyBhbHBoYTogdHJ1ZSB9fT4KCQkJPFNjZW5lIG9yYlN0YXRlPXtzdGF0ZX0ge2FtcGxpdHVkZX0ge2NvbG9yfSB7c3BlZWR9IC8+CgkJPC9DYW52YXM+Cgk8L2Rpdj4KPC9kaXY+Cg==", + "components/orb/OrbScene.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBULCB1c2VUYXNrLCB1c2VUaHJlbHRlIH0gZnJvbSAiQHRocmVsdGUvY29yZSI7CglpbXBvcnQgeyBDb2xvciwgU2hhZGVyTWF0ZXJpYWwsIE1lc2gsIFZlY3RvcjMgfSBmcm9tICJ0aHJlZSI7CglpbXBvcnQgeyBvcmJWZXJ0ZXgsIG9yYkZyYWdtZW50IH0gZnJvbSAiLi9vcmIuZ2xzbCI7CglpbXBvcnQgdHlwZSB7IE9yYlN0YXRlLCBTdGF0ZUNvbmZpZyB9IGZyb20gIi4vdHlwZXMiOwoKCWludGVyZmFjZSBQcm9wcyB7CgkJLyoqCgkJICogQ3VycmVudCBhbmltYXRpb24gc3RhdGUgb2YgdGhlIG9yYi4KCQkgKiBAZGVmYXVsdCAiaWRsZSIKCQkgKi8KCQlvcmJTdGF0ZT86IE9yYlN0YXRlOwoJCS8qKgoJCSAqIEF1ZGlvIGFtcGxpdHVkZSBpbiBbMCwgMV0gdGhhdCBkcml2ZXMgcmVhY3RpdmUgcHVsc2UuCgkJICogQGRlZmF1bHQgMAoJCSAqLwoJCWFtcGxpdHVkZT86IG51bWJlcjsKCQkvKioKCQkgKiBCYXNlIGNvbG9yIGZvciB0aGUgb3JiIHBhbGV0dGUgYW5kIHJpbSBnbG93LiBUaGUgZnVsbCA1LWNvbG9yIHBhbGV0dGUKCQkgKiBpcyBkZXJpdmVkIGZyb20gdGhpcyBodWUgdXNpbmcgSFNMIHZhcmlhdGlvbnMuCgkJICogQGRlZmF1bHQgIiM2OTMzZmYiCgkJICovCgkJY29sb3I/OiBzdHJpbmc7CgkJLyoqCgkJICogU3BlZWQgbXVsdGlwbGllciBhcHBsaWVkIHRvIHRoZSBlbnRpcmUgYW5pbWF0aW9uLiAxIGlzIGRlZmF1bHQsIDIgaXMgZG91YmxlIHNwZWVkLgoJCSAqIEBkZWZhdWx0IDEKCQkgKi8KCQlzcGVlZD86IG51bWJlcjsKCX0KCglsZXQgeyBvcmJTdGF0ZSA9ICJpZGxlIiwgYW1wbGl0dWRlID0gMCwgY29sb3IgPSAiIzY5MzNmZiIsIHNwZWVkID0gMSB9OiBQcm9wcyA9ICRwcm9wcygpOwoKCWNvbnN0IGlkbGVQYWxldHRlOiBTdGF0ZUNvbmZpZ1sicGFsZXR0ZSJdID0gWwoJCVswLjA0LCAwLjAxLCAwLjI1XSwKCQlbMC45MiwgMC40MiwgMC41XSwKCQlbMC4yMiwgMC4wNCwgMC41XSwKCQlbMC44OCwgMC41OCwgMC40OF0sCgkJWzAuMSwgMC4wNCwgMC40NV0sCgldOwoKCWNvbnN0IFNUQVRFUzogUmVjb3JkPE9yYlN0YXRlLCBTdGF0ZUNvbmZpZz4gPSB7CgkJaWRsZTogewoJCQlwYWxldHRlOiBpZGxlUGFsZXR0ZSwKCQkJZnJlc25lbENvbG9yOiBbMC41NSwgMC4zLCAwLjgyXSwKCQkJZnJlc25lbFN0cmVuZ3RoOiAwLjgsCgkJCW5vaXNlU3BlZWQ6IDAuNSwKCQkJZmxvd0RyaWZ0OiAxLAoJCQlmbG93T3V0OiAwLAoJCQlmbG93SW46IDAsCgkJCWZsb3dQdWxzZTogMCwKCQkJZmxvd1N3aXJsOiAwLAoJCQliYXNlUHVsc2U6IDAsCgkJfSwKCQlhdHR1bmU6IHsKCQkJcGFsZXR0ZTogaWRsZVBhbGV0dGUsCgkJCWZyZXNuZWxDb2xvcjogWzAuNTUsIDAuMywgMC44Ml0sCgkJCWZyZXNuZWxTdHJlbmd0aDogMS4xLAoJCQlub2lzZVNwZWVkOiAwLjksCgkJCWZsb3dEcmlmdDogMCwKCQkJZmxvd091dDogMCwKCQkJZmxvd0luOiAxLjYsCgkJCWZsb3dQdWxzZTogMCwKCQkJZmxvd1N3aXJsOiAwLAoJCQliYXNlUHVsc2U6IDAuMDEsCgkJfSwKCQlwdWxzZTogewoJCQlwYWxldHRlOiBpZGxlUGFsZXR0ZSwKCQkJZnJlc25lbENvbG9yOiBbMC41NSwgMC4zLCAwLjgyXSwKCQkJZnJlc25lbFN0cmVuZ3RoOiAxLjMsCgkJCW5vaXNlU3BlZWQ6IDAuOCwKCQkJZmxvd0RyaWZ0OiAwLAoJCQlmbG93T3V0OiAwLAoJCQlmbG93SW46IDAsCgkJCWZsb3dQdWxzZTogMSwKCQkJZmxvd1N3aXJsOiAwLAoJCQliYXNlUHVsc2U6IDAuMDEsCgkJfSwKCQlzdXJnZTogewoJCQlwYWxldHRlOiBpZGxlUGFsZXR0ZSwKCQkJZnJlc25lbENvbG9yOiBbMC41NSwgMC4zLCAwLjgyXSwKCQkJZnJlc25lbFN0cmVuZ3RoOiAxLjIsCgkJCW5vaXNlU3BlZWQ6IDIuMCwKCQkJZmxvd0RyaWZ0OiAwLAoJCQlmbG93T3V0OiAwLAoJCQlmbG93SW46IDAsCgkJCWZsb3dQdWxzZTogMCwKCQkJZmxvd1N3aXJsOiAxLjUsCgkJCWJhc2VQdWxzZTogMC4wMywKCQl9LAoJfTsKCgljb25zdCBMRVJQX0tFWVM6IChrZXlvZiBTdGF0ZUNvbmZpZylbXSA9IFsKCQkibm9pc2VTcGVlZCIsCgkJImZyZXNuZWxTdHJlbmd0aCIsCgkJImZsb3dEcmlmdCIsCgkJImZsb3dPdXQiLAoJCSJmbG93SW4iLAoJCSJmbG93UHVsc2UiLAoJCSJmbG93U3dpcmwiLAoJXTsKCgkvLyBNYXRlcmlhbCByZWZzIOKAlCB1cGRhdGVkIGJ5IHVzZVRhc2sKCWxldCBvcmJNYXRlcmlhbCA9ICRzdGF0ZTxTaGFkZXJNYXRlcmlhbD4oKTsKCWxldCBvcmJNZXNoID0gJHN0YXRlPE1lc2g+KCk7CgoJLy8gUHJlLWFsbG9jYXRlZCBDb2xvciBvYmplY3RzIGZvciBwYWxldHRlIGRlcml2YXRpb24gKHJldXNlZCBlYWNoIGZyYW1lKQoJY29uc3QgX2Jhc2UgPSBuZXcgQ29sb3IoKTsKCWNvbnN0IF9oc2wgPSB7IGg6IDAsIHM6IDAsIGw6IDAgfTsKCWNvbnN0IF9wYWwgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiA1IH0sICgpID0+IG5ldyBDb2xvcigpKTsKCWNvbnN0IF9mcmVzbmVsID0gbmV3IENvbG9yKCk7CgoJZnVuY3Rpb24gYXBwbHlDdXN0b21Db2xvcihoZXg6IHN0cmluZywgdTogUmVjb3JkPHN0cmluZywgeyB2YWx1ZTogdW5rbm93biB9PikgewoJCV9iYXNlLnNldChoZXgpOwoJCV9iYXNlLmdldEhTTChfaHNsKTsKCQljb25zdCB7IGgsIHMgfSA9IF9oc2w7CgoJCS8vIERlcml2ZSA1IGhhcm1vbmlvdXMgcGFsZXR0ZSBlbnRyaWVzIGZyb20gdGhlIGJhc2UgaHVlCgkJX3BhbFswXS5zZXRIU0woaCwgTWF0aC5taW4ocyAqIDEuMiwgMSksIDAuMDgpOyAgICAgICAgICAgLy8gdmVyeSBkYXJrCgkJX3BhbFsxXS5zZXRIU0woKGggKyAwLjA1KSAlIDEsIHMgKiAwLjg1LCAwLjY1KTsgICAgICAgICAgLy8gYnJpZ2h0LCBzbGlnaHQgc2hpZnQKCQlfcGFsWzJdLnNldEhTTChoLCBNYXRoLm1pbihzICogMS4xLCAxKSwgMC4yMik7ICAgICAgICAgICAgLy8gbWlkCgkJX3BhbFszXS5zZXRIU0woKGggKyAwLjA4KSAlIDEsIHMgKiAwLjY1LCAwLjcyKTsgICAgICAgICAgLy8gbGlnaHQsIG1vcmUgc2hpZnQKCQlfcGFsWzRdLnNldEhTTChoLCBzICogMC45LCAwLjE0KTsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVlcAoKCQlmb3IgKGxldCBpID0gMDsgaSA8IDU7IGkrKykgewoJCQljb25zdCBjID0gX3BhbFtpXTsKCQkJKHVbYHVQYWxBJHtpfWBdLnZhbHVlIGFzIFZlY3RvcjMpLnNldChjLnIsIGMuZywgYy5iKTsKCQkJKHVbYHVQYWxCJHtpfWBdLnZhbHVlIGFzIFZlY3RvcjMpLnNldChjLnIsIGMuZywgYy5iKTsKCQl9CgkJdS51UGFsZXR0ZUJsZW5kLnZhbHVlID0gMDsKCgkJLy8gRnJlc25lbDogYnJpZ2h0ZXIsIHNhdHVyYXRlZCB2ZXJzaW9uIG9mIHRoZSBiYXNlIGh1ZQoJCV9mcmVzbmVsLnNldEhTTChoLCBNYXRoLm1pbihzICogMS4zLCAxKSwgMC42OCk7CgkJKHUudUZyZXNuZWxDb2xvci52YWx1ZSBhcyBWZWN0b3IzKS5zZXQoX2ZyZXNuZWwuciwgX2ZyZXNuZWwuZywgX2ZyZXNuZWwuYik7Cgl9CgoJLy8gVHJhbnNpdGlvbiBtdXRhYmxlIHN0YXRlIChub3QgcmVhY3RpdmUg4oCUIG11dGF0ZWQgaW4gdGFzaykKCWxldCBlbGFwc2VkID0gMDsKCWxldCBzbW9vdGhBbXAgPSAwOwoJbGV0IGN1cnJlbnRPcmJTdGF0ZTogT3JiU3RhdGUgPSAiaWRsZSI7CglsZXQgdHJhbnNpdGlvblByb2dyZXNzID0gMTsKCWxldCBzbmFwU2NhbGFyczogUGFydGlhbDxSZWNvcmQ8a2V5b2YgU3RhdGVDb25maWcsIG51bWJlcj4+ID0ge307CglsZXQgc25hcEZyZXNuZWwgPSBbMC41NSwgMC4zLCAwLjgyXTsKCWxldCB0YXJnZXRDb25maWc6IFN0YXRlQ29uZmlnID0gU1RBVEVTLmlkbGU7CgoJY29uc3QgaW5pdENmZyA9IFNUQVRFUy5pZGxlOwoKCS8vIFVuaWZvcm0gaW5pdGlhbCB2YWx1ZXMgKHBhc3NlZCBvbmNlOyB1cGRhdGVkIGltcGVyYXRpdmVseSB2aWEgcmVmKQoJY29uc3Qgb3JiVW5pZm9ybXMgPSB7CgkJdVRpbWU6IHsgdmFsdWU6IDAgfSwKCQl1TGlnaHRQb3M6IHsgdmFsdWU6IG5ldyBWZWN0b3IzKC0yLjUsIDEuMCwgMy4wKSB9LAoJCXVBbXBsaXR1ZGU6IHsgdmFsdWU6IDAgfSwKCQl1Tm9pc2VTcGVlZDogeyB2YWx1ZTogaW5pdENmZy5ub2lzZVNwZWVkIH0sCgkJdUZsb3dEcmlmdDogeyB2YWx1ZTogaW5pdENmZy5mbG93RHJpZnQgfSwKCQl1Rmxvd091dDogeyB2YWx1ZTogMCB9LAoJCXVGbG93SW46IHsgdmFsdWU6IDAgfSwKCQl1Rmxvd1B1bHNlOiB7IHZhbHVlOiAwIH0sCgkJdUZsb3dTd2lybDogeyB2YWx1ZTogMCB9LAoJCXVGcmVzbmVsQ29sb3I6IHsgdmFsdWU6IG5ldyBWZWN0b3IzKC4uLmluaXRDZmcuZnJlc25lbENvbG9yKSB9LAoJCXVGcmVzbmVsU3RyZW5ndGg6IHsgdmFsdWU6IGluaXRDZmcuZnJlc25lbFN0cmVuZ3RoIH0sCgkJdVBhbGV0dGVCbGVuZDogeyB2YWx1ZTogMCB9LAoJCXVQYWxBMDogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzBdKSB9LAoJCXVQYWxBMTogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzFdKSB9LAoJCXVQYWxBMjogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzJdKSB9LAoJCXVQYWxBMzogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzNdKSB9LAoJCXVQYWxBNDogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzRdKSB9LAoJCXVQYWxCMDogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzBdKSB9LAoJCXVQYWxCMTogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzFdKSB9LAoJCXVQYWxCMjogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzJdKSB9LAoJCXVQYWxCMzogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzNdKSB9LAoJCXVQYWxCNDogeyB2YWx1ZTogbmV3IFZlY3RvcjMoLi4uaW5pdENmZy5wYWxldHRlWzRdKSB9LAoJfTsKCglmdW5jdGlvbiBsZXJwKGE6IG51bWJlciwgYjogbnVtYmVyLCB0OiBudW1iZXIpIHsKCQlyZXR1cm4gYSArIChiIC0gYSkgKiB0OwoJfQoKCWZ1bmN0aW9uIHN0YXJ0VHJhbnNpdGlvbihuZXdPcmJTdGF0ZTogT3JiU3RhdGUpIHsKCQlpZiAoIW9yYk1hdGVyaWFsKSByZXR1cm47CgkJY29uc3QgdSA9IG9yYk1hdGVyaWFsLnVuaWZvcm1zOwoKCQkvLyBTbmFwc2hvdCBwYWxldHRlIEEgZnJvbSBjdXJyZW50IGJsZW5kZWQgcG9zaXRpb24KCQlpZiAodHJhbnNpdGlvblByb2dyZXNzIDwgMSkgewoJCQljb25zdCBiID0gdHJhbnNpdGlvblByb2dyZXNzOwoJCQlmb3IgKGxldCBpID0gMDsgaSA8IDU7IGkrKykgewoJCQkJY29uc3QgYSA9IHVbYHVQYWxBJHtpfWBdLnZhbHVlIGFzIFZlY3RvcjM7CgkJCQljb25zdCBidiA9IHVbYHVQYWxCJHtpfWBdLnZhbHVlIGFzIFZlY3RvcjM7CgkJCQlhLmxlcnBWZWN0b3JzKGEuY2xvbmUoKSwgYnYsIGIpOwoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yIChsZXQgaSA9IDA7IGkgPCA1OyBpKyspIHsKCQkJCSh1W2B1UGFsQSR7aX1gXS52YWx1ZSBhcyBWZWN0b3IzKS5jb3B5KHVbYHVQYWxCJHtpfWBdLnZhbHVlIGFzIFZlY3RvcjMpOwoJCQl9CgkJfQoKCQljb25zdCBjZmcgPSBTVEFURVNbbmV3T3JiU3RhdGVdOwoJCWZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7CgkJCSh1W2B1UGFsQiR7aX1gXS52YWx1ZSBhcyBWZWN0b3IzKS5zZXQoLi4uY2ZnLnBhbGV0dGVbaV0pOwoJCX0KCgkJLy8gU25hcHNob3QgY3VycmVudCBzY2FsYXIgdW5pZm9ybSB2YWx1ZXMKCQlzbmFwU2NhbGFycyA9IHt9OwoJCWZvciAoY29uc3QgayBvZiBMRVJQX0tFWVMpIHsKCQkJY29uc3QgdUtleSA9IGB1JHtrWzBdLnRvVXBwZXJDYXNlKCl9JHtrLnNsaWNlKDEpfWA7CgkJCXNuYXBTY2FsYXJzW2tdID0gdVt1S2V5XS52YWx1ZSBhcyBudW1iZXI7CgkJfQoJCWNvbnN0IGZjID0gdS51RnJlc25lbENvbG9yLnZhbHVlIGFzIFZlY3RvcjM7CgkJc25hcEZyZXNuZWwgPSBbZmMueCwgZmMueSwgZmMuel07CgoJCXRhcmdldENvbmZpZyA9IGNmZzsKCQljdXJyZW50T3JiU3RhdGUgPSBuZXdPcmJTdGF0ZTsKCQl0cmFuc2l0aW9uUHJvZ3Jlc3MgPSAwOwoJfQoKCWNvbnN0IHsgc2NlbmUgfSA9IHVzZVRocmVsdGUoKTsKCXNjZW5lLmJhY2tncm91bmQgPSBudWxsOwoKCXVzZVRhc2soKGRlbHRhKSA9PiB7CgkJaWYgKCFvcmJNYXRlcmlhbCB8fCAhb3JiTWVzaCkgcmV0dXJuOwoKCQllbGFwc2VkICs9IGRlbHRhICogc3BlZWQ7CgkJY29uc3QgdSA9IG9yYk1hdGVyaWFsLnVuaWZvcm1zOwoKCQlpZiAob3JiU3RhdGUgIT09IGN1cnJlbnRPcmJTdGF0ZSkgc3RhcnRUcmFuc2l0aW9uKG9yYlN0YXRlKTsKCgkJLy8gQWR2YW5jZSB0cmFuc2l0aW9uCgkJaWYgKHRyYW5zaXRpb25Qcm9ncmVzcyA8IDEpIHsKCQkJdHJhbnNpdGlvblByb2dyZXNzID0gTWF0aC5taW4oMSwgdHJhbnNpdGlvblByb2dyZXNzICsgZGVsdGEgLyAwLjQpOwoJCQljb25zdCBlYXNlID0gdHJhbnNpdGlvblByb2dyZXNzICogKDIgLSB0cmFuc2l0aW9uUHJvZ3Jlc3MpOwoJCQl1LnVQYWxldHRlQmxlbmQudmFsdWUgPSBlYXNlOwoKCQkJZm9yIChjb25zdCBrIG9mIExFUlBfS0VZUykgewoJCQkJY29uc3QgdUtleSA9IGB1JHtrWzBdLnRvVXBwZXJDYXNlKCl9JHtrLnNsaWNlKDEpfWA7CgkJCQl1W3VLZXldLnZhbHVlID0gbGVycCgKCQkJCQlzbmFwU2NhbGFyc1trXSA/PyAodGFyZ2V0Q29uZmlnW2tdIGFzIG51bWJlciksCgkJCQkJdGFyZ2V0Q29uZmlnW2tdIGFzIG51bWJlciwKCQkJCQllYXNlLAoJCQkJKTsKCQkJfQoKCQkJY29uc3QgZmMgPSB1LnVGcmVzbmVsQ29sb3IudmFsdWUgYXMgVmVjdG9yMzsKCQkJZmMuc2V0KAoJCQkJbGVycChzbmFwRnJlc25lbFswXSwgdGFyZ2V0Q29uZmlnLmZyZXNuZWxDb2xvclswXSwgZWFzZSksCgkJCQlsZXJwKHNuYXBGcmVzbmVsWzFdLCB0YXJnZXRDb25maWcuZnJlc25lbENvbG9yWzFdLCBlYXNlKSwKCQkJCWxlcnAoc25hcEZyZXNuZWxbMl0sIHRhcmdldENvbmZpZy5mcmVzbmVsQ29sb3JbMl0sIGVhc2UpLAoJCQkpOwoJCX0KCgkJLy8gU21vb3RoIGFtcGxpdHVkZTogZmFzdCBhdHRhY2ssIHNsb3cgcmVsZWFzZQoJCWNvbnN0IHJpc2luZyA9IGFtcGxpdHVkZSA+IHNtb290aEFtcDsKCQlzbW9vdGhBbXAgKz0gKGFtcGxpdHVkZSAtIHNtb290aEFtcCkgKiBNYXRoLm1pbigxLCBkZWx0YSAqIChyaXNpbmcgPyAxNCA6IDQpKTsKCgkJdS51VGltZS52YWx1ZSA9IGVsYXBzZWQ7CgkJdS51QW1wbGl0dWRlLnZhbHVlID0gc21vb3RoQW1wOwoKCQkvLyBDb2xvciBvdmVycmlkZTogZGVyaXZlIGZ1bGwgcGFsZXR0ZSArIGZyZXNuZWwgZnJvbSB1c2VyLXByb3ZpZGVkIGNvbG9yCgkJaWYgKGNvbG9yKSBhcHBseUN1c3RvbUNvbG9yKGNvbG9yLCB1KTsKCgkJLy8gR2VudGxlIGJyZWF0aGluZwoJCWNvbnN0IGJhc2VQdWxzZSA9IFNUQVRFU1tjdXJyZW50T3JiU3RhdGVdLmJhc2VQdWxzZTsKCQlvcmJNZXNoLnNjYWxlLnNldFNjYWxhcigxICsgYmFzZVB1bHNlICogTWF0aC5zaW4oZWxhcHNlZCAqIDIuNSkgKiAwLjUpOwoJCW9yYk1lc2gucm90YXRpb24ueSA9IGVsYXBzZWQgKiAwLjEyOwoJfSk7Cjwvc2NyaXB0PgoKPFQuUGVyc3BlY3RpdmVDYW1lcmEgbWFrZURlZmF1bHQgZm92PXs1MH0gbmVhcj17MC4xfSBmYXI9ezEwMH0gcG9zaXRpb249e1swLCAwLCA0XX0gLz4KCjxULk1lc2ggYmluZDpyZWY9e29yYk1lc2h9PgoJPFQuU3BoZXJlR2VvbWV0cnkgYXJncz17WzAuNzUsIDEyOCwgMTI4XX0gLz4KCTxULlNoYWRlck1hdGVyaWFsCgkJYmluZDpyZWY9e29yYk1hdGVyaWFsfQoJCXZlcnRleFNoYWRlcj17b3JiVmVydGV4fQoJCWZyYWdtZW50U2hhZGVyPXtvcmJGcmFnbWVudH0KCQl1bmlmb3Jtcz17b3JiVW5pZm9ybXN9CgkvPgo8L1QuTWVzaD4K", + "components/orb/orb.glsl.ts": "aW1wb3J0IHsgc2ltcGxleDNEIH0gZnJvbSAiLi9ub2lzZS5nbHNsIjsKCmV4cG9ydCBjb25zdCBvcmJWZXJ0ZXggPSBgCiAgdmFyeWluZyB2ZWMzIHZOb3JtYWwsIHZPYmpQb3MsIHZXb3JsZFBvczsKICB2b2lkIG1haW4oKXsKICAgIHZOb3JtYWwgPSBub3JtYWxpemUobm9ybWFsTWF0cml4ICogbm9ybWFsKTsKICAgIHZPYmpQb3MgPSBwb3NpdGlvbjsKICAgIHZXb3JsZFBvcyA9IChtb2RlbE1hdHJpeCAqIHZlYzQocG9zaXRpb24sMS4wKSkueHl6OwogICAgZ2xfUG9zaXRpb24gPSBwcm9qZWN0aW9uTWF0cml4ICogbW9kZWxWaWV3TWF0cml4ICogdmVjNChwb3NpdGlvbiwxLjApOwogIH0KYDsKCmV4cG9ydCBjb25zdCBvcmJGcmFnbWVudCA9IGAKICB1bmlmb3JtIGZsb2F0IHVUaW1lOwogIHVuaWZvcm0gdmVjMyB1TGlnaHRQb3M7CiAgdW5pZm9ybSBmbG9hdCB1QW1wbGl0dWRlOwogIHVuaWZvcm0gZmxvYXQgdU5vaXNlU3BlZWQ7CiAgdW5pZm9ybSB2ZWMzIHVGcmVzbmVsQ29sb3I7CiAgdW5pZm9ybSBmbG9hdCB1RnJlc25lbFN0cmVuZ3RoOwoKICB1bmlmb3JtIGZsb2F0IHVGbG93RHJpZnQ7CiAgdW5pZm9ybSBmbG9hdCB1Rmxvd091dDsKICB1bmlmb3JtIGZsb2F0IHVGbG93SW47CiAgdW5pZm9ybSBmbG9hdCB1Rmxvd1B1bHNlOwogIHVuaWZvcm0gZmxvYXQgdUZsb3dTd2lybDsKCiAgdW5pZm9ybSB2ZWMzIHVQYWxBMCwgdVBhbEExLCB1UGFsQTIsIHVQYWxBMywgdVBhbEE0OwogIHVuaWZvcm0gdmVjMyB1UGFsQjAsIHVQYWxCMSwgdVBhbEIyLCB1UGFsQjMsIHVQYWxCNDsKICB1bmlmb3JtIGZsb2F0IHVQYWxldHRlQmxlbmQ7CgogIHZhcnlpbmcgdmVjMyB2Tm9ybWFsLCB2T2JqUG9zLCB2V29ybGRQb3M7CgogICR7c2ltcGxleDNEfQoKICB2ZWMzIHBhbGV0dGVNaXgodmVjMyBjMCwgdmVjMyBjMSwgdmVjMyBjMiwgdmVjMyBjMywgdmVjMyBjNCwgZmxvYXQgbjEsIGZsb2F0IG4yLCBmbG9hdCBuMywgZmxvYXQgbjQpewogICAgdmVjMyBjID0gbWl4KGMwLCBjMSwgc21vb3Roc3RlcCguMTUsIC42NSwgbjEpKTsKICAgIGMgPSBtaXgoYywgYzIsIHNtb290aHN0ZXAoLjIsIC41NSwgbjIpKTsKICAgIGMgPSBtaXgoYywgYzMsIHNtb290aHN0ZXAoLjQsIC43NSwgbjMpICogLjYpOwogICAgYyA9IG1peChjLCBjNCwgc21vb3Roc3RlcCguMSwgLjQsIG40KSAqIC40KTsKICAgIHJldHVybiBjOwogIH0KCiAgdm9pZCBtYWluKCl7CiAgICB2ZWMzIE4gPSBub3JtYWxpemUodk5vcm1hbCk7CiAgICB2ZWMzIFYgPSBub3JtYWxpemUoY2FtZXJhUG9zaXRpb24gLSB2V29ybGRQb3MpOwogICAgdmVjMyBMID0gbm9ybWFsaXplKHVMaWdodFBvcyAtIHZXb3JsZFBvcyk7CgogICAgZmxvYXQgdCA9IHVUaW1lICogdU5vaXNlU3BlZWQ7CiAgICB2ZWMzIHJhZGlhbCA9IG5vcm1hbGl6ZSh2T2JqUG9zICsgdmVjMygwLjAwMSkpOwogICAgdmVjMyB0YW5nZW50ID0gbm9ybWFsaXplKGNyb3NzKHJhZGlhbCwgdmVjMygwLjAsIDEuMCwgMC4wMDEpKSk7CgogICAgZmxvYXQgYXVkaW9BY3RpdmUgPSB1Rmxvd091dCArIHVGbG93SW4gKyB1Rmxvd1B1bHNlOwoKICAgIHZlYzMgcCA9IHZPYmpQb3MgKiAxLjI7CgogICAgLy8gSWRsZTogZ2VudGxlIG1lYW5kZXJpbmcKICAgIHAgKz0gdmVjMyhzaW4odCowLjMpKjAuMTUsIHNpbih0KjAuMikqMC4yLCBjb3ModCowLjI1KSowLjE1KSAqIHVGbG93RHJpZnQ7CgogICAgLy8gRGljdGF0aW9uOiBzdHJvbmcgdmVydGljYWwgc2xpZGUKICAgIHAgKz0gdmVjMygwLjAsIHNpbih0ICogMS44KSAqIDAuNSArIHNpbih0ICogMi45KSAqIDAuMTUsIDAuMCkgKiB1Rmxvd091dDsKICAgIHAgKz0gdmVjMyhzaW4odCAqIDAuNCkgKiAwLjA4LCAwLjAsIGNvcyh0ICogMC4zKSAqIDAuMDgpICogdUZsb3dPdXQ7CgogICAgLy8gTGlzdGVuaW5nOiB0YW5nZW50aWFsIHN3aXJsIOKAlCBjb2xvcnMgdmlzaWJseSByb3RhdGUgYXJvdW5kIHRoZSBzcGhlcmUKICAgIHAgKz0gdGFuZ2VudCAqIHNpbih0ICogMS4yKSAqIDAuNSAqIHVGbG93SW47CiAgICBwICs9IGNyb3NzKHRhbmdlbnQsIHJhZGlhbCkgKiBjb3ModCAqIDAuOCkgKiAwLjMgKiB1Rmxvd0luOwogICAgcCAtPSByYWRpYWwgKiBzaW4odCAqIDEuNikgKiAwLjE1ICogdUZsb3dJbjsKCiAgICAvLyBUYWxraW5nOiByYWRpYWwgYnJlYXRoaW5nIOKAlCBjb2xvcnMgZXhwYW5kIG91dHdhcmQgYW5kIGNvbnRyYWN0IGJhY2sKICAgIHAgKz0gcmFkaWFsICogc2luKHQgKiAyLjApICogMC41NSAqIHVGbG93UHVsc2U7CiAgICBwICs9IHJhZGlhbCAqIHNpbih0ICogMy4zKSAqIDAuMiAqIHVGbG93UHVsc2U7CgogICAgLy8gV29ya2luZzogbGlzc2Fqb3VzIG9yYml0YWwgY2h1cm4KICAgIHAgKz0gdmVjMyhzaW4odCoxLjMpKjAuMzUsIGNvcyh0KjAuOSkqMC4zLCBzaW4odCoxLjcpKjAuMzUpICogdUZsb3dTd2lybDsKICAgIHAgKz0gdGFuZ2VudCAqIHNpbih0KjIuMCkgKiAwLjI1ICogdUZsb3dTd2lybDsKCiAgICBmbG9hdCB3YXJwQW10ID0gMC40ICogKDEuMCAtIGF1ZGlvQWN0aXZlICogMC41KTsKICAgIHZlYzMgd2FycDEgPSB2ZWMzKAogICAgICBzbm9pc2UocCArIHZlYzMoMC4wLCB0ICogMC4xMiwgMC4wKSksCiAgICAgIHNub2lzZShwICsgdmVjMyg1LjIsIHQgKiAwLjEwLCAxLjMpKSwKICAgICAgc25vaXNlKHAgKyB2ZWMzKDEuNywgMy40LCB0ICogMC4xNCkpCiAgICApOwogICAgcCArPSB3YXJwMSAqIHdhcnBBbXQ7CgogICAgdmVjMyB3YXJwMiA9IHZlYzMoCiAgICAgIHNub2lzZShwICogMC44ICsgdmVjMyh0ICogMC4wOCwgMC4wLCAzLjEpKSwKICAgICAgc25vaXNlKHAgKiAwLjggKyB2ZWMzKDguMywgdCAqIDAuMDcsIDAuMCkpLAogICAgICBzbm9pc2UocCAqIDAuOCArIHZlYzMoMC4wLCAyLjgsIHQgKiAwLjA5KSkKICAgICk7CiAgICB2ZWMzIGZjID0gcCArIHdhcnAyICogMC4xNTsKCiAgICBmbG9hdCBucyA9IDEuMCArIGF1ZGlvQWN0aXZlICogMC42OwogICAgZmxvYXQgbjEgPSBzbm9pc2UoZmMgKiAwLjcgKiBucykgKiAwLjUgKyAwLjU7CiAgICBmbG9hdCBuMiA9IHNub2lzZShmYyAqIDAuOSAqIG5zICsgdmVjMygzLjcsIDEuMiwgNC4xKSkgKiAwLjUgKyAwLjU7CiAgICBmbG9hdCBuMyA9IHNub2lzZShmYyAqIDAuNiAqIG5zICsgdmVjMyg3LjEsIDguMywgMi45KSkgKiAwLjUgKyAwLjU7CiAgICBmbG9hdCBuNCA9IHNub2lzZShmYyAqIDEuMSAqIG5zICsgdmVjMygyLjMsIDUuMSwgMC43KSkgKiAwLjUgKyAwLjU7CgogICAgdmVjMyBjb2xBID0gcGFsZXR0ZU1peCh1UGFsQTAsIHVQYWxBMSwgdVBhbEEyLCB1UGFsQTMsIHVQYWxBNCwgbjEsIG4yLCBuMywgbjQpOwogICAgdmVjMyBjb2xCID0gcGFsZXR0ZU1peCh1UGFsQjAsIHVQYWxCMSwgdVBhbEIyLCB1UGFsQjMsIHVQYWxCNCwgbjEsIG4yLCBuMywgbjQpOwogICAgdmVjMyBjb2wgPSBtaXgoY29sQSwgY29sQiwgdVBhbGV0dGVCbGVuZCk7CgogICAgZmxvYXQgZGlmZiA9IG1heChkb3QoTiwgTCksIDAuMCkgKiAwLjUgKyAwLjU7CiAgICB2ZWMzIEggPSBub3JtYWxpemUoTCArIFYpOwogICAgZmxvYXQgc3BlYyA9IHBvdyhtYXgoZG90KE4sIEgpLCAwLjApLCA0OC4wKSAqIDAuNDsKCiAgICB2ZWMzIGZDb2wgPSB1RnJlc25lbENvbG9yOwogICAgZmxvYXQgZlN0ciA9IHVGcmVzbmVsU3RyZW5ndGg7CiAgICBjb2wgPSBtaXgoY29sLCBmQ29sLCBwb3coMS4wIC0gbWF4KGRvdChOLCBWKSwgMC4wKSwgMi41KSAqIDAuMTggKiBmU3RyKTsKCiAgICB2ZWMzIGZpbiA9IGNvbCAqIGRpZmYgKyB2ZWMzKDEuMCkgKiBzcGVjICsgZkNvbCAqIHBvdygxLjAgLSBtYXgoZG90KE4sIFYpLCAwLjApLCAzLjApICogMC4zNSAqIGZTdHI7CiAgICBmaW4gKz0gZkNvbCAqIHBvdygxLjAgLSBtYXgoZG90KE4sIFYpLCAwLjApLCAzLjApICogMC4xMiAqIGZTdHI7CgogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChmaW4sIDEuMCk7CiAgfQpgOwoK", + "components/orb/noise.glsl.ts": "ZXhwb3J0IGNvbnN0IHNpbXBsZXgzRCA9IGAKICB2ZWM0IHBlcm11dGUodmVjNCB4KXtyZXR1cm4gbW9kKCgoeCozNC4wKSsxLjApKngsMjg5LjApO30KICB2ZWM0IHRheWxvckludlNxcnQodmVjNCByKXtyZXR1cm4gMS43OTI4NDI5MTQwMDE1OS0wLjg1MzczNDcyMDk1MzE0KnI7fQogIGZsb2F0IHNub2lzZSh2ZWMzIHYpewogICAgY29uc3QgdmVjMiBDPXZlYzIoMS4wLzYuMCwxLjAvMy4wKTsgY29uc3QgdmVjNCBEPXZlYzQoMC4wLDAuNSwxLjAsMi4wKTsKICAgIHZlYzMgaT1mbG9vcih2K2RvdCh2LEMueXl5KSk7IHZlYzMgeDA9di1pK2RvdChpLEMueHh4KTsKICAgIHZlYzMgZz1zdGVwKHgwLnl6eCx4MC54eXopOyB2ZWMzIGw9MS4wLWc7CiAgICB2ZWMzIGkxPW1pbihnLnh5eixsLnp4eSk7IHZlYzMgaTI9bWF4KGcueHl6LGwuenh5KTsKICAgIHZlYzMgeDE9eDAtaTErQy54eHg7IHZlYzMgeDI9eDAtaTIrQy55eXk7IHZlYzMgeDM9eDAtRC55eXk7CiAgICBpPW1vZChpLDI4OS4wKTsKICAgIHZlYzQgcD1wZXJtdXRlKHBlcm11dGUocGVybXV0ZShpLnordmVjNCgwLjAsaTEueixpMi56LDEuMCkpK2kueSt2ZWM0KDAuMCxpMS55LGkyLnksMS4wKSkraS54K3ZlYzQoMC4wLGkxLngsaTIueCwxLjApKTsKICAgIGZsb2F0IG5fPTEuMC83LjA7IHZlYzMgbnM9bl8qRC53eXotRC54eng7CiAgICB2ZWM0IGo9cC00OS4wKmZsb29yKHAqbnMueipucy56KTsKICAgIHZlYzQgeF89Zmxvb3Ioaipucy56KTsgdmVjNCB5Xz1mbG9vcihqLTcuMCp4Xyk7CiAgICB2ZWM0IHg9eF8qbnMueCtucy55eXl5OyB2ZWM0IHk9eV8qbnMueCtucy55eXl5OwogICAgdmVjNCBoPTEuMC1hYnMoeCktYWJzKHkpOwogICAgdmVjNCBiMD12ZWM0KHgueHkseS54eSk7IHZlYzQgYjE9dmVjNCh4Lnp3LHkuencpOwogICAgdmVjNCBzMD1mbG9vcihiMCkqMi4wKzEuMDsgdmVjNCBzMT1mbG9vcihiMSkqMi4wKzEuMDsKICAgIHZlYzQgc2g9LXN0ZXAoaCx2ZWM0KDAuMCkpOwogICAgdmVjNCBhMD1iMC54enl3K3MwLnh6eXcqc2gueHh5eTsgdmVjNCBhMT1iMS54enl3K3MxLnh6eXcqc2guenp3dzsKICAgIHZlYzMgcDA9dmVjMyhhMC54eSxoLngpOyB2ZWMzIHAxPXZlYzMoYTAuencsaC55KTsKICAgIHZlYzMgcDI9dmVjMyhhMS54eSxoLnopOyB2ZWMzIHAzPXZlYzMoYTEuencsaC53KTsKICAgIHZlYzQgbm9ybT10YXlsb3JJbnZTcXJ0KHZlYzQoZG90KHAwLHAwKSxkb3QocDEscDEpLGRvdChwMixwMiksZG90KHAzLHAzKSkpOwogICAgcDAqPW5vcm0ueDtwMSo9bm9ybS55O3AyKj1ub3JtLno7cDMqPW5vcm0udzsKICAgIHZlYzQgbT1tYXgoMC42LXZlYzQoZG90KHgwLHgwKSxkb3QoeDEseDEpLGRvdCh4Mix4MiksZG90KHgzLHgzKSksMC4wKTsKICAgIG09bSptOwogICAgcmV0dXJuIDQyLjAqZG90KG0qbSx2ZWM0KGRvdChwMCx4MCksZG90KHAxLHgxKSxkb3QocDIseDIpLGRvdChwMyx4MykpKTsKICB9CmA7Cg==", + "components/orb/types.ts": "ZXhwb3J0IHR5cGUgT3JiU3RhdGUgPSAiaWRsZSIgfCAiYXR0dW5lIiB8ICJwdWxzZSIgfCAic3VyZ2UiOwoKZXhwb3J0IHR5cGUgU3RhdGVDb25maWcgPSB7CglwYWxldHRlOiBbbnVtYmVyW10sIG51bWJlcltdLCBudW1iZXJbXSwgbnVtYmVyW10sIG51bWJlcltdXTsKCWZyZXNuZWxDb2xvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdOwoJZnJlc25lbFN0cmVuZ3RoOiBudW1iZXI7Cglub2lzZVNwZWVkOiBudW1iZXI7CglmbG93RHJpZnQ6IG51bWJlcjsKCWZsb3dPdXQ6IG51bWJlcjsKCWZsb3dJbjogbnVtYmVyOwoJZmxvd1B1bHNlOiBudW1iZXI7CglmbG93U3dpcmw6IG51bWJlcjsKCWJhc2VQdWxzZTogbnVtYmVyOwp9Owo=", "components/pixelated-image/PixelatedImage.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBDYW52YXMgfSBmcm9tICJAdGhyZWx0ZS9jb3JlIjsKCWltcG9ydCBTY2VuZSBmcm9tICIuL1BpeGVsYXRlZEltYWdlU2NlbmUuc3ZlbHRlIjsKCWltcG9ydCB7IGNuIH0gZnJvbSAiLi4vdXRpbHMvY24iOwoJaW1wb3J0IHsgTm9Ub25lTWFwcGluZyB9IGZyb20gInRocmVlIjsKCWltcG9ydCB0eXBlIHsgQ29tcG9uZW50UHJvcHMgfSBmcm9tICJzdmVsdGUiOwoKCXR5cGUgU2NlbmVQcm9wcyA9IENvbXBvbmVudFByb3BzPHR5cGVvZiBTY2VuZT47CgoJaW50ZXJmYWNlIFByb3BzIHsKCQkvKioKCQkgKiBUaGUgaW1hZ2Ugc291cmNlIFVSTC4KCQkgKi8KCQlzcmM6IFNjZW5lUHJvcHNbImltYWdlIl07CgkJLyoqCgkJICogQWRkaXRpb25hbCBDU1MgY2xhc3NlcyBmb3IgdGhlIGNvbnRhaW5lci4KCQkgKi8KCQljbGFzcz86IHN0cmluZzsKCQkvKioKCQkgKiBJbml0aWFsIGdyaWQgc2l6ZSBmb3IgdGhlIHBpeGVsYXRpb24gZWZmZWN0LgoJCSAqIEBkZWZhdWx0IDYuMAoJCSAqLwoJCWluaXRpYWxHcmlkU2l6ZT86IFNjZW5lUHJvcHNbImluaXRpYWxHcmlkU2l6ZSJdOwoJCS8qKgoJCSAqIER1cmF0aW9uIG9mIGVhY2ggc3RlcCBpbiB0aGUgZGVwaXhlbGF0aW9uIGFuaW1hdGlvbi4KCQkgKiBAZGVmYXVsdCAwLjE1CgkJICovCgkJc3RlcER1cmF0aW9uPzogU2NlbmVQcm9wc1sic3RlcER1cmF0aW9uIl07CgkJW2tleTogc3RyaW5nXTogdW5rbm93bjsKCX0KCglsZXQgewoJCXNyYywKCQljbGFzczogY2xhc3NOYW1lID0gIiIsCgkJaW5pdGlhbEdyaWRTaXplID0gNi4wLAoJCXN0ZXBEdXJhdGlvbiA9IDAuMTUsCgkJLi4ucmVzdAoJfTogUHJvcHMgPSAkcHJvcHMoKTsKCgljb25zdCBkcHIgPSB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiA/IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIDogMTsKPC9zY3JpcHQ+Cgo8ZGl2IGNsYXNzPXtjbigicmVsYXRpdmUgaC1mdWxsIHctZnVsbCBvdmVyZmxvdy1oaWRkZW4iLCBjbGFzc05hbWUpfSB7Li4ucmVzdH0+Cgk8ZGl2IGNsYXNzPSJhYnNvbHV0ZSBpbnNldC0wIHotMCI+CgkJPENhbnZhcyB7ZHByfSB0b25lTWFwcGluZz17Tm9Ub25lTWFwcGluZ30+CgkJCTxTY2VuZSBpbWFnZT17c3JjfSB7aW5pdGlhbEdyaWRTaXplfSB7c3RlcER1cmF0aW9ufSAvPgoJCTwvQ2FudmFzPgoJPC9kaXY+CjwvZGl2Pgo=", "components/pixelated-image/PixelatedImageScene.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBULCB1c2VUYXNrLCB1c2VUaHJlbHRlIH0gZnJvbSAiQHRocmVsdGUvY29yZSI7CglpbXBvcnQgeyB1c2VUZXh0dXJlIH0gZnJvbSAiQHRocmVsdGUvZXh0cmFzIjsKCWltcG9ydCB7IFZlY3RvcjIsIE5lYXJlc3RGaWx0ZXIsIExpbmVhckZpbHRlciwgU2hhZGVyTWF0ZXJpYWwgfSBmcm9tICJ0aHJlZSI7CgoJaW50ZXJmYWNlIFByb3BzIHsKCQkvKioKCQkgKiBUaGUgaW1hZ2Ugc291cmNlIFVSTC4KCQkgKi8KCQlpbWFnZTogc3RyaW5nOwoJCS8qKgoJCSAqIEluaXRpYWwgZ3JpZCBzaXplIGZvciB0aGUgcGl4ZWxhdGlvbiBlZmZlY3QuCgkJICogQGRlZmF1bHQgNi4wCgkJICovCgkJaW5pdGlhbEdyaWRTaXplPzogbnVtYmVyOwoJCS8qKgoJCSAqIER1cmF0aW9uIG9mIGVhY2ggc3RlcCBpbiB0aGUgZGVwaXhlbGF0aW9uIGFuaW1hdGlvbi4KCQkgKiBAZGVmYXVsdCAwLjE1CgkJICovCgkJc3RlcER1cmF0aW9uPzogbnVtYmVyOwoJfQoKCWxldCB7IGltYWdlLCBpbml0aWFsR3JpZFNpemUgPSA2LjAsIHN0ZXBEdXJhdGlvbiA9IDAuMTUgfTogUHJvcHMgPSAkcHJvcHMoKTsKCgljb25zdCB7IHNpemUgfSA9IHVzZVRocmVsdGUoKTsKCWxldCB0aW1lID0gMDsKCWxldCBjdXJyZW50R3JpZFNpemUgPSAkc3RhdGUoNi4wKTsKCWxldCBpc0RvbmUgPSAkc3RhdGUoZmFsc2UpOwoJbGV0IG1hdGVyaWFsID0gJHN0YXRlPFNoYWRlck1hdGVyaWFsPigpOwoKCWNvbnN0IHJlc29sdXRpb25Vbmlmb3JtID0gbmV3IFZlY3RvcjIoMSwgMSk7Cgljb25zdCB0ZXh0dXJlU2l6ZVVuaWZvcm0gPSBuZXcgVmVjdG9yMigxLCAxKTsKCgkkZWZmZWN0KCgpID0+IHsKCQljb25zdCBuZXh0V2lkdGggPSAkc2l6ZS53aWR0aDsKCQljb25zdCBuZXh0SGVpZ2h0ID0gJHNpemUuaGVpZ2h0OwoJCXJlc29sdXRpb25Vbmlmb3JtLnNldChuZXh0V2lkdGgsIG5leHRIZWlnaHQpOwoJfSk7CgoJJGVmZmVjdCgoKSA9PiB7CgkJY3VycmVudEdyaWRTaXplID0gaW5pdGlhbEdyaWRTaXplOwoJCXRpbWUgPSAwOwoJCWlzRG9uZSA9IGZhbHNlOwoJfSk7CgoJY29uc3QgdGV4dHVyZSA9ICRkZXJpdmVkKAoJCXVzZVRleHR1cmUoaW1hZ2UsIHsKCQkJdHJhbnNmb3JtOiAodGV4KSA9PiB7CgkJCQl0ZXgubWFnRmlsdGVyID0gTmVhcmVzdEZpbHRlcjsKCQkJCXRleC5taW5GaWx0ZXIgPSBOZWFyZXN0RmlsdGVyOwoJCQkJdGV4LmdlbmVyYXRlTWlwbWFwcyA9IGZhbHNlOwoJCQkJcmV0dXJuIHRleDsKCQkJfSwKCQl9KSwKCSk7CgoJJGVmZmVjdCgoKSA9PiB7CgkJY29uc3QgdGV4ID0gJHRleHR1cmU7CgkJaWYgKHRleCAmJiB0ZXguaW1hZ2UpIHsKCQkJdGV4dHVyZVNpemVVbmlmb3JtLnNldCh0ZXguaW1hZ2Uud2lkdGgsIHRleC5pbWFnZS5oZWlnaHQpOwoJCX0KCX0pOwoKCXVzZVRhc2soKGRlbHRhKSA9PiB7CgkJaWYgKCFpc0RvbmUpIHsKCQkJdGltZSArPSBkZWx0YTsKCgkJCWNvbnN0IHN0ZXAgPSBNYXRoLmZsb29yKHRpbWUgLyBzdGVwRHVyYXRpb24pOwoJCQljb25zdCBuZXh0R3JpZCA9IGluaXRpYWxHcmlkU2l6ZSAqIE1hdGgucG93KDIsIHN0ZXApOwoKCQkJY3VycmVudEdyaWRTaXplID0gbmV4dEdyaWQ7CgoJCQlpZiAoY3VycmVudEdyaWRTaXplID4gJHNpemUuaGVpZ2h0KSB7CgkJCQlpc0RvbmUgPSB0cnVlOwoJCQkJaWYgKCR0ZXh0dXJlKSB7CgkJCQkJJHRleHR1cmUubWFnRmlsdGVyID0gTGluZWFyRmlsdGVyOwoJCQkJCSR0ZXh0dXJlLm1pbkZpbHRlciA9IExpbmVhckZpbHRlcjsKCQkJCQkkdGV4dHVyZS5uZWVkc1VwZGF0ZSA9IHRydWU7CgkJCQl9CgkJCX0KCQl9CgkJaWYgKG1hdGVyaWFsKSB7CgkJCW1hdGVyaWFsLnVuaWZvcm1zLnVHcmlkU2l6ZS52YWx1ZSA9IGN1cnJlbnRHcmlkU2l6ZTsKCQkJbWF0ZXJpYWwudW5pZm9ybXMudUlzRG9uZS52YWx1ZSA9IGlzRG9uZTsKCQl9Cgl9KTsKCgljb25zdCB2ZXJ0ZXhTaGFkZXIgPSBgCiAgICB2YXJ5aW5nIHZlYzIgdlV2OwogICAgdm9pZCBtYWluKCkgewogICAgICB2VXYgPSB1djsKICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAxLjApOwogICAgfQogIGA7CgoJY29uc3QgZnJhZ21lbnRTaGFkZXIgPSBgCiAgICB1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZTsKICAgIHVuaWZvcm0gdmVjMiB1UmVzb2x1dGlvbjsKICAgIHVuaWZvcm0gdmVjMiB1VGV4dHVyZVNpemU7CiAgICB1bmlmb3JtIGZsb2F0IHVHcmlkU2l6ZTsKICAgIHVuaWZvcm0gYm9vbCB1SXNEb25lOwoKICAgIHZhcnlpbmcgdmVjMiB2VXY7CgogICAgdmVjMiBnZXRDb3ZlclVWKHZlYzIgdXYsIHZlYzIgdGV4dHVyZVNpemUpIHsKICAgICAgIHZlYzIgcyA9IHVSZXNvbHV0aW9uIC8gdGV4dHVyZVNpemU7CiAgICAgICBmbG9hdCBzY2FsZSA9IG1heChzLngsIHMueSk7CiAgICAgICB2ZWMyIHNjYWxlZFNpemUgPSB0ZXh0dXJlU2l6ZSAqIHNjYWxlOwogICAgICAgdmVjMiBvZmZzZXQgPSAodVJlc29sdXRpb24gLSBzY2FsZWRTaXplKSAqIDAuNTsKICAgICAgIHJldHVybiAodXYgKiB1UmVzb2x1dGlvbiAtIG9mZnNldCkgLyBzY2FsZWRTaXplOwogICAgfQoKICAgIHZvaWQgbWFpbigpIHsKICAgICAgIHZlYzIgcyA9IHVSZXNvbHV0aW9uOwogICAgICAgZmxvYXQgcnMgPSBzLnggLyBtYXgocy55LCAwLjAwMDAxKTsKCiAgICAgICB2ZWMyIGdyaWQgPSB2ZWMyKHVHcmlkU2l6ZSAqIHJzLCB1R3JpZFNpemUpOwogICAgICAgdmVjMiBwaXhlbGF0ZWRTY3JlZW5VdiA9IGZsb29yKHZVdiAqIGdyaWQpIC8gZ3JpZCArICgwLjUgLyBncmlkKTsKCiAgICAgICB2ZWMyIGZpbmFsVXYgPSB1SXNEb25lID8gdlV2IDogcGl4ZWxhdGVkU2NyZWVuVXY7CiAgICAgICB2ZWMyIGNvdmVyVXYgPSBnZXRDb3ZlclVWKGZpbmFsVXYsIHVUZXh0dXJlU2l6ZSk7CgogICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh1VGV4dHVyZSwgY292ZXJVdik7CiAgICAgICBnbF9GcmFnQ29sb3IgPSBjb2xvcjsKICAgICAgICNpbmNsdWRlIDxjb2xvcnNwYWNlX2ZyYWdtZW50PgogICAgfQogIGA7Cjwvc2NyaXB0PgoKeyNpZiAkdGV4dHVyZX0KCTxULk1lc2g+CgkJPFQuUGxhbmVHZW9tZXRyeSBhcmdzPXtbMiwgMl19IC8+CgkJPFQuU2hhZGVyTWF0ZXJpYWwKCQkJYmluZDpyZWY9e21hdGVyaWFsfQoJCQl7dmVydGV4U2hhZGVyfQoJCQl7ZnJhZ21lbnRTaGFkZXJ9CgkJCXVuaWZvcm1zPXt7CgkJCQl1VGV4dHVyZTogeyB2YWx1ZTogJHRleHR1cmUgfSwKCQkJCXVSZXNvbHV0aW9uOiB7IHZhbHVlOiByZXNvbHV0aW9uVW5pZm9ybSB9LAoJCQkJdVRleHR1cmVTaXplOiB7IHZhbHVlOiB0ZXh0dXJlU2l6ZVVuaWZvcm0gfSwKCQkJCXVHcmlkU2l6ZTogeyB2YWx1ZTogaW5pdGlhbEdyaWRTaXplIH0sCgkJCQl1SXNEb25lOiB7IHZhbHVlOiBmYWxzZSB9LAoJCQl9fQoJCS8+Cgk8L1QuTWVzaD4Key9pZn0K", "components/plasma-grid/PlasmaGrid.svelte": "PHNjcmlwdCBsYW5nPSJ0cyI+CglpbXBvcnQgeyBDYW52YXMgfSBmcm9tICJAdGhyZWx0ZS9jb3JlIjsKCWltcG9ydCBTY2VuZSBmcm9tICIuL1BsYXNtYUdyaWRTY2VuZS5zdmVsdGUiOwoJaW1wb3J0IHsgY24gfSBmcm9tICIuLi91dGlscy9jbiI7CglpbXBvcnQgeyBOb1RvbmVNYXBwaW5nIH0gZnJvbSAidGhyZWUiOwoJaW1wb3J0IHR5cGUgeyBDb21wb25lbnRQcm9wcyB9IGZyb20gInN2ZWx0ZSI7CgoJdHlwZSBTY2VuZVByb3BzID0gQ29tcG9uZW50UHJvcHM8dHlwZW9mIFNjZW5lPjsKCglpbnRlcmZhY2UgUHJvcHMgewoJCS8qKgoJCSAqIFRoZSBiYXNlIGJhY2tncm91bmQgY29sb3Igb2YgdGhlIGVmZmVjdC4KCQkgKiBAZGVmYXVsdCAiIzExMTExMyIKCQkgKi8KCQljb2xvcj86IFNjZW5lUHJvcHNbImNvbG9yIl07CgkJLyoqCgkJICogVGhlIGNvbG9yIHVzZWQgZm9yIHRoZSBwbGFzbWEgbm9pc2UgZ3JhZGllbnRzLgoJCSAqIEBkZWZhdWx0ICIjRkY2OTAwIgoJCSAqLwoJCWhpZ2hsaWdodENvbG9yPzogU2NlbmVQcm9wc1siaGlnaGxpZ2h0Q29sb3IiXTsKCQkvKioKCQkgKiBBZGRpdGlvbmFsIENTUyBjbGFzc2VzIGZvciB0aGUgY29udGFpbmVyLgoJCSAqLwoJCWNsYXNzPzogc3RyaW5nOwoJCVtrZXk6IHN0cmluZ106IHVua25vd247Cgl9CgoJbGV0IHsKCQljb2xvciwKCQloaWdobGlnaHRDb2xvciwKCQljbGFzczogY2xhc3NOYW1lID0gIiIsCgkJLi4ucmVzdAoJfTogUHJvcHMgPSAkcHJvcHMoKTsKCgljb25zdCBkcHIgPSB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiA/IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIDogMTsKPC9zY3JpcHQ+Cgo8ZGl2IGNsYXNzPXtjbigicmVsYXRpdmUgaC1mdWxsIHctZnVsbCBvdmVyZmxvdy1oaWRkZW4iLCBjbGFzc05hbWUpfSB7Li4ucmVzdH0+Cgk8ZGl2IGNsYXNzPSJhYnNvbHV0ZSBpbnNldC0wIHotMCI+CgkJPENhbnZhcyB7ZHByfSB0b25lTWFwcGluZz17Tm9Ub25lTWFwcGluZ30+CgkJCTxTY2VuZSB7Y29sb3J9IHtoaWdobGlnaHRDb2xvcn0gLz4KCQk8L0NhbnZhcz4KCTwvZGl2Pgo8L2Rpdj4K", diff --git a/apps/web/static/registry/registry.json b/apps/web/static/registry/registry.json index 5040638..53fde9f 100644 --- a/apps/web/static/registry/registry.json +++ b/apps/web/static/registry/registry.json @@ -751,6 +751,43 @@ } ] }, + "orb": { + "slug": "orb", + "name": "Orb", + "description": "A 3D animated orb with state-driven flow patterns — idle drift, attune swirl, pulse breathing, surge churn — and smooth palette transitions between states.", + "category": "canvas", + "dependencies": { + "@threlte/core": "^8.3.1", + "three": "^0.182.0" + }, + "devDependencies": { + "@types/three": "^0.182.0" + }, + "internalDependencies": [], + "files": [ + { + "path": "components/orb/Orb.svelte", + "kind": "entry" + }, + { + "path": "components/orb/OrbScene.svelte" + }, + { + "path": "components/orb/orb.glsl.ts" + }, + { + "path": "components/orb/noise.glsl.ts" + }, + { + "path": "components/orb/types.ts", + "typeExports": ["OrbState"] + }, + { + "path": "utils/cn.ts", + "target": "utils" + } + ] + }, "pixelated-image": { "slug": "pixelated-image", "name": "Pixelated Image", diff --git a/bun.lock b/bun.lock index ea33fdf..91a405a 100644 --- a/bun.lock +++ b/bun.lock @@ -69,7 +69,7 @@ }, "packages/motion-core": { "name": "motion-core", - "version": "0.7.0", + "version": "0.10.0", "dependencies": { "clsx": "^2.1.1", "tailwind-merge": "^3.4.0", diff --git a/packages/motion-core/src/lib/components/index.ts b/packages/motion-core/src/lib/components/index.ts index 3569b20..eac6cb5 100644 --- a/packages/motion-core/src/lib/components/index.ts +++ b/packages/motion-core/src/lib/components/index.ts @@ -43,3 +43,5 @@ export { default as VideoPlayer } from "./video-player/VideoPlayer.svelte"; export { default as GodRays } from "./god-rays/GodRays.svelte"; export { default as SpecularBand } from "./specular-band/SpecularBand.svelte"; export { default as Halo } from "./halo/Halo.svelte"; +export { default as Orb } from "./orb/Orb.svelte"; +export type { OrbState } from "./orb/types"; diff --git a/packages/motion-core/src/lib/components/orb/Orb.svelte b/packages/motion-core/src/lib/components/orb/Orb.svelte new file mode 100644 index 0000000..4719055 --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/Orb.svelte @@ -0,0 +1,60 @@ + + +
+
+ + + +
+
diff --git a/packages/motion-core/src/lib/components/orb/OrbScene.svelte b/packages/motion-core/src/lib/components/orb/OrbScene.svelte new file mode 100644 index 0000000..051487e --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/OrbScene.svelte @@ -0,0 +1,290 @@ + + + + + + + + diff --git a/packages/motion-core/src/lib/components/orb/component.json b/packages/motion-core/src/lib/components/orb/component.json new file mode 100644 index 0000000..62f3609 --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/component.json @@ -0,0 +1,37 @@ +{ + "name": "Orb", + "slug": "orb", + "description": "A 3D animated orb with state-driven flow patterns — idle drift, attune swirl, pulse breathing, surge churn — and smooth palette transitions between states.", + "category": "canvas", + "dependencies": { + "@threlte/core": "^8.3.1", + "three": "^0.182.0" + }, + "devDependencies": { + "@types/three": "^0.182.0" + }, + "internalDependencies": [], + "files": [ + { + "path": "Orb.svelte", + "kind": "entry" + }, + { + "path": "OrbScene.svelte" + }, + { + "path": "orb.glsl.ts" + }, + { + "path": "noise.glsl.ts" + }, + { + "path": "types.ts", + "typeExports": ["OrbState"] + }, + { + "path": "../../utils/cn.ts", + "target": "utils" + } + ] +} diff --git a/packages/motion-core/src/lib/components/orb/noise.glsl.ts b/packages/motion-core/src/lib/components/orb/noise.glsl.ts new file mode 100644 index 0000000..5aa43ae --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/noise.glsl.ts @@ -0,0 +1,29 @@ +export const simplex3D = ` + vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x,289.0);} + vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;} + float snoise(vec3 v){ + const vec2 C=vec2(1.0/6.0,1.0/3.0); const vec4 D=vec4(0.0,0.5,1.0,2.0); + vec3 i=floor(v+dot(v,C.yyy)); vec3 x0=v-i+dot(i,C.xxx); + vec3 g=step(x0.yzx,x0.xyz); vec3 l=1.0-g; + vec3 i1=min(g.xyz,l.zxy); vec3 i2=max(g.xyz,l.zxy); + vec3 x1=x0-i1+C.xxx; vec3 x2=x0-i2+C.yyy; vec3 x3=x0-D.yyy; + i=mod(i,289.0); + vec4 p=permute(permute(permute(i.z+vec4(0.0,i1.z,i2.z,1.0))+i.y+vec4(0.0,i1.y,i2.y,1.0))+i.x+vec4(0.0,i1.x,i2.x,1.0)); + float n_=1.0/7.0; vec3 ns=n_*D.wyz-D.xzx; + vec4 j=p-49.0*floor(p*ns.z*ns.z); + vec4 x_=floor(j*ns.z); vec4 y_=floor(j-7.0*x_); + vec4 x=x_*ns.x+ns.yyyy; vec4 y=y_*ns.x+ns.yyyy; + vec4 h=1.0-abs(x)-abs(y); + vec4 b0=vec4(x.xy,y.xy); vec4 b1=vec4(x.zw,y.zw); + vec4 s0=floor(b0)*2.0+1.0; vec4 s1=floor(b1)*2.0+1.0; + vec4 sh=-step(h,vec4(0.0)); + vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy; vec4 a1=b1.xzyw+s1.xzyw*sh.zzww; + vec3 p0=vec3(a0.xy,h.x); vec3 p1=vec3(a0.zw,h.y); + vec3 p2=vec3(a1.xy,h.z); vec3 p3=vec3(a1.zw,h.w); + vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3))); + p0*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w; + vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.0); + m=m*m; + return 42.0*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3))); + } +`; diff --git a/packages/motion-core/src/lib/components/orb/orb.glsl.ts b/packages/motion-core/src/lib/components/orb/orb.glsl.ts new file mode 100644 index 0000000..43cdab4 --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/orb.glsl.ts @@ -0,0 +1,114 @@ +import { simplex3D } from "./noise.glsl"; + +export const orbVertex = ` + varying vec3 vNormal, vObjPos, vWorldPos; + void main(){ + vNormal = normalize(normalMatrix * normal); + vObjPos = position; + vWorldPos = (modelMatrix * vec4(position,1.0)).xyz; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); + } +`; + +export const orbFragment = ` + uniform float uTime; + uniform vec3 uLightPos; + uniform float uAmplitude; + uniform float uNoiseSpeed; + uniform vec3 uFresnelColor; + uniform float uFresnelStrength; + + uniform float uFlowDrift; + uniform float uFlowOut; + uniform float uFlowIn; + uniform float uFlowPulse; + uniform float uFlowSwirl; + + uniform vec3 uPalA0, uPalA1, uPalA2, uPalA3, uPalA4; + uniform vec3 uPalB0, uPalB1, uPalB2, uPalB3, uPalB4; + uniform float uPaletteBlend; + + varying vec3 vNormal, vObjPos, vWorldPos; + + ${simplex3D} + + vec3 paletteMix(vec3 c0, vec3 c1, vec3 c2, vec3 c3, vec3 c4, float n1, float n2, float n3, float n4){ + vec3 c = mix(c0, c1, smoothstep(.15, .65, n1)); + c = mix(c, c2, smoothstep(.2, .55, n2)); + c = mix(c, c3, smoothstep(.4, .75, n3) * .6); + c = mix(c, c4, smoothstep(.1, .4, n4) * .4); + return c; + } + + void main(){ + vec3 N = normalize(vNormal); + vec3 V = normalize(cameraPosition - vWorldPos); + vec3 L = normalize(uLightPos - vWorldPos); + + float t = uTime * uNoiseSpeed; + vec3 radial = normalize(vObjPos + vec3(0.001)); + vec3 tangent = normalize(cross(radial, vec3(0.0, 1.0, 0.001))); + + float audioActive = uFlowOut + uFlowIn + uFlowPulse; + + vec3 p = vObjPos * 1.2; + + // Idle: gentle meandering + p += vec3(sin(t*0.3)*0.15, sin(t*0.2)*0.2, cos(t*0.25)*0.15) * uFlowDrift; + + // Dictation: strong vertical slide + p += vec3(0.0, sin(t * 1.8) * 0.5 + sin(t * 2.9) * 0.15, 0.0) * uFlowOut; + p += vec3(sin(t * 0.4) * 0.08, 0.0, cos(t * 0.3) * 0.08) * uFlowOut; + + // Listening: tangential swirl — colors visibly rotate around the sphere + p += tangent * sin(t * 1.2) * 0.5 * uFlowIn; + p += cross(tangent, radial) * cos(t * 0.8) * 0.3 * uFlowIn; + p -= radial * sin(t * 1.6) * 0.15 * uFlowIn; + + // Talking: radial breathing — colors expand outward and contract back + p += radial * sin(t * 2.0) * 0.55 * uFlowPulse; + p += radial * sin(t * 3.3) * 0.2 * uFlowPulse; + + // Working: lissajous orbital churn + p += vec3(sin(t*1.3)*0.35, cos(t*0.9)*0.3, sin(t*1.7)*0.35) * uFlowSwirl; + p += tangent * sin(t*2.0) * 0.25 * uFlowSwirl; + + float warpAmt = 0.4 * (1.0 - audioActive * 0.5); + vec3 warp1 = vec3( + snoise(p + vec3(0.0, t * 0.12, 0.0)), + snoise(p + vec3(5.2, t * 0.10, 1.3)), + snoise(p + vec3(1.7, 3.4, t * 0.14)) + ); + p += warp1 * warpAmt; + + vec3 warp2 = vec3( + snoise(p * 0.8 + vec3(t * 0.08, 0.0, 3.1)), + snoise(p * 0.8 + vec3(8.3, t * 0.07, 0.0)), + snoise(p * 0.8 + vec3(0.0, 2.8, t * 0.09)) + ); + vec3 fc = p + warp2 * 0.15; + + float ns = 1.0 + audioActive * 0.6; + float n1 = snoise(fc * 0.7 * ns) * 0.5 + 0.5; + float n2 = snoise(fc * 0.9 * ns + vec3(3.7, 1.2, 4.1)) * 0.5 + 0.5; + float n3 = snoise(fc * 0.6 * ns + vec3(7.1, 8.3, 2.9)) * 0.5 + 0.5; + float n4 = snoise(fc * 1.1 * ns + vec3(2.3, 5.1, 0.7)) * 0.5 + 0.5; + + vec3 colA = paletteMix(uPalA0, uPalA1, uPalA2, uPalA3, uPalA4, n1, n2, n3, n4); + vec3 colB = paletteMix(uPalB0, uPalB1, uPalB2, uPalB3, uPalB4, n1, n2, n3, n4); + vec3 col = mix(colA, colB, uPaletteBlend); + + float diff = max(dot(N, L), 0.0) * 0.5 + 0.5; + vec3 H = normalize(L + V); + float spec = pow(max(dot(N, H), 0.0), 48.0) * 0.4; + + vec3 fCol = uFresnelColor; + float fStr = uFresnelStrength; + col = mix(col, fCol, pow(1.0 - max(dot(N, V), 0.0), 2.5) * 0.18 * fStr); + + vec3 fin = col * diff + vec3(1.0) * spec + fCol * pow(1.0 - max(dot(N, V), 0.0), 3.0) * 0.35 * fStr; + fin += fCol * pow(1.0 - max(dot(N, V), 0.0), 3.0) * 0.12 * fStr; + + gl_FragColor = vec4(fin, 1.0); + } +`; diff --git a/packages/motion-core/src/lib/components/orb/types.ts b/packages/motion-core/src/lib/components/orb/types.ts new file mode 100644 index 0000000..c75f183 --- /dev/null +++ b/packages/motion-core/src/lib/components/orb/types.ts @@ -0,0 +1,14 @@ +export type OrbState = "idle" | "attune" | "pulse" | "surge"; + +export type StateConfig = { + palette: [number[], number[], number[], number[], number[]]; + fresnelColor: [number, number, number]; + fresnelStrength: number; + noiseSpeed: number; + flowDrift: number; + flowOut: number; + flowIn: number; + flowPulse: number; + flowSwirl: number; + basePulse: number; +};