@hjmds/design-contracts 1.7.0 → 1.9.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/affix.d.ts +8 -0
- package/dist/affix.d.ts.map +1 -0
- package/dist/affix.js +7 -0
- package/dist/affix.js.map +1 -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 +445 -651
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +149 -101
- package/dist/catalog.js.map +1 -1
- package/dist/color-picker.d.ts +11 -0
- package/dist/color-picker.d.ts.map +1 -0
- package/dist/color-picker.js +20 -0
- package/dist/color-picker.js.map +1 -0
- 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 -9
- package/dist/component-definitions.d.ts.map +1 -1
- package/dist/component-definitions.js +1 -9
- 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 +10 -25
- package/dist/component-references.d.ts.map +1 -1
- package/dist/component-references.js +5 -8
- 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/interaction-adapters.d.ts +53 -0
- package/dist/interaction-adapters.d.ts.map +1 -0
- package/dist/interaction-adapters.js +45 -0
- package/dist/interaction-adapters.js.map +1 -0
- 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 +53 -12
- 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 +103 -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/dist/watermark.d.ts +15 -0
- package/dist/watermark.d.ts.map +1 -0
- package/dist/watermark.js +11 -0
- package/dist/watermark.js.map +1 -0
- package/docs/affix.md +27 -63
- package/docs/anchor.md +5 -4
- package/docs/ant-design-coverage.md +8 -12
- 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 +11 -0
- package/docs/catalog-cleanup.md +7 -0
- package/docs/catalog-decision-status.md +8 -3
- package/docs/catalog-freeze.json +9 -7
- package/docs/collapsible.md +12 -0
- package/docs/color-picker.md +30 -72
- package/docs/command-palette.md +5 -3
- package/docs/confirm-popover.md +5 -0
- 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 +91 -99
- package/docs/generated/renderer-evidence.json +2043 -1059
- package/docs/generated/renderer-evidence.md +156 -145
- package/docs/generated/showcase-manifest.json +476 -625
- 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 +126 -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/rating.md +5 -0
- 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 +92 -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/time-picker.md +5 -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 +7 -1
- package/docs/tree.md +12 -7
- package/docs/upload-item.md +7 -3
- package/docs/virtual-list.md +10 -67
- package/docs/watermark.md +26 -58
- package/package.json +54 -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,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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Indexed reads are bounded by the populated array length or modulo; assertions preserve upstream geometry.
|
|
2
|
+
// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
|
|
3
|
+
// Web: a constellation wires itself — the "connecting" state. Nodes drift
|
|
4
|
+
// on the sphere under slow value noise; any pair closer than `thr` grows an
|
|
5
|
+
// edge, and bright packets run along randomly re-picked node pairs.
|
|
6
|
+
import { fibDir, finalizeFrame, frac, hashD, lerp, makeProj, radiusScale, vnoise } from './core.js';
|
|
7
|
+
export const frameWeb = (size, t, o) => {
|
|
8
|
+
const cx = size / 2;
|
|
9
|
+
const cy = size / 2;
|
|
10
|
+
const R = (size / 2) * 0.8 * (o.spread ?? 1);
|
|
11
|
+
// note the projector carries the radius as its scale, so node vectors stay
|
|
12
|
+
// unit-length and distances below are in unit-sphere space
|
|
13
|
+
const pt = makeProj(t * 0.12, 0.32, cx, cy, R);
|
|
14
|
+
const rs = radiusScale(size, o.rsPow ?? 0.6);
|
|
15
|
+
const nodeN = o.nodeN ?? 30;
|
|
16
|
+
const thr = o.thr ?? 0.72;
|
|
17
|
+
const nodeR = o.nodeR ?? 1.4;
|
|
18
|
+
const nodeRDepth = o.nodeRDepth ?? 1.8;
|
|
19
|
+
// nodes: fib lattice + slow noise wander, renormalised to the surface
|
|
20
|
+
const nodes = [];
|
|
21
|
+
for (let i = 0; i < nodeN; i++) {
|
|
22
|
+
const d = fibDir(i, nodeN);
|
|
23
|
+
const x = d[0] + 0.3 * (vnoise(i * 0.31 + 9, t * 0.24) - 0.5) * 2;
|
|
24
|
+
const y = d[1] + 0.3 * (vnoise(i * 0.53 + 27, t * 0.21) - 0.5) * 2;
|
|
25
|
+
const z = d[2] + 0.3 * (vnoise(i * 0.77 + 55, t * 0.27) - 0.5) * 2;
|
|
26
|
+
const l = Math.sqrt(x * x + y * y + z * z);
|
|
27
|
+
nodes.push([x / l, y / l, z / l]);
|
|
28
|
+
}
|
|
29
|
+
const lines = [];
|
|
30
|
+
const dots = [];
|
|
31
|
+
// edges between close neighbours, alpha by proximity + depth
|
|
32
|
+
for (let i = 0; i < nodeN; i++) {
|
|
33
|
+
for (let j = i + 1; j < nodeN; j++) {
|
|
34
|
+
const dx = nodes[i][0] - nodes[j][0];
|
|
35
|
+
const dy = nodes[i][1] - nodes[j][1];
|
|
36
|
+
const dz = nodes[i][2] - nodes[j][2];
|
|
37
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
38
|
+
if (dist >= thr)
|
|
39
|
+
continue;
|
|
40
|
+
const [x1, y1, z1] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);
|
|
41
|
+
const [x2, y2, z2] = pt(nodes[j][0], nodes[j][1], nodes[j][2]);
|
|
42
|
+
const depth = ((z1 + z2) / 2 + 1) / 2;
|
|
43
|
+
lines.push({
|
|
44
|
+
x1,
|
|
45
|
+
y1,
|
|
46
|
+
x2,
|
|
47
|
+
y2,
|
|
48
|
+
white: 0.42,
|
|
49
|
+
a: (1 - dist / thr) * (0.3 + 0.55 * depth),
|
|
50
|
+
w: Math.max(0.6, (o.lineW ?? 0.8) * rs)
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (let i = 0; i < nodeN; i++) {
|
|
55
|
+
const [px, py, z] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);
|
|
56
|
+
const depth = (z + 1) / 2;
|
|
57
|
+
const pulse = 1 + 0.25 * Math.sin(t * 1.4 + i * 2.7);
|
|
58
|
+
dots.push({
|
|
59
|
+
x: px,
|
|
60
|
+
y: py,
|
|
61
|
+
z,
|
|
62
|
+
r: (nodeR + nodeRDepth * depth) * pulse * rs,
|
|
63
|
+
white: 0.55 - 0.45 * depth
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// signals: bright packets running between paired nodes
|
|
67
|
+
const signals = o.signals ?? 5;
|
|
68
|
+
for (let s = 0; s < signals; s++) {
|
|
69
|
+
const seg = Math.floor(t * 0.55 + s * 7.31);
|
|
70
|
+
const a = Math.floor(hashD(seg, s * 3.1 + 1.7) * nodeN);
|
|
71
|
+
const b = Math.floor(hashD(seg, s * 5.7 + 4.2) * nodeN);
|
|
72
|
+
if (a === b)
|
|
73
|
+
continue;
|
|
74
|
+
const f = frac(t * 0.55 + s * 7.31);
|
|
75
|
+
const x = lerp(nodes[a][0], nodes[b][0], f);
|
|
76
|
+
const y = lerp(nodes[a][1], nodes[b][1], f);
|
|
77
|
+
const z = lerp(nodes[a][2], nodes[b][2], f);
|
|
78
|
+
const l = Math.max(1e-6, Math.sqrt(x * x + y * y + z * z));
|
|
79
|
+
const [px, py, zr] = pt(x / l, y / l, z / l);
|
|
80
|
+
const depth = (zr + 1) / 2;
|
|
81
|
+
dots.push({
|
|
82
|
+
x: px,
|
|
83
|
+
y: py,
|
|
84
|
+
z: zr,
|
|
85
|
+
r: (nodeR * 1.5 + nodeRDepth * depth) * rs,
|
|
86
|
+
white: 0.05,
|
|
87
|
+
a: 0.5 + 0.5 * depth
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return finalizeFrame(dots, lines, o.rMin);
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/web.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAC5G,wEAAwE;AACxE,0EAA0E;AAC1E,4EAA4E;AAC5E,oEAAoE;AAGpE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEpG,MAAM,CAAC,MAAM,QAAQ,GAAc,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;IAChD,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;IACpB,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;IACpB,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAC7C,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;IAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC;IAC7B,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC;IAEvC,sEAAsE;IACtE,MAAM,KAAK,GAAoC,EAAE,CAAC;IAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACnE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACnE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,MAAM,IAAI,GAAU,EAAE,CAAC;IAEvB,6DAA6D;IAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,IAAI,IAAI,IAAI,GAAG;gBAAE,SAAS;YAC1B,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE;gBACF,EAAE;gBACF,EAAE;gBACF,EAAE;gBACF,KAAK,EAAE,IAAI;gBACX,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;gBAC1C,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;aACxC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC;YACR,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE;YACL,CAAC;YACD,CAAC,EAAE,CAAC,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;YAC5C,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,uDAAuD;IACvD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QACxD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC;YACR,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,GAAG,UAAU,GAAG,KAAK,CAAC,GAAG,EAAE;YAC1C,KAAK,EAAE,IAAI;YACX,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC","sourcesContent":["// Indexed reads are bounded by the populated array length or modulo; assertions preserve upstream geometry.\n// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Web: a constellation wires itself — the \"connecting\" state. Nodes drift\n// on the sphere under slow value noise; any pair closer than `thr` grows an\n// edge, and bright packets run along randomly re-picked node pairs.\n\nimport type { Dot, Line, ModeFrame } from './types.js';\nimport { fibDir, finalizeFrame, frac, hashD, lerp, makeProj, radiusScale, vnoise } from './core.js';\n\nexport const frameWeb: ModeFrame = (size, t, o) => {\n const cx = size / 2;\n const cy = size / 2;\n const R = (size / 2) * 0.8 * (o.spread ?? 1);\n // note the projector carries the radius as its scale, so node vectors stay\n // unit-length and distances below are in unit-sphere space\n const pt = makeProj(t * 0.12, 0.32, cx, cy, R);\n const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n const nodeN = o.nodeN ?? 30;\n const thr = o.thr ?? 0.72;\n const nodeR = o.nodeR ?? 1.4;\n const nodeRDepth = o.nodeRDepth ?? 1.8;\n\n // nodes: fib lattice + slow noise wander, renormalised to the surface\n const nodes: Array<[number, number, number]> = [];\n for (let i = 0; i < nodeN; i++) {\n const d = fibDir(i, nodeN);\n const x = d[0] + 0.3 * (vnoise(i * 0.31 + 9, t * 0.24) - 0.5) * 2;\n const y = d[1] + 0.3 * (vnoise(i * 0.53 + 27, t * 0.21) - 0.5) * 2;\n const z = d[2] + 0.3 * (vnoise(i * 0.77 + 55, t * 0.27) - 0.5) * 2;\n const l = Math.sqrt(x * x + y * y + z * z);\n nodes.push([x / l, y / l, z / l]);\n }\n\n const lines: Line[] = [];\n const dots: Dot[] = [];\n\n // edges between close neighbours, alpha by proximity + depth\n for (let i = 0; i < nodeN; i++) {\n for (let j = i + 1; j < nodeN; j++) {\n const dx = nodes[i]![0] - nodes[j]![0];\n const dy = nodes[i]![1] - nodes[j]![1];\n const dz = nodes[i]![2] - nodes[j]![2];\n const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);\n if (dist >= thr) continue;\n const [x1, y1, z1] = pt(nodes[i]![0], nodes[i]![1], nodes[i]![2]);\n const [x2, y2, z2] = pt(nodes[j]![0], nodes[j]![1], nodes[j]![2]);\n const depth = ((z1 + z2) / 2 + 1) / 2;\n lines.push({\n x1,\n y1,\n x2,\n y2,\n white: 0.42,\n a: (1 - dist / thr) * (0.3 + 0.55 * depth),\n w: Math.max(0.6, (o.lineW ?? 0.8) * rs)\n });\n }\n }\n\n for (let i = 0; i < nodeN; i++) {\n const [px, py, z] = pt(nodes[i]![0], nodes[i]![1], nodes[i]![2]);\n const depth = (z + 1) / 2;\n const pulse = 1 + 0.25 * Math.sin(t * 1.4 + i * 2.7);\n dots.push({\n x: px,\n y: py,\n z,\n r: (nodeR + nodeRDepth * depth) * pulse * rs,\n white: 0.55 - 0.45 * depth\n });\n }\n\n // signals: bright packets running between paired nodes\n const signals = o.signals ?? 5;\n for (let s = 0; s < signals; s++) {\n const seg = Math.floor(t * 0.55 + s * 7.31);\n const a = Math.floor(hashD(seg, s * 3.1 + 1.7) * nodeN);\n const b = Math.floor(hashD(seg, s * 5.7 + 4.2) * nodeN);\n if (a === b) continue;\n const f = frac(t * 0.55 + s * 7.31);\n const x = lerp(nodes[a]![0], nodes[b]![0], f);\n const y = lerp(nodes[a]![1], nodes[b]![1], f);\n const z = lerp(nodes[a]![2], nodes[b]![2], f);\n const l = Math.max(1e-6, Math.sqrt(x * x + y * y + z * z));\n const [px, py, zr] = pt(x / l, y / l, z / l);\n const depth = (zr + 1) / 2;\n dots.push({\n x: px,\n y: py,\n z: zr,\n r: (nodeR * 1.5 + nodeRDepth * depth) * rs,\n white: 0.05,\n a: 0.5 + 0.5 * depth\n });\n }\n\n return finalizeFrame(dots, lines, o.rMin);\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Height-driven packing preserves source order; DOM/native reading order never follows columns. */
|
|
2
|
+
export declare function resolveMasonryLayout(heights: readonly number[], width: number, columns?: number, gap?: number): {
|
|
3
|
+
items: {
|
|
4
|
+
top: number;
|
|
5
|
+
left: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}[];
|
|
9
|
+
height: number;
|
|
10
|
+
itemWidth: number;
|
|
11
|
+
};
|
|
12
|
+
export declare const masonryRecipe: {
|
|
13
|
+
readonly layout: "shortest-column";
|
|
14
|
+
readonly readingOrder: "source";
|
|
15
|
+
readonly maxColumns: 12;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=masonry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masonry.d.ts","sourceRoot":"","sources":["../src/masonry.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,EAAE,GAAG,SAAK;;;;;;;;;EAYpG;AACD,eAAO,MAAM,aAAa;;;;CAAiF,CAAC"}
|
package/dist/masonry.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Height-driven packing preserves source order; DOM/native reading order never follows columns. */
|
|
2
|
+
export function resolveMasonryLayout(heights, width, columns = 2, gap = 12) {
|
|
3
|
+
if (!Number.isFinite(width) || width <= 0 || !Number.isInteger(columns) || columns < 1 || columns > 12 || !Number.isFinite(gap) || gap < 0)
|
|
4
|
+
throw new TypeError("Invalid Masonry geometry");
|
|
5
|
+
const itemWidth = (width - gap * (columns - 1)) / columns;
|
|
6
|
+
if (itemWidth <= 0 || heights.some(height => !Number.isFinite(height) || height <= 0))
|
|
7
|
+
throw new TypeError("Masonry items need positive dimensions");
|
|
8
|
+
const ends = Array(columns).fill(0);
|
|
9
|
+
const items = heights.map(height => {
|
|
10
|
+
const column = ends.indexOf(Math.min(...ends));
|
|
11
|
+
const top = ends[column];
|
|
12
|
+
ends[column] = top + height + gap;
|
|
13
|
+
return { top, left: column * (itemWidth + gap), width: itemWidth, height };
|
|
14
|
+
});
|
|
15
|
+
return { items, height: heights.length ? Math.max(...ends) - gap : 0, itemWidth };
|
|
16
|
+
}
|
|
17
|
+
export const masonryRecipe = { layout: "shortest-column", readingOrder: "source", maxColumns: 12 };
|
|
18
|
+
//# sourceMappingURL=masonry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masonry.js","sourceRoot":"","sources":["../src/masonry.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,OAA0B,EAAE,KAAa,EAAE,OAAO,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE;IACnG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAC5L,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAC1D,IAAI,SAAS,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;IACrJ,MAAM,IAAI,GAAG,KAAK,CAAS,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QAClC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7E,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;AACpF,CAAC;AACD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAW,CAAC","sourcesContent":["/** Height-driven packing preserves source order; DOM/native reading order never follows columns. */\nexport function resolveMasonryLayout(heights: readonly number[], width: number, columns = 2, gap = 12) {\n if (!Number.isFinite(width) || width <= 0 || !Number.isInteger(columns) || columns < 1 || columns > 12 || !Number.isFinite(gap) || gap < 0) throw new TypeError(\"Invalid Masonry geometry\");\n const itemWidth = (width - gap * (columns - 1)) / columns;\n if (itemWidth <= 0 || heights.some(height => !Number.isFinite(height) || height <= 0)) throw new TypeError(\"Masonry items need positive dimensions\");\n const ends = Array<number>(columns).fill(0);\n const items = heights.map(height => {\n const column = ends.indexOf(Math.min(...ends));\n const top = ends[column]!;\n ends[column] = top + height + gap;\n return { top, left: column * (itemWidth + gap), width: itemWidth, height };\n });\n return { items, height: heights.length ? Math.max(...ends) - gap : 0, itemWidth };\n}\nexport const masonryRecipe = { layout: \"shortest-column\", readingOrder: \"source\", maxColumns: 12 } as const;\n"]}
|
package/dist/menubar.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare const menubarRecipe: {
|
|
|
40
40
|
}>;
|
|
41
41
|
readonly openBackground: Readonly<{
|
|
42
42
|
source: "theme";
|
|
43
|
-
key: "
|
|
43
|
+
key: "bg";
|
|
44
44
|
alpha?: number;
|
|
45
45
|
}>;
|
|
46
46
|
};
|
|
@@ -67,7 +67,7 @@ export declare const menubarRecipe: {
|
|
|
67
67
|
};
|
|
68
68
|
readonly highlightedBackground: Readonly<{
|
|
69
69
|
source: "theme";
|
|
70
|
-
key: "
|
|
70
|
+
key: "bg";
|
|
71
71
|
alpha?: number;
|
|
72
72
|
}>;
|
|
73
73
|
readonly focus: {
|
|
@@ -81,7 +81,7 @@ export declare const menubarRecipe: {
|
|
|
81
81
|
};
|
|
82
82
|
readonly selectedBackground: Readonly<{
|
|
83
83
|
source: "theme";
|
|
84
|
-
key: "
|
|
84
|
+
key: "bg";
|
|
85
85
|
alpha?: number;
|
|
86
86
|
}>;
|
|
87
87
|
readonly selectedIndicator: Readonly<{
|
package/dist/menubar.js
CHANGED
|
@@ -47,7 +47,7 @@ export const menubarRecipe = {
|
|
|
47
47
|
paddingHorizontal: spacing.sm,
|
|
48
48
|
radius: radius.sm,
|
|
49
49
|
color: semanticColors.content.body,
|
|
50
|
-
openBackground: semanticColors.
|
|
50
|
+
openBackground: semanticColors.canvas,
|
|
51
51
|
},
|
|
52
52
|
item: collectionItemContract,
|
|
53
53
|
states: { focus: focusIndicatorContract },
|
package/dist/menubar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BehaviorContract, MenuItemDescriptor } from \"./behaviors.js\";\nimport type { ColorReference } from \"./color-references.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, radius, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\n/**\n * 데스크톱 앱의 가로 메뉴 막대 — 파일·편집·보기처럼 항상 같은 자리에 있는 메뉴들.\n *\n * `Menu` 여러 개를 나란히 놓는 것과 다르다. 막대는 **하나의 키보드 단위**다: 메뉴가\n * 열린 상태에서 좌우 방향키를 누르면 옆 메뉴로 **넘어가고**(닫았다 여는 것이 아니라),\n * 한 번에 하나만 열린다. 독립된 Menu 세 개로는 그 이동이 성립하지 않는다.\n *\n * `Tabs`와도 다르다. Tabs는 화면을 바꾸고 선택 상태가 남는다. Menubar는 행동을 실행하고\n * 아무것도 선택되지 않은 상태로 돌아간다.\n */\nexport type MenubarMenuDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n id: MenuKey;\n label: string;\n items: readonly MenuItemDescriptor<Key>[];\n disabled?: boolean;\n}>;\n\nexport type MenubarDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n accessibilityLabel: string;\n menus: readonly MenubarMenuDescriptor<Key, MenuKey>[];\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`Menubar ${field} must not be empty`);\n }\n}\n\nexport function validateMenubarDescriptor<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n): void {\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n if (!Array.isArray(descriptor.menus) || descriptor.menus.length === 0) {\n throw new RangeError(\"Menubar must contain at least one menu\");\n }\n const menuIds = new Set<MenuKey>();\n for (const menu of descriptor.menus) {\n assertNonEmpty(menu.id, \"menu id\");\n assertNonEmpty(menu.label, `menu ${menu.id} label`);\n if (menuIds.has(menu.id)) throw new TypeError(`Duplicate Menubar menu id: ${menu.id}`);\n menuIds.add(menu.id);\n if (!Array.isArray(menu.items) || menu.items.length === 0) {\n throw new RangeError(`Menubar menu ${menu.id} must contain at least one item`);\n }\n }\n}\n\n/**\n * 좌우 이동은 **비활성 메뉴를 건너뛰고 순환**한다. 막대 끝에서 멈추면 사용자가 방향을\n * 바꿔 되돌아와야 하는데, 항목이 대여섯 개뿐인 가로 막대에서는 순환이 더 짧다.\n */\nexport function resolveMenubarNavigation<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n currentId: MenuKey,\n direction: \"next\" | \"previous\",\n): MenuKey {\n validateMenubarDescriptor(descriptor);\n const enabled = descriptor.menus.filter((menu) => menu.disabled !== true);\n if (enabled.length === 0) return currentId;\n const index = enabled.findIndex((menu) => menu.id === currentId);\n if (index === -1) return enabled[0]!.id;\n const next = direction === \"next\" ? index + 1 : index - 1;\n return enabled[(next + enabled.length) % enabled.length]!.id;\n}\n\nexport const menubarRecipe = {\n slots: [\"root\", \"menu\", \"label\", \"panel\", \"item\"] as const,\n minHeight: control.minTouchTarget,\n gap: spacing.xxs,\n paddingHorizontal: spacing.xs,\n label: {\n paddingHorizontal: spacing.sm,\n radius: radius.sm,\n color: semanticColors.content.body,\n openBackground: semanticColors.canvas,\n },\n item: collectionItemContract,\n states: { focus: focusIndicatorContract },\n} as const satisfies {\n slots: readonly [\"root\", \"menu\", \"label\", \"panel\", \"item\"];\n minHeight: number;\n gap: number;\n paddingHorizontal: number;\n label: { paddingHorizontal: number; radius: number; color: ColorReference; openBackground: ColorReference };\n item: typeof collectionItemContract;\n states: { focus: typeof focusIndicatorContract };\n};\n\nexport const menubarBehavior = {\n controlled: [\"openMenuId\", \"defaultOpenMenuId\", \"onOpenMenuIdChange\"],\n inputs: [\"menus\", \"accessibilityLabel\"],\n events: [\"onAction\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\"],\n value: [\"open\", \"closed\"],\n interaction: [\"idle\", \"hover\", \"focusVisible\"],\n },\n web: {\n roles: [\"menubar\", \"menuitem\", \"menu\"],\n keyboard: [\"ArrowLeft\", \"ArrowRight\", \"ArrowDown\", \"ArrowUp\", \"Home\", \"End\", \"Enter\", \"Space\", \"Escape\"],\n focus: \"roving\",\n dismiss: [\"escape\", \"outside\"],\n },\n /** Web-only: a phone has no always-present menu bar, and a native app bar is the OS's. */\n native: { roles: [], states: [], actions: [] },\n scenarios: [\n \"left-and-right-move-between-menus-while-one-is-open-instead-of-closing-and-reopening\",\n \"exactly-one-menu-is-open-at-a-time-which-three-independent-menus-cannot-guarantee\",\n \"disabled-menus-are-skipped-by-navigation-and-cycling-is-shorter-than-stopping-at-the-end\",\n \"the-bar-is-a-single-tab-stop-with-roving-focus-not-one-stop-per-menu\",\n \"activating-an-item-runs-an-action-and-leaves-nothing-selected-unlike-tabs\",\n ],\n} as const satisfies BehaviorContract;\n"]}
|