@hjmds/design-contracts 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +58 -0
- package/dist/agreement.d.ts +3 -3
- package/dist/agreement.js +1 -1
- package/dist/agreement.js.map +1 -1
- package/dist/asset.d.ts +1 -1
- package/dist/asset.js +1 -1
- package/dist/asset.js.map +1 -1
- package/dist/base-recipes.d.ts +12 -12
- package/dist/base-recipes.d.ts.map +1 -1
- package/dist/base-recipes.js +15 -14
- package/dist/base-recipes.js.map +1 -1
- package/dist/behaviors.d.ts +1 -1
- package/dist/catalog.d.ts +417 -561
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +138 -90
- package/dist/catalog.js.map +1 -1
- package/dist/command-palette.d.ts +3 -3
- package/dist/component-contracts.d.ts +4 -4
- package/dist/component-contracts.d.ts.map +1 -1
- package/dist/component-contracts.js +5 -4
- package/dist/component-contracts.js.map +1 -1
- package/dist/component-definitions.d.ts +1 -4
- package/dist/component-definitions.d.ts.map +1 -1
- package/dist/component-definitions.js +1 -4
- package/dist/component-definitions.js.map +1 -1
- package/dist/component-recipes.d.ts +76 -83
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +29 -49
- package/dist/component-recipes.js.map +1 -1
- package/dist/component-references.d.ts +0 -15
- package/dist/component-references.d.ts.map +1 -1
- package/dist/component-references.js +0 -3
- package/dist/component-references.js.map +1 -1
- package/dist/data-table.d.ts +3 -3
- package/dist/data-table.js +1 -1
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.d.ts +2 -2
- package/dist/icon-button-recipe.d.ts +2 -2
- package/dist/icon-button-recipe.js +1 -1
- package/dist/icon-button-recipe.js.map +1 -1
- package/dist/image.d.ts +2 -2
- package/dist/image.js +2 -2
- package/dist/image.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/thinking-orb/braid.d.ts +3 -0
- package/dist/internal/thinking-orb/braid.d.ts.map +1 -0
- package/dist/internal/thinking-orb/braid.js +47 -0
- package/dist/internal/thinking-orb/braid.js.map +1 -0
- package/dist/internal/thinking-orb/core.d.ts +60 -0
- package/dist/internal/thinking-orb/core.d.ts.map +1 -0
- package/dist/internal/thinking-orb/core.js +86 -0
- package/dist/internal/thinking-orb/core.js.map +1 -0
- package/dist/internal/thinking-orb/lattice.d.ts +5 -0
- package/dist/internal/thinking-orb/lattice.d.ts.map +1 -0
- package/dist/internal/thinking-orb/lattice.js +187 -0
- package/dist/internal/thinking-orb/lattice.js.map +1 -0
- package/dist/internal/thinking-orb/morph.d.ts +3 -0
- package/dist/internal/thinking-orb/morph.d.ts.map +1 -0
- package/dist/internal/thinking-orb/morph.js +127 -0
- package/dist/internal/thinking-orb/morph.js.map +1 -0
- package/dist/internal/thinking-orb/orbits.d.ts +3 -0
- package/dist/internal/thinking-orb/orbits.d.ts.map +1 -0
- package/dist/internal/thinking-orb/orbits.js +68 -0
- package/dist/internal/thinking-orb/orbits.js.map +1 -0
- package/dist/internal/thinking-orb/presets.d.ts +21 -0
- package/dist/internal/thinking-orb/presets.d.ts.map +1 -0
- package/dist/internal/thinking-orb/presets.js +77 -0
- package/dist/internal/thinking-orb/presets.js.map +1 -0
- package/dist/internal/thinking-orb/profiles.d.ts +8 -0
- package/dist/internal/thinking-orb/profiles.d.ts.map +1 -0
- package/dist/internal/thinking-orb/profiles.js +158 -0
- package/dist/internal/thinking-orb/profiles.js.map +1 -0
- package/dist/internal/thinking-orb/registry.d.ts +9 -0
- package/dist/internal/thinking-orb/registry.d.ts.map +1 -0
- package/dist/internal/thinking-orb/registry.js +27 -0
- package/dist/internal/thinking-orb/registry.js.map +1 -0
- package/dist/internal/thinking-orb/ribbon.d.ts +3 -0
- package/dist/internal/thinking-orb/ribbon.d.ts.map +1 -0
- package/dist/internal/thinking-orb/ribbon.js +87 -0
- package/dist/internal/thinking-orb/ribbon.js.map +1 -0
- package/dist/internal/thinking-orb/types.d.ts +15 -0
- package/dist/internal/thinking-orb/types.d.ts.map +1 -0
- package/dist/internal/thinking-orb/types.js +4 -0
- package/dist/internal/thinking-orb/types.js.map +1 -0
- package/dist/internal/thinking-orb/web.d.ts +3 -0
- package/dist/internal/thinking-orb/web.d.ts.map +1 -0
- package/dist/internal/thinking-orb/web.js +92 -0
- package/dist/internal/thinking-orb/web.js.map +1 -0
- package/dist/masonry.d.ts +17 -0
- package/dist/masonry.d.ts.map +1 -0
- package/dist/masonry.js +18 -0
- package/dist/masonry.js.map +1 -0
- package/dist/menubar.d.ts +3 -3
- package/dist/menubar.js +1 -1
- package/dist/menubar.js.map +1 -1
- package/dist/number-field.d.ts +2 -2
- package/dist/otp-field.d.ts +1 -1
- package/dist/password-field.d.ts +2 -2
- package/dist/popover.d.ts +7 -8
- package/dist/popover.d.ts.map +1 -1
- package/dist/popover.js +2 -0
- package/dist/popover.js.map +1 -1
- package/dist/qr-code-recipe.d.ts +7 -0
- package/dist/qr-code-recipe.d.ts.map +1 -0
- package/dist/qr-code-recipe.js +2 -0
- package/dist/qr-code-recipe.js.map +1 -0
- package/dist/qr-code.d.ts +16 -0
- package/dist/qr-code.d.ts.map +1 -0
- package/dist/qr-code.js +37 -0
- package/dist/qr-code.js.map +1 -0
- package/dist/semantic-colors.d.ts +1 -1
- package/dist/semantic-colors.js +1 -1
- package/dist/semantic-colors.js.map +1 -1
- package/dist/showcase.d.ts +5 -1
- package/dist/showcase.d.ts.map +1 -1
- package/dist/showcase.js +51 -13
- package/dist/showcase.js.map +1 -1
- package/dist/sidebar.d.ts +3 -3
- package/dist/sidebar.js +1 -1
- package/dist/sidebar.js.map +1 -1
- package/dist/tag.d.ts +4 -4
- package/dist/tag.js +3 -3
- package/dist/tag.js.map +1 -1
- package/dist/tags-input.d.ts +3 -3
- package/dist/tags-input.js +1 -1
- package/dist/tags-input.js.map +1 -1
- package/dist/text-formats.d.ts +2 -2
- package/dist/text-formats.js +2 -2
- package/dist/text-formats.js.map +1 -1
- package/dist/thinking-orb-recipe.d.ts +15 -0
- package/dist/thinking-orb-recipe.d.ts.map +1 -0
- package/dist/thinking-orb-recipe.js +9 -0
- package/dist/thinking-orb-recipe.js.map +1 -0
- package/dist/thinking-orb.d.ts +25 -0
- package/dist/thinking-orb.d.ts.map +1 -0
- package/dist/thinking-orb.js +40 -0
- package/dist/thinking-orb.js.map +1 -0
- package/dist/toast-liquid.d.ts +116 -0
- package/dist/toast-liquid.d.ts.map +1 -0
- package/dist/toast-liquid.js +100 -0
- package/dist/toast-liquid.js.map +1 -0
- package/dist/toast.d.ts +7 -1
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +5 -0
- package/dist/toast.js.map +1 -1
- package/dist/toggle-group.d.ts +2 -2
- package/dist/toggle-group.js +3 -3
- package/dist/toggle-group.js.map +1 -1
- package/dist/transfer-list.d.ts +3 -3
- package/dist/transfer-list.js +1 -1
- package/dist/transfer-list.js.map +1 -1
- package/dist/tree.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/virtual-list.d.ts +13 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +13 -0
- package/dist/virtual-list.js.map +1 -0
- package/docs/anchor.md +5 -4
- package/docs/ant-design-coverage.md +2 -2
- package/docs/architecture.md +6 -2
- package/docs/authoring-brief.md +3 -2
- package/docs/bottom-navigation.md +7 -6
- package/docs/breadcrumb.md +5 -2
- package/docs/calendar.md +6 -3
- package/docs/carousel.md +2 -2
- package/docs/cascader.md +6 -0
- package/docs/catalog-cleanup.md +7 -0
- package/docs/catalog-decision-status.md +3 -3
- package/docs/catalog-freeze.json +9 -7
- package/docs/collapsible.md +12 -0
- package/docs/command-palette.md +5 -3
- package/docs/consumer-policy.md +29 -12
- package/docs/context-menu.md +12 -2
- package/docs/data-table.md +11 -6
- package/docs/date-picker.md +6 -4
- package/docs/date-range.md +4 -2
- package/docs/description-list.md +8 -9
- package/docs/dialog.md +39 -0
- package/docs/expansion-roadmap.md +11 -7
- package/docs/file-picker.md +5 -3
- package/docs/form.md +16 -4
- package/docs/generated/component-maturity.md +88 -91
- package/docs/generated/renderer-evidence.json +1848 -1023
- package/docs/generated/renderer-evidence.md +153 -145
- package/docs/generated/showcase-manifest.json +431 -497
- package/docs/layout.md +8 -9
- package/docs/library-gap-analysis.md +1 -1
- package/docs/masonry.md +11 -0
- package/docs/mentions.md +14 -7
- package/docs/optional-adapters.md +106 -0
- package/docs/otp-field.md +2 -1
- package/docs/pagination.md +4 -1
- package/docs/password-field.md +2 -1
- package/docs/popover.md +9 -6
- package/docs/promotion-candidates.md +2 -1
- package/docs/qr-code.md +11 -65
- package/docs/react-native-completion.md +1 -1
- package/docs/result.md +8 -5
- package/docs/screen-chrome.md +2 -1
- package/docs/sheet.md +8 -2
- package/docs/showcase.md +10 -2
- package/docs/side-panel.md +12 -6
- package/docs/sidebar.md +3 -0
- package/docs/splitter.md +6 -6
- package/docs/stable-core.md +72 -0
- package/docs/stable-promotion.md +47 -43
- package/docs/tags-input.md +5 -2
- package/docs/theme-palette.md +27 -0
- package/docs/thinking-orb.md +124 -0
- package/docs/timeline.md +2 -3
- package/docs/toast.md +6 -0
- package/docs/tooltip.md +2 -1
- package/docs/tour.md +14 -8
- package/docs/transfer-list.md +24 -21
- package/docs/tree-select.md +2 -1
- package/docs/tree.md +12 -7
- package/docs/upload-item.md +7 -3
- package/docs/virtual-list.md +10 -67
- package/package.json +30 -3
- package/docs/app-provider.md +0 -50
- package/docs/border-beam.md +0 -66
- package/docs/chart.md +0 -33
- package/docs/utility.md +0 -53
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
|
|
2
|
+
// Orbits: particles on tilted orbits — the "working" state. No nucleus
|
|
3
|
+
// (the tuned preset runs coreless): just ghost paths and the particles
|
|
4
|
+
// doing the work.
|
|
5
|
+
import { finalizeFrame, hashD, makeProj, radiusScale } from './core.js';
|
|
6
|
+
export const frameOrbits = (size, t, o) => {
|
|
7
|
+
const cx = size / 2;
|
|
8
|
+
const cy = size / 2;
|
|
9
|
+
const R = (size / 2) * 0.82;
|
|
10
|
+
const pt = makeProj(t * 0.12, 0.3, cx, cy, 1);
|
|
11
|
+
const rs = radiusScale(size, o.rsPow ?? 0.6);
|
|
12
|
+
const dots = [];
|
|
13
|
+
const orbitN = o.orbitN ?? 12;
|
|
14
|
+
const ghostN = o.ghostN ?? 40;
|
|
15
|
+
const particles = o.particles ?? 3;
|
|
16
|
+
// orbits: each a tilted circle — a ghost path + running particles
|
|
17
|
+
for (let orb = 0; orb < orbitN; orb++) {
|
|
18
|
+
const h1 = hashD(orb, 1.7);
|
|
19
|
+
const h2 = hashD(orb, 5.2);
|
|
20
|
+
const h3 = hashD(orb, 8.9);
|
|
21
|
+
const ro = R * (0.45 + 0.52 * h1);
|
|
22
|
+
const th = h1 * 2 * Math.PI;
|
|
23
|
+
const phi = Math.acos(2 * h2 - 1);
|
|
24
|
+
// orbit plane basis (u, v ⟂ normal n)
|
|
25
|
+
const nx = Math.sin(phi) * Math.cos(th);
|
|
26
|
+
const ny = Math.cos(phi);
|
|
27
|
+
const nz = Math.sin(phi) * Math.sin(th);
|
|
28
|
+
let ux = -ny;
|
|
29
|
+
let uy = nx;
|
|
30
|
+
const uz = 0;
|
|
31
|
+
const ul = Math.max(1e-6, Math.sqrt(ux * ux + uy * uy));
|
|
32
|
+
ux /= ul;
|
|
33
|
+
uy /= ul;
|
|
34
|
+
const vx = ny * uz - nz * uy;
|
|
35
|
+
const vy = nz * ux - nx * uz;
|
|
36
|
+
const vz = nx * uy - ny * ux;
|
|
37
|
+
const speed = (0.25 + 0.55 * h3) * (h3 > 0.5 ? 1 : -1);
|
|
38
|
+
// ghost path
|
|
39
|
+
for (let k = 0; k < ghostN; k++) {
|
|
40
|
+
const a = (k / ghostN) * 2 * Math.PI;
|
|
41
|
+
const [px, py, z] = pt((ux * Math.cos(a) + vx * Math.sin(a)) * ro, (uy * Math.cos(a) + vy * Math.sin(a)) * ro, (uz * Math.cos(a) + vz * Math.sin(a)) * ro);
|
|
42
|
+
const depth = (z / ro + 1) / 2;
|
|
43
|
+
dots.push({
|
|
44
|
+
x: px,
|
|
45
|
+
y: py,
|
|
46
|
+
z,
|
|
47
|
+
r: (o.ghostR ?? 0.9) * rs,
|
|
48
|
+
white: 0.72,
|
|
49
|
+
a: (o.ghostA ?? 0.5) * (0.4 + 0.6 * depth)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// the particles doing the work
|
|
53
|
+
for (let m = 0; m < particles; m++) {
|
|
54
|
+
const a = t * speed + (m / particles) * 2 * Math.PI + h2 * 6;
|
|
55
|
+
const [px, py, z] = pt((ux * Math.cos(a) + vx * Math.sin(a)) * ro, (uy * Math.cos(a) + vy * Math.sin(a)) * ro, (uz * Math.cos(a) + vz * Math.sin(a)) * ro);
|
|
56
|
+
const depth = (z / ro + 1) / 2;
|
|
57
|
+
dots.push({
|
|
58
|
+
x: px,
|
|
59
|
+
y: py,
|
|
60
|
+
z,
|
|
61
|
+
r: ((o.partR ?? 1.2) + (o.partRDepth ?? 1.6) * depth) * rs,
|
|
62
|
+
white: 0.3 - 0.22 * depth
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return finalizeFrame(dots, [], o.rMin);
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=orbits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orbits.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/orbits.ts"],"names":[],"mappings":"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","sourcesContent":["// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Orbits: particles on tilted orbits — the \"working\" state. No nucleus\n// (the tuned preset runs coreless): just ghost paths and the particles\n// doing the work.\n\nimport type { Dot, ModeFrame } from './types.js';\nimport { finalizeFrame, hashD, makeProj, radiusScale } from './core.js';\n\nexport const frameOrbits: ModeFrame = (size, t, o) => {\n const cx = size / 2;\n const cy = size / 2;\n const R = (size / 2) * 0.82;\n const pt = makeProj(t * 0.12, 0.3, cx, cy, 1);\n const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n const dots: Dot[] = [];\n const orbitN = o.orbitN ?? 12;\n const ghostN = o.ghostN ?? 40;\n const particles = o.particles ?? 3;\n\n // orbits: each a tilted circle — a ghost path + running particles\n for (let orb = 0; orb < orbitN; orb++) {\n const h1 = hashD(orb, 1.7);\n const h2 = hashD(orb, 5.2);\n const h3 = hashD(orb, 8.9);\n const ro = R * (0.45 + 0.52 * h1);\n const th = h1 * 2 * Math.PI;\n const phi = Math.acos(2 * h2 - 1);\n // orbit plane basis (u, v ⟂ normal n)\n const nx = Math.sin(phi) * Math.cos(th);\n const ny = Math.cos(phi);\n const nz = Math.sin(phi) * Math.sin(th);\n let ux = -ny;\n let uy = nx;\n const uz = 0;\n const ul = Math.max(1e-6, Math.sqrt(ux * ux + uy * uy));\n ux /= ul;\n uy /= ul;\n const vx = ny * uz - nz * uy;\n const vy = nz * ux - nx * uz;\n const vz = nx * uy - ny * ux;\n const speed = (0.25 + 0.55 * h3) * (h3 > 0.5 ? 1 : -1);\n\n // ghost path\n for (let k = 0; k < ghostN; k++) {\n const a = (k / ghostN) * 2 * Math.PI;\n const [px, py, z] = pt(\n (ux * Math.cos(a) + vx * Math.sin(a)) * ro,\n (uy * Math.cos(a) + vy * Math.sin(a)) * ro,\n (uz * Math.cos(a) + vz * Math.sin(a)) * ro\n );\n const depth = (z / ro + 1) / 2;\n dots.push({\n x: px,\n y: py,\n z,\n r: (o.ghostR ?? 0.9) * rs,\n white: 0.72,\n a: (o.ghostA ?? 0.5) * (0.4 + 0.6 * depth)\n });\n }\n // the particles doing the work\n for (let m = 0; m < particles; m++) {\n const a = t * speed + (m / particles) * 2 * Math.PI + h2 * 6;\n const [px, py, z] = pt(\n (ux * Math.cos(a) + vx * Math.sin(a)) * ro,\n (uy * Math.cos(a) + vy * Math.sin(a)) * ro,\n (uz * Math.cos(a) + vz * Math.sin(a)) * ro\n );\n const depth = (z / ro + 1) / 2;\n dots.push({\n x: px,\n y: py,\n z,\n r: ((o.partR ?? 1.2) + (o.partRDepth ?? 1.6) * depth) * rs,\n white: 0.3 - 0.22 * depth\n });\n }\n }\n return finalizeFrame(dots, [], o.rMin);\n};\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ModeOpts } from './profiles.js';
|
|
2
|
+
import type { OrbSize, OrbState } from './types.js';
|
|
3
|
+
export type ModeKey = 'orbits' | 'globe' | 'rubik' | 'wave' | 'web' | 'braid' | 'ribbon' | 'ring' | 'morph';
|
|
4
|
+
export declare const STATE_TO_MODE: Record<OrbState, ModeKey>;
|
|
5
|
+
export interface Preset {
|
|
6
|
+
speed: number;
|
|
7
|
+
count: number;
|
|
8
|
+
size: number;
|
|
9
|
+
/** Extra mode opts merged verbatim after scaling. */
|
|
10
|
+
extra?: ModeOpts;
|
|
11
|
+
}
|
|
12
|
+
/** Exported so `scripts/extract-spec.ts` can emit them for the native ports. */
|
|
13
|
+
export declare const PRESETS: Record<ModeKey, Record<OrbSize, Preset>>;
|
|
14
|
+
export interface Resolved {
|
|
15
|
+
mode: ModeKey;
|
|
16
|
+
speed: number;
|
|
17
|
+
opts: ModeOpts;
|
|
18
|
+
}
|
|
19
|
+
/** Resolve a (state, size) pair to its mode + fully-scaled draw options. */
|
|
20
|
+
export declare function resolvePreset(state: OrbState, size: OrbSize): Resolved;
|
|
21
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/presets.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,OAAO,GACf,QAAQ,GACR,OAAO,GACP,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,CAAC;AAEZ,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAUnD,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,gFAAgF;AAChF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAqC5D,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;CAChB;AAID,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,CAetE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Upstream tuning retained for visual fidelity; see THIRD_PARTY_NOTICES.md.
|
|
2
|
+
// The shipped tunings: nine states × two sizes, baked from the inkform
|
|
3
|
+
// mini-page tuning session. `count`/`size` are multipliers over the base
|
|
4
|
+
// fine profiles; `speed` multiplies the shared clock. Resolved once per
|
|
5
|
+
// (state, size) pair and cached — the render loop sees plain numbers.
|
|
6
|
+
import { BASE_PROFILES, scaleCounts, scaleRadii } from './profiles.js';
|
|
7
|
+
export const STATE_TO_MODE = {
|
|
8
|
+
working: 'orbits',
|
|
9
|
+
searching: 'globe',
|
|
10
|
+
solving: 'rubik',
|
|
11
|
+
listening: 'wave',
|
|
12
|
+
connecting: 'web',
|
|
13
|
+
weaving: 'braid',
|
|
14
|
+
composing: 'ribbon',
|
|
15
|
+
breathing: 'ring',
|
|
16
|
+
shaping: 'morph'
|
|
17
|
+
};
|
|
18
|
+
/** Exported so `scripts/extract-spec.ts` can emit them for the native ports. */
|
|
19
|
+
export const PRESETS = {
|
|
20
|
+
orbits: {
|
|
21
|
+
64: { speed: 1.885, count: 1, size: 1 },
|
|
22
|
+
20: { speed: 3.9, count: 0.238, size: 2.4 }
|
|
23
|
+
},
|
|
24
|
+
globe: {
|
|
25
|
+
64: { speed: 2.015, count: 0.42, size: 1.15, extra: { scanMul: 4.08, dimBase: 0.45 } },
|
|
26
|
+
20: { speed: 2.665, count: 0.105, size: 1.75, extra: { scanMul: 4.335, dimBase: 0.45 } }
|
|
27
|
+
},
|
|
28
|
+
rubik: {
|
|
29
|
+
64: { speed: 1.82, count: 0.35, size: 1.05 },
|
|
30
|
+
20: { speed: 1.95, count: 0.088, size: 1.9 }
|
|
31
|
+
},
|
|
32
|
+
wave: {
|
|
33
|
+
64: { speed: 4.388, count: 0.341, size: 1 },
|
|
34
|
+
20: { speed: 3.998, count: 0.105, size: 1.6 }
|
|
35
|
+
},
|
|
36
|
+
web: {
|
|
37
|
+
64: { speed: 3.315, count: 1.35, size: 0.95 },
|
|
38
|
+
20: { speed: 6.63, count: 0.25, size: 1.52 }
|
|
39
|
+
},
|
|
40
|
+
braid: {
|
|
41
|
+
64: { speed: 1.625, count: 0.5, size: 1 },
|
|
42
|
+
20: { speed: 2.75, count: 0.1125, size: 1.36 }
|
|
43
|
+
},
|
|
44
|
+
ribbon: {
|
|
45
|
+
64: { speed: 2.34, count: 0.25, size: 0.85, extra: { spin: 0, bandMul: 3.9, wobMul: 1 } },
|
|
46
|
+
20: { speed: 3.12, count: 0.051, size: 1.073, extra: { spin: 0, bandMul: 4.94, wobMul: 1 } }
|
|
47
|
+
},
|
|
48
|
+
ring: {
|
|
49
|
+
64: { speed: 3.24, count: 0.25, size: 0.956, extra: { spin: 0, bandMul: 3.627, wobMul: 0.368 } },
|
|
50
|
+
20: { speed: 3.78, count: 0.028, size: 1.622, extra: { spin: 0, bandMul: 3.968, wobMul: 0.565 } }
|
|
51
|
+
},
|
|
52
|
+
morph: {
|
|
53
|
+
64: { speed: 2.405, count: 0.702, size: 0.395, extra: { spread: 1.45 } },
|
|
54
|
+
20: { speed: 2.08, count: 0.53, size: 1.011, extra: { spread: 1.45 } }
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const cache = new Map();
|
|
58
|
+
/** Resolve a (state, size) pair to its mode + fully-scaled draw options. */
|
|
59
|
+
export function resolvePreset(state, size) {
|
|
60
|
+
const key = `${state}-${size}`;
|
|
61
|
+
const hit = cache.get(key);
|
|
62
|
+
if (hit)
|
|
63
|
+
return hit;
|
|
64
|
+
const mode = STATE_TO_MODE[state];
|
|
65
|
+
const preset = PRESETS[mode][size];
|
|
66
|
+
let opts = { ...BASE_PROFILES[mode] };
|
|
67
|
+
if (preset.count !== 1)
|
|
68
|
+
opts = scaleCounts(opts, preset.count);
|
|
69
|
+
if (preset.size !== 1)
|
|
70
|
+
opts = scaleRadii(opts, preset.size);
|
|
71
|
+
if (preset.extra)
|
|
72
|
+
opts = { ...opts, ...preset.extra };
|
|
73
|
+
const resolved = { mode, speed: preset.speed, opts };
|
|
74
|
+
cache.set(key, resolved);
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/presets.ts"],"names":[],"mappings":"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","sourcesContent":["// Upstream tuning retained for visual fidelity; see THIRD_PARTY_NOTICES.md.\n// The shipped tunings: nine states × two sizes, baked from the inkform\n// mini-page tuning session. `count`/`size` are multipliers over the base\n// fine profiles; `speed` multiplies the shared clock. Resolved once per\n// (state, size) pair and cached — the render loop sees plain numbers.\n\nimport type { ModeOpts } from './profiles.js';\nimport { BASE_PROFILES, scaleCounts, scaleRadii } from './profiles.js';\nimport type { OrbSize, OrbState } from './types.js';\n\nexport type ModeKey =\n | 'orbits'\n | 'globe'\n | 'rubik'\n | 'wave'\n | 'web'\n | 'braid'\n | 'ribbon'\n | 'ring'\n | 'morph';\n\nexport const STATE_TO_MODE: Record<OrbState, ModeKey> = {\n working: 'orbits',\n searching: 'globe',\n solving: 'rubik',\n listening: 'wave',\n connecting: 'web',\n weaving: 'braid',\n composing: 'ribbon',\n breathing: 'ring',\n shaping: 'morph'\n};\n\nexport interface Preset {\n speed: number;\n count: number;\n size: number;\n /** Extra mode opts merged verbatim after scaling. */\n extra?: ModeOpts;\n}\n\n/** Exported so `scripts/extract-spec.ts` can emit them for the native ports. */\nexport const PRESETS: Record<ModeKey, Record<OrbSize, Preset>> = {\n orbits: {\n 64: { speed: 1.885, count: 1, size: 1 },\n 20: { speed: 3.9, count: 0.238, size: 2.4 }\n },\n globe: {\n 64: { speed: 2.015, count: 0.42, size: 1.15, extra: { scanMul: 4.08, dimBase: 0.45 } },\n 20: { speed: 2.665, count: 0.105, size: 1.75, extra: { scanMul: 4.335, dimBase: 0.45 } }\n },\n rubik: {\n 64: { speed: 1.82, count: 0.35, size: 1.05 },\n 20: { speed: 1.95, count: 0.088, size: 1.9 }\n },\n wave: {\n 64: { speed: 4.388, count: 0.341, size: 1 },\n 20: { speed: 3.998, count: 0.105, size: 1.6 }\n },\n web: {\n 64: { speed: 3.315, count: 1.35, size: 0.95 },\n 20: { speed: 6.63, count: 0.25, size: 1.52 }\n },\n braid: {\n 64: { speed: 1.625, count: 0.5, size: 1 },\n 20: { speed: 2.75, count: 0.1125, size: 1.36 }\n },\n ribbon: {\n 64: { speed: 2.34, count: 0.25, size: 0.85, extra: { spin: 0, bandMul: 3.9, wobMul: 1 } },\n 20: { speed: 3.12, count: 0.051, size: 1.073, extra: { spin: 0, bandMul: 4.94, wobMul: 1 } }\n },\n ring: {\n 64: { speed: 3.24, count: 0.25, size: 0.956, extra: { spin: 0, bandMul: 3.627, wobMul: 0.368 } },\n 20: { speed: 3.78, count: 0.028, size: 1.622, extra: { spin: 0, bandMul: 3.968, wobMul: 0.565 } }\n },\n morph: {\n 64: { speed: 2.405, count: 0.702, size: 0.395, extra: { spread: 1.45 } },\n 20: { speed: 2.08, count: 0.53, size: 1.011, extra: { spread: 1.45 } }\n }\n};\n\nexport interface Resolved {\n mode: ModeKey;\n speed: number;\n opts: ModeOpts;\n}\n\nconst cache = new Map<string, Resolved>();\n\n/** Resolve a (state, size) pair to its mode + fully-scaled draw options. */\nexport function resolvePreset(state: OrbState, size: OrbSize): Resolved {\n const key = `${state}-${size}`;\n const hit = cache.get(key);\n if (hit) return hit;\n\n const mode = STATE_TO_MODE[state];\n const preset = PRESETS[mode][size];\n let opts: ModeOpts = { ...BASE_PROFILES[mode] };\n if (preset.count !== 1) opts = scaleCounts(opts, preset.count);\n if (preset.size !== 1) opts = scaleRadii(opts, preset.size);\n if (preset.extra) opts = { ...opts, ...preset.extra };\n\n const resolved: Resolved = { mode, speed: preset.speed, opts };\n cache.set(key, resolved);\n return resolved;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ModeOpts {
|
|
2
|
+
[key: string]: number | undefined;
|
|
3
|
+
}
|
|
4
|
+
export declare function scaleCounts(opts: ModeOpts, scale: number): ModeOpts;
|
|
5
|
+
export declare function scaleRadii(opts: ModeOpts, scale: number): ModeOpts;
|
|
6
|
+
/** Base (fine) profiles per mode, before preset multipliers. */
|
|
7
|
+
export declare const BASE_PROFILES: Record<string, ModeOpts>;
|
|
8
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/profiles.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AA2BD,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAyBnE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAUlE;AAED,gEAAgE;AAChE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAwFlD,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
|
|
2
|
+
// Density profiles + the multiplier machinery that scales them. The base
|
|
3
|
+
// rows are inkform's `fine` profiles; each shipped preset (state × size)
|
|
4
|
+
// applies count / radius multipliers on top, resolved once per mount.
|
|
5
|
+
// 2-D lattices (rings × dots-per-ring) come in pairs — each side takes
|
|
6
|
+
// √scale so the TOTAL dot count scales by `scale`; flat lists scale
|
|
7
|
+
// linearly. `iconD` sets the morph outline's sampling density.
|
|
8
|
+
const COUNT_PAIRS = [
|
|
9
|
+
['latRings', 'lonDensity'],
|
|
10
|
+
['rings', 'lonDensity'],
|
|
11
|
+
['lanes', 'segs']
|
|
12
|
+
];
|
|
13
|
+
const COUNT_KEYS = ['orbitN', 'ghostN', 'nodeN', 'strandN', 'signals'];
|
|
14
|
+
const ICON_DENSITY_KEYS = ['iconD'];
|
|
15
|
+
// Every key that sets a dot's rendered radius — scaling all of them keeps
|
|
16
|
+
// a dot's near/far falloff intact while shrinking or growing the mark.
|
|
17
|
+
const RADIUS_KEYS = [
|
|
18
|
+
'rBase',
|
|
19
|
+
'rDepth',
|
|
20
|
+
'rActive',
|
|
21
|
+
'rDot',
|
|
22
|
+
'ghostR',
|
|
23
|
+
'partR',
|
|
24
|
+
'partRDepth',
|
|
25
|
+
'nodeR',
|
|
26
|
+
'nodeRDepth'
|
|
27
|
+
];
|
|
28
|
+
export function scaleCounts(opts, scale) {
|
|
29
|
+
const out = { ...opts };
|
|
30
|
+
const done = new Set();
|
|
31
|
+
const rt = Math.sqrt(scale);
|
|
32
|
+
for (const [a, b] of COUNT_PAIRS) {
|
|
33
|
+
const va = out[a];
|
|
34
|
+
const vb = out[b];
|
|
35
|
+
if (va != null && vb != null && !done.has(a) && !done.has(b)) {
|
|
36
|
+
out[a] = Math.max(2, Math.round(va * rt));
|
|
37
|
+
out[b] = Math.max(2, Math.round(vb * rt));
|
|
38
|
+
done.add(a);
|
|
39
|
+
done.add(b);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
for (const k of COUNT_KEYS) {
|
|
43
|
+
const v = out[k];
|
|
44
|
+
// 0 means the mode opted out of that layer entirely (ring has no ghost
|
|
45
|
+
// sphere) — scaling must not resurrect it as a single stray dot
|
|
46
|
+
if (v != null && v !== 0 && !done.has(k))
|
|
47
|
+
out[k] = Math.max(1, Math.round(v * scale));
|
|
48
|
+
}
|
|
49
|
+
for (const k of ICON_DENSITY_KEYS) {
|
|
50
|
+
const v = out[k];
|
|
51
|
+
if (v != null)
|
|
52
|
+
out[k] = Math.max(0.02, v * scale);
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
export function scaleRadii(opts, scale) {
|
|
57
|
+
const out = { ...opts };
|
|
58
|
+
for (const k of RADIUS_KEYS) {
|
|
59
|
+
const v = out[k];
|
|
60
|
+
if (v != null)
|
|
61
|
+
out[k] = v * scale;
|
|
62
|
+
}
|
|
63
|
+
// remember the multiplier itself — spacing-derived radii (the morph
|
|
64
|
+
// outline) use it, since they aren't based on any single radius key
|
|
65
|
+
out.rSizeMul = (out.rSizeMul ?? 1) * scale;
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/** Base (fine) profiles per mode, before preset multipliers. */
|
|
69
|
+
export const BASE_PROFILES = {
|
|
70
|
+
globe: {
|
|
71
|
+
latRings: 17,
|
|
72
|
+
lonDensity: 44,
|
|
73
|
+
rBase: 0.6,
|
|
74
|
+
rDepth: 1.7,
|
|
75
|
+
rBoost: 1.0,
|
|
76
|
+
inkFar: 0.62,
|
|
77
|
+
inkSpan: 0.54,
|
|
78
|
+
rsPow: 0.6,
|
|
79
|
+
rMin: 0.3
|
|
80
|
+
},
|
|
81
|
+
orbits: {
|
|
82
|
+
orbitN: 12,
|
|
83
|
+
ghostN: 40,
|
|
84
|
+
ghostR: 0.9,
|
|
85
|
+
ghostA: 0.5,
|
|
86
|
+
particles: 3,
|
|
87
|
+
partR: 1.2,
|
|
88
|
+
partRDepth: 1.6,
|
|
89
|
+
rsPow: 0.6,
|
|
90
|
+
rMin: 0.3
|
|
91
|
+
},
|
|
92
|
+
rubik: {
|
|
93
|
+
latRings: 15,
|
|
94
|
+
lonDensity: 40,
|
|
95
|
+
moveCount: 14,
|
|
96
|
+
rBase: 0.6,
|
|
97
|
+
rDepth: 1.7,
|
|
98
|
+
rActive: 0.3,
|
|
99
|
+
inkFar: 0.62,
|
|
100
|
+
inkSpan: 0.54,
|
|
101
|
+
rsPow: 0.6,
|
|
102
|
+
rMin: 0.3
|
|
103
|
+
},
|
|
104
|
+
wave: {
|
|
105
|
+
rings: 15,
|
|
106
|
+
lonDensity: 40,
|
|
107
|
+
rBase: 0.6,
|
|
108
|
+
rDepth: 1.7,
|
|
109
|
+
rsPow: 0.6,
|
|
110
|
+
rMin: 0.3
|
|
111
|
+
},
|
|
112
|
+
web: {
|
|
113
|
+
nodeN: 30,
|
|
114
|
+
thr: 0.72,
|
|
115
|
+
signals: 5,
|
|
116
|
+
nodeR: 1.4,
|
|
117
|
+
nodeRDepth: 1.8,
|
|
118
|
+
lineW: 0.8,
|
|
119
|
+
rsPow: 0.6,
|
|
120
|
+
rMin: 0.3
|
|
121
|
+
},
|
|
122
|
+
braid: {
|
|
123
|
+
strandN: 52,
|
|
124
|
+
turns: 3.0,
|
|
125
|
+
ghostN: 150,
|
|
126
|
+
rBase: 1.2,
|
|
127
|
+
rDepth: 1.8,
|
|
128
|
+
rsPow: 0.6,
|
|
129
|
+
rMin: 0.3
|
|
130
|
+
},
|
|
131
|
+
ribbon: {
|
|
132
|
+
lanes: 5,
|
|
133
|
+
segs: 88,
|
|
134
|
+
ghostN: 150,
|
|
135
|
+
rBase: 1.1,
|
|
136
|
+
rDepth: 1.7,
|
|
137
|
+
rsPow: 0.6,
|
|
138
|
+
rMin: 0.3
|
|
139
|
+
},
|
|
140
|
+
// ring shares ribbon's painter; faceOn cancels the camera tilt and moves
|
|
141
|
+
// the undulation onto the radius, and there is no ghost sphere behind it
|
|
142
|
+
ring: {
|
|
143
|
+
lanes: 5,
|
|
144
|
+
segs: 88,
|
|
145
|
+
ghostN: 0,
|
|
146
|
+
faceOn: 1,
|
|
147
|
+
rBase: 1.1,
|
|
148
|
+
rDepth: 1.7,
|
|
149
|
+
rsPow: 0.6,
|
|
150
|
+
rMin: 0.3
|
|
151
|
+
},
|
|
152
|
+
morph: {
|
|
153
|
+
rDot: 0.021,
|
|
154
|
+
iconD: 1,
|
|
155
|
+
rMin: 0.25
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/profiles.ts"],"names":[],"mappings":"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","sourcesContent":["// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Density profiles + the multiplier machinery that scales them. The base\n// rows are inkform's `fine` profiles; each shipped preset (state × size)\n// applies count / radius multipliers on top, resolved once per mount.\n\nexport interface ModeOpts {\n [key: string]: number | undefined;\n}\n\n// 2-D lattices (rings × dots-per-ring) come in pairs — each side takes\n// √scale so the TOTAL dot count scales by `scale`; flat lists scale\n// linearly. `iconD` sets the morph outline's sampling density.\nconst COUNT_PAIRS: ReadonlyArray<readonly [string, string]> = [\n ['latRings', 'lonDensity'],\n ['rings', 'lonDensity'],\n ['lanes', 'segs']\n];\nconst COUNT_KEYS = ['orbitN', 'ghostN', 'nodeN', 'strandN', 'signals'] as const;\nconst ICON_DENSITY_KEYS = ['iconD'] as const;\n\n// Every key that sets a dot's rendered radius — scaling all of them keeps\n// a dot's near/far falloff intact while shrinking or growing the mark.\nconst RADIUS_KEYS = [\n 'rBase',\n 'rDepth',\n 'rActive',\n 'rDot',\n 'ghostR',\n 'partR',\n 'partRDepth',\n 'nodeR',\n 'nodeRDepth'\n] as const;\n\nexport function scaleCounts(opts: ModeOpts, scale: number): ModeOpts {\n const out: ModeOpts = { ...opts };\n const done = new Set<string>();\n const rt = Math.sqrt(scale);\n for (const [a, b] of COUNT_PAIRS) {\n const va = out[a];\n const vb = out[b];\n if (va != null && vb != null && !done.has(a) && !done.has(b)) {\n out[a] = Math.max(2, Math.round(va * rt));\n out[b] = Math.max(2, Math.round(vb * rt));\n done.add(a);\n done.add(b);\n }\n }\n for (const k of COUNT_KEYS) {\n const v = out[k];\n // 0 means the mode opted out of that layer entirely (ring has no ghost\n // sphere) — scaling must not resurrect it as a single stray dot\n if (v != null && v !== 0 && !done.has(k)) out[k] = Math.max(1, Math.round(v * scale));\n }\n for (const k of ICON_DENSITY_KEYS) {\n const v = out[k];\n if (v != null) out[k] = Math.max(0.02, v * scale);\n }\n return out;\n}\n\nexport function scaleRadii(opts: ModeOpts, scale: number): ModeOpts {\n const out: ModeOpts = { ...opts };\n for (const k of RADIUS_KEYS) {\n const v = out[k];\n if (v != null) out[k] = v * scale;\n }\n // remember the multiplier itself — spacing-derived radii (the morph\n // outline) use it, since they aren't based on any single radius key\n out.rSizeMul = (out.rSizeMul ?? 1) * scale;\n return out;\n}\n\n/** Base (fine) profiles per mode, before preset multipliers. */\nexport const BASE_PROFILES: Record<string, ModeOpts> = {\n globe: {\n latRings: 17,\n lonDensity: 44,\n rBase: 0.6,\n rDepth: 1.7,\n rBoost: 1.0,\n inkFar: 0.62,\n inkSpan: 0.54,\n rsPow: 0.6,\n rMin: 0.3\n },\n orbits: {\n orbitN: 12,\n ghostN: 40,\n ghostR: 0.9,\n ghostA: 0.5,\n particles: 3,\n partR: 1.2,\n partRDepth: 1.6,\n rsPow: 0.6,\n rMin: 0.3\n },\n rubik: {\n latRings: 15,\n lonDensity: 40,\n moveCount: 14,\n rBase: 0.6,\n rDepth: 1.7,\n rActive: 0.3,\n inkFar: 0.62,\n inkSpan: 0.54,\n rsPow: 0.6,\n rMin: 0.3\n },\n wave: {\n rings: 15,\n lonDensity: 40,\n rBase: 0.6,\n rDepth: 1.7,\n rsPow: 0.6,\n rMin: 0.3\n },\n web: {\n nodeN: 30,\n thr: 0.72,\n signals: 5,\n nodeR: 1.4,\n nodeRDepth: 1.8,\n lineW: 0.8,\n rsPow: 0.6,\n rMin: 0.3\n },\n braid: {\n strandN: 52,\n turns: 3.0,\n ghostN: 150,\n rBase: 1.2,\n rDepth: 1.8,\n rsPow: 0.6,\n rMin: 0.3\n },\n ribbon: {\n lanes: 5,\n segs: 88,\n ghostN: 150,\n rBase: 1.1,\n rDepth: 1.7,\n rsPow: 0.6,\n rMin: 0.3\n },\n // ring shares ribbon's painter; faceOn cancels the camera tilt and moves\n // the undulation onto the radius, and there is no ghost sphere behind it\n ring: {\n lanes: 5,\n segs: 88,\n ghostN: 0,\n faceOn: 1,\n rBase: 1.1,\n rDepth: 1.7,\n rsPow: 0.6,\n rMin: 0.3\n },\n morph: {\n rDot: 0.021,\n iconD: 1,\n rMin: 0.25\n }\n};\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModeKey } from './presets.js';
|
|
2
|
+
import type { ModeFrame } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The portable surface: pure geometry, no canvas. The React Native port
|
|
5
|
+
* imports exactly these functions, so its output is identical to the web's
|
|
6
|
+
* by construction rather than by re-implementation.
|
|
7
|
+
*/
|
|
8
|
+
export declare const MODE_FRAMES: Record<ModeKey, ModeFrame>;
|
|
9
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAWlD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
|
|
2
|
+
// Mode key → geometry builder. Kept separate from the presets so tree
|
|
3
|
+
// shaking can in principle drop unused modes in custom builds.
|
|
4
|
+
import { frameBraid } from './braid.js';
|
|
5
|
+
import { frameGlobe, frameRubik, frameWave } from './lattice.js';
|
|
6
|
+
import { frameMorph } from './morph.js';
|
|
7
|
+
import { frameOrbits } from './orbits.js';
|
|
8
|
+
import { frameRibbon } from './ribbon.js';
|
|
9
|
+
import { frameWeb } from './web.js';
|
|
10
|
+
/**
|
|
11
|
+
* The portable surface: pure geometry, no canvas. The React Native port
|
|
12
|
+
* imports exactly these functions, so its output is identical to the web's
|
|
13
|
+
* by construction rather than by re-implementation.
|
|
14
|
+
*/
|
|
15
|
+
export const MODE_FRAMES = {
|
|
16
|
+
orbits: frameOrbits,
|
|
17
|
+
globe: frameGlobe,
|
|
18
|
+
rubik: frameRubik,
|
|
19
|
+
wave: frameWave,
|
|
20
|
+
web: frameWeb,
|
|
21
|
+
braid: frameBraid,
|
|
22
|
+
ribbon: frameRibbon,
|
|
23
|
+
// ring shares ribbon's geometry — the `faceOn` profile flag switches it
|
|
24
|
+
ring: frameRibbon,
|
|
25
|
+
morph: frameMorph
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/registry.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,sEAAsE;AACtE,+DAA+D;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAA+B;IACrD,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,QAAQ;IACb,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,WAAW;IACnB,wEAAwE;IACxE,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,UAAU;CAClB,CAAC","sourcesContent":["// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Mode key → geometry builder. Kept separate from the presets so tree\n// shaking can in principle drop unused modes in custom builds.\n\nimport type { ModeKey } from './presets.js';\nimport type { ModeFrame } from './types.js';\nimport { frameBraid } from './braid.js';\nimport { frameGlobe, frameRubik, frameWave } from './lattice.js';\nimport { frameMorph } from './morph.js';\nimport { frameOrbits } from './orbits.js';\nimport { frameRibbon } from './ribbon.js';\nimport { frameWeb } from './web.js';\n\n/**\n * The portable surface: pure geometry, no canvas. The React Native port\n * imports exactly these functions, so its output is identical to the web's\n * by construction rather than by re-implementation.\n */\nexport const MODE_FRAMES: Record<ModeKey, ModeFrame> = {\n orbits: frameOrbits,\n globe: frameGlobe,\n rubik: frameRubik,\n wave: frameWave,\n web: frameWeb,\n braid: frameBraid,\n ribbon: frameRibbon,\n // ring shares ribbon's geometry — the `faceOn` profile flag switches it\n ring: frameRibbon,\n morph: frameMorph\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ribbon.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/ribbon.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAO,SAAS,EAAE,MAAM,YAAY,CAAC;AAGjD,eAAO,MAAM,WAAW,EAAE,SAiFzB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
|
|
2
|
+
// Ribbon: an undulating sash of parallel strands rides a great circle —
|
|
3
|
+
// the "composing" state. The tuned preset freezes the 3D tumble
|
|
4
|
+
// (spin 0), leaving the traveling undulation on a fixed band.
|
|
5
|
+
//
|
|
6
|
+
// The same painter also drives "breathing" (ring), via the `faceOn` flag:
|
|
7
|
+
// a face-on circle whose radius — not its out-of-plane offset — undulates,
|
|
8
|
+
// so it reads as a ring slowly morphing rather than a sash in orbit.
|
|
9
|
+
import { fibDir, finalizeFrame, makeProj, radiusScale } from './core.js';
|
|
10
|
+
export const frameRibbon = (size, t, o) => {
|
|
11
|
+
const cx = size / 2;
|
|
12
|
+
const cy = size / 2;
|
|
13
|
+
const R = (size / 2) * 0.78;
|
|
14
|
+
// spin scales the 3D tumble; spin=0 freezes the band's orientation,
|
|
15
|
+
// leaving only the traveling undulation
|
|
16
|
+
const spin = o.spin ?? 1;
|
|
17
|
+
const camTilt = 0.3;
|
|
18
|
+
const pt = makeProj(t * 0.1 * spin, camTilt, cx, cy, 1);
|
|
19
|
+
const rs = radiusScale(size, o.rsPow ?? 0.6);
|
|
20
|
+
const dots = [];
|
|
21
|
+
const ghostN = o.ghostN ?? 150;
|
|
22
|
+
for (let i = 0; i < ghostN; i++) {
|
|
23
|
+
const d = fibDir(i, ghostN);
|
|
24
|
+
const [px, py, z] = pt(d[0] * R, d[1] * R, d[2] * R);
|
|
25
|
+
const depth = (z / R + 1) / 2;
|
|
26
|
+
dots.push({ x: px, y: py, z, r: 0.8 * rs, white: 0.78, a: 0.1 + 0.22 * depth });
|
|
27
|
+
}
|
|
28
|
+
// The band plane, precessing (frozen when spin=0). The projection squashes
|
|
29
|
+
// the band's great circle vertically by cos(ta + camTilt); face-on sets
|
|
30
|
+
// ta = -camTilt so that term is 1 and the band reads as a true circle
|
|
31
|
+
// rather than ribbon's tilted ellipse.
|
|
32
|
+
const ya = t * 0.24 * spin;
|
|
33
|
+
const ta = o.faceOn ? -camTilt : 0.55 + 0.3 * Math.sin(t * 0.18) * spin;
|
|
34
|
+
const ux = Math.cos(ya);
|
|
35
|
+
const uy = 0;
|
|
36
|
+
const uz = Math.sin(ya);
|
|
37
|
+
const vx = -uz * Math.sin(ta);
|
|
38
|
+
const vy = Math.cos(ta);
|
|
39
|
+
const vz = ux * Math.sin(ta);
|
|
40
|
+
// plane normal n = u × v
|
|
41
|
+
const nx = uy * vz - uz * vy;
|
|
42
|
+
const ny = uz * vx - ux * vz;
|
|
43
|
+
const nz = ux * vy - uy * vx;
|
|
44
|
+
// Radial lobes swell past R, so pull the base radius in by (most of) the
|
|
45
|
+
// wobble amplitude. The silhouette then stays inside the frame however far
|
|
46
|
+
// the deformation is pushed, while lobes keep getting deeper relative to
|
|
47
|
+
// the mean radius.
|
|
48
|
+
const wobAmp = 0.23 * (o.wobMul ?? 1);
|
|
49
|
+
const baseR = o.faceOn ? R / (1 + 0.85 * wobAmp) : R;
|
|
50
|
+
const baseLanes = o.lanes ?? 5;
|
|
51
|
+
const segs = o.segs ?? 88;
|
|
52
|
+
const lanes = Math.max(1, Math.round(baseLanes * (o.bandMul ?? 1)));
|
|
53
|
+
for (let w = 0; w < lanes; w++) {
|
|
54
|
+
const laneOff = (w - (lanes - 1) / 2) * 0.075;
|
|
55
|
+
const edge = Math.abs(w - (lanes - 1) / 2) / Math.max(1, (lanes - 1) / 2);
|
|
56
|
+
for (let k = 0; k < segs; k++) {
|
|
57
|
+
const a = (k / segs) * 2 * Math.PI;
|
|
58
|
+
// the undulation: two traveling waves along the band; wobMul
|
|
59
|
+
// scales the deformation — 0 is a clean band
|
|
60
|
+
const wob = (0.16 * Math.sin(a * 3 - t * 1.7 + w * 0.22) + 0.07 * Math.sin(a * 5 + t * 1.1)) * (o.wobMul ?? 1);
|
|
61
|
+
// A normal-direction wobble is cancelled by the re-normalisation below:
|
|
62
|
+
// the point lands back on the sphere, so the silhouette is pinned at R
|
|
63
|
+
// and the deformation can only ever pull dots inward. Face-on instead
|
|
64
|
+
// modulates the in-plane RADIUS, so lobes genuinely swell outward and
|
|
65
|
+
// pinch inward. Ribbon keeps the original out-of-plane sash wobble.
|
|
66
|
+
const radial = o.faceOn ? 1 + wob : 1;
|
|
67
|
+
const off = o.faceOn ? laneOff : laneOff + wob;
|
|
68
|
+
const x = ux * Math.cos(a) + vx * Math.sin(a) + nx * off;
|
|
69
|
+
const y = uy * Math.cos(a) + vy * Math.sin(a) + ny * off;
|
|
70
|
+
const z = uz * Math.cos(a) + vz * Math.sin(a) + nz * off;
|
|
71
|
+
const l = Math.sqrt(x * x + y * y + z * z);
|
|
72
|
+
const rr = baseR * radial;
|
|
73
|
+
const [px, py, zr] = pt((x / l) * rr, (y / l) * rr, (z / l) * rr);
|
|
74
|
+
const depth = (zr / R + 1) / 2;
|
|
75
|
+
dots.push({
|
|
76
|
+
x: px,
|
|
77
|
+
y: py,
|
|
78
|
+
z: zr,
|
|
79
|
+
r: ((o.rBase ?? 1.1) + (o.rDepth ?? 1.7) * depth) * (1 - 0.25 * edge) * rs,
|
|
80
|
+
white: 0.52 - 0.44 * depth + 0.18 * edge,
|
|
81
|
+
a: 0.4 + 0.6 * depth
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return finalizeFrame(dots, [], o.rMin);
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=ribbon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ribbon.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/ribbon.ts"],"names":[],"mappings":"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","sourcesContent":["// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Ribbon: an undulating sash of parallel strands rides a great circle —\n// the \"composing\" state. The tuned preset freezes the 3D tumble\n// (spin 0), leaving the traveling undulation on a fixed band.\n//\n// The same painter also drives \"breathing\" (ring), via the `faceOn` flag:\n// a face-on circle whose radius — not its out-of-plane offset — undulates,\n// so it reads as a ring slowly morphing rather than a sash in orbit.\n\nimport type { Dot, ModeFrame } from './types.js';\nimport { fibDir, finalizeFrame, makeProj, radiusScale } from './core.js';\n\nexport const frameRibbon: ModeFrame = (size, t, o) => {\n const cx = size / 2;\n const cy = size / 2;\n const R = (size / 2) * 0.78;\n // spin scales the 3D tumble; spin=0 freezes the band's orientation,\n // leaving only the traveling undulation\n const spin = o.spin ?? 1;\n const camTilt = 0.3;\n const pt = makeProj(t * 0.1 * spin, camTilt, cx, cy, 1);\n const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n const dots: Dot[] = [];\n const ghostN = o.ghostN ?? 150;\n for (let i = 0; i < ghostN; i++) {\n const d = fibDir(i, ghostN);\n const [px, py, z] = pt(d[0] * R, d[1] * R, d[2] * R);\n const depth = (z / R + 1) / 2;\n dots.push({ x: px, y: py, z, r: 0.8 * rs, white: 0.78, a: 0.1 + 0.22 * depth });\n }\n\n // The band plane, precessing (frozen when spin=0). The projection squashes\n // the band's great circle vertically by cos(ta + camTilt); face-on sets\n // ta = -camTilt so that term is 1 and the band reads as a true circle\n // rather than ribbon's tilted ellipse.\n const ya = t * 0.24 * spin;\n const ta = o.faceOn ? -camTilt : 0.55 + 0.3 * Math.sin(t * 0.18) * spin;\n const ux = Math.cos(ya);\n const uy = 0;\n const uz = Math.sin(ya);\n const vx = -uz * Math.sin(ta);\n const vy = Math.cos(ta);\n const vz = ux * Math.sin(ta);\n // plane normal n = u × v\n const nx = uy * vz - uz * vy;\n const ny = uz * vx - ux * vz;\n const nz = ux * vy - uy * vx;\n\n // Radial lobes swell past R, so pull the base radius in by (most of) the\n // wobble amplitude. The silhouette then stays inside the frame however far\n // the deformation is pushed, while lobes keep getting deeper relative to\n // the mean radius.\n const wobAmp = 0.23 * (o.wobMul ?? 1);\n const baseR = o.faceOn ? R / (1 + 0.85 * wobAmp) : R;\n\n const baseLanes = o.lanes ?? 5;\n const segs = o.segs ?? 88;\n const lanes = Math.max(1, Math.round(baseLanes * (o.bandMul ?? 1)));\n for (let w = 0; w < lanes; w++) {\n const laneOff = (w - (lanes - 1) / 2) * 0.075;\n const edge = Math.abs(w - (lanes - 1) / 2) / Math.max(1, (lanes - 1) / 2);\n for (let k = 0; k < segs; k++) {\n const a = (k / segs) * 2 * Math.PI;\n // the undulation: two traveling waves along the band; wobMul\n // scales the deformation — 0 is a clean band\n const wob =\n (0.16 * Math.sin(a * 3 - t * 1.7 + w * 0.22) + 0.07 * Math.sin(a * 5 + t * 1.1)) * (o.wobMul ?? 1);\n // A normal-direction wobble is cancelled by the re-normalisation below:\n // the point lands back on the sphere, so the silhouette is pinned at R\n // and the deformation can only ever pull dots inward. Face-on instead\n // modulates the in-plane RADIUS, so lobes genuinely swell outward and\n // pinch inward. Ribbon keeps the original out-of-plane sash wobble.\n const radial = o.faceOn ? 1 + wob : 1;\n const off = o.faceOn ? laneOff : laneOff + wob;\n const x = ux * Math.cos(a) + vx * Math.sin(a) + nx * off;\n const y = uy * Math.cos(a) + vy * Math.sin(a) + ny * off;\n const z = uz * Math.cos(a) + vz * Math.sin(a) + nz * off;\n const l = Math.sqrt(x * x + y * y + z * z);\n const rr = baseR * radial;\n const [px, py, zr] = pt((x / l) * rr, (y / l) * rr, (z / l) * rr);\n const depth = (zr / R + 1) / 2;\n dots.push({\n x: px,\n y: py,\n z: zr,\n r: ((o.rBase ?? 1.1) + (o.rDepth ?? 1.7) * depth) * (1 - 0.25 * edge) * rs,\n white: 0.52 - 0.44 * depth + 0.18 * edge,\n a: 0.4 + 0.6 * depth\n });\n }\n }\n return finalizeFrame(dots, [], o.rMin);\n};\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ModeOpts } from './profiles.js';
|
|
2
|
+
export type { Dot, Line, OrbFrame } from './core.js';
|
|
3
|
+
import type { OrbFrame } from './core.js';
|
|
4
|
+
/**
|
|
5
|
+
* Geometry for one instant: pure math over (size, t, opts), no rendering
|
|
6
|
+
* surface and no theme — `dark` only affects ink at paint time.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately closure-free and `Math`-only so the same function can run
|
|
9
|
+
* inside a Reanimated worklet on the React Native UI thread, and so its
|
|
10
|
+
* output can be compared numerically against the Swift port.
|
|
11
|
+
*/
|
|
12
|
+
export type ModeFrame = (size: number, t: number, opts: ModeOpts) => OrbFrame;
|
|
13
|
+
export type OrbState = 'working' | 'searching' | 'solving' | 'listening' | 'connecting' | 'weaving' | 'composing' | 'breathing' | 'shaping';
|
|
14
|
+
export type OrbSize = 20 | 64;
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAG9E,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAC5I,MAAM,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,8DAA8D","sourcesContent":["// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Engine-level contracts shared by every mode implementation.\n\nimport type { ModeOpts } from './profiles.js';\n\nexport type { Dot, Line, OrbFrame } from './core.js';\n\nimport type { OrbFrame } from './core.js';\n\n/**\n * Geometry for one instant: pure math over (size, t, opts), no rendering\n * surface and no theme — `dark` only affects ink at paint time.\n *\n * Deliberately closure-free and `Math`-only so the same function can run\n * inside a Reanimated worklet on the React Native UI thread, and so its\n * output can be compared numerically against the Swift port.\n */\nexport type ModeFrame = (size: number, t: number, opts: ModeOpts) => OrbFrame;\n\n\nexport type OrbState = 'working' | 'searching' | 'solving' | 'listening' | 'connecting' | 'weaving' | 'composing' | 'breathing' | 'shaping';\nexport type OrbSize = 20 | 64;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../src/internal/thinking-orb/web.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvD,eAAO,MAAM,QAAQ,EAAE,SAyFtB,CAAC"}
|