@joewinke/jatui 0.22.0 → 0.24.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/CLAUDE.md +72 -2
- package/dist/actions/reveal.d.ts +37 -0
- package/dist/actions/reveal.js +42 -0
- package/dist/components/AudioRecorder.svelte +529 -0
- package/dist/components/AudioRecorder.svelte.d.ts +30 -0
- package/dist/components/BulkActionBar.svelte +40 -0
- package/dist/components/BulkActionBar.svelte.d.ts +9 -0
- package/dist/components/ConfirmDialog.svelte +39 -35
- package/dist/components/CopyButton.svelte +5 -2
- package/dist/components/FloatingActionBar.svelte +55 -1
- package/dist/components/FloatingActionBar.svelte.d.ts +8 -1
- package/dist/components/IconSelector.svelte +417 -0
- package/dist/components/IconSelector.svelte.d.ts +55 -0
- package/dist/components/InfiniteGrid.svelte +305 -0
- package/dist/components/InfiniteGrid.svelte.d.ts +71 -0
- package/dist/components/InfiniteSearchGrid.svelte +131 -0
- package/dist/components/InfiniteSearchGrid.svelte.d.ts +67 -0
- package/dist/components/InputDialog.svelte +49 -38
- package/dist/components/KeyboardShortcutsOverlay.svelte +94 -3
- package/dist/components/KeyboardShortcutsOverlay.svelte.d.ts +61 -16
- package/dist/components/MediaCaptureIcon.svelte +23 -0
- package/dist/components/MediaCaptureIcon.svelte.d.ts +1 -1
- package/dist/components/ThumbnailGrid.svelte +137 -0
- package/dist/components/ThumbnailGrid.svelte.d.ts +42 -0
- package/dist/components/batch/BatchJobTable.svelte +549 -0
- package/dist/components/batch/BatchJobTable.svelte.d.ts +114 -0
- package/dist/components/batch/QuotaMeter.svelte +78 -0
- package/dist/components/batch/QuotaMeter.svelte.d.ts +16 -0
- package/dist/components/batch/batchQueue.d.ts +56 -0
- package/dist/components/batch/batchQueue.js +81 -0
- package/dist/components/batch/elapsedEstimate.d.ts +24 -0
- package/dist/components/batch/elapsedEstimate.js +25 -0
- package/dist/components/batch/pollOperation.d.ts +45 -0
- package/dist/components/batch/pollOperation.js +80 -0
- package/dist/components/batch/useElapsedEstimate.d.ts +10 -0
- package/dist/components/batch/useElapsedEstimate.js +38 -0
- package/dist/components/bulkActionBarKeys.d.ts +40 -0
- package/dist/components/bulkActionBarKeys.js +38 -0
- package/dist/components/infiniteGridLoader.d.ts +70 -0
- package/dist/components/infiniteGridLoader.js +141 -0
- package/dist/components/linked-columns/LinkedColumns.svelte +10 -22
- package/dist/components/linked-columns/LinkedColumns.svelte.d.ts +1 -9
- package/dist/components/linked-columns/types.d.ts +9 -0
- package/dist/components/linked-columns/types.js +1 -0
- package/dist/components/replay/ChapterTimeline.svelte +43 -25
- package/dist/components/replay/ChapterTimeline.svelte.d.ts +26 -1
- package/dist/components/table/columnResize.d.ts +38 -0
- package/dist/components/table/columnResize.js +117 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/toast/ToastItem.svelte +47 -2
- package/dist/components/variant/VariantMatrixPicker.svelte +181 -0
- package/dist/components/variant/VariantMatrixPicker.svelte.d.ts +37 -0
- package/dist/components/variant/variantCombinations.d.ts +75 -0
- package/dist/components/variant/variantCombinations.js +100 -0
- package/dist/index.d.ts +34 -3
- package/dist/index.js +30 -1
- package/dist/stores/toast.d.ts +8 -0
- package/dist/stores/toast.js +2 -0
- package/dist/styles/motion.css +100 -0
- package/dist/utils/audioRecorder.d.ts +28 -0
- package/dist/utils/audioRecorder.js +58 -0
- package/dist/utils/audioRecorderCore.d.ts +132 -0
- package/dist/utils/audioRecorderCore.js +447 -0
- package/dist/utils/clipboard.d.ts +25 -0
- package/dist/utils/clipboard.js +59 -0
- package/dist/utils/dateFormatters.d.ts +11 -2
- package/dist/utils/dateFormatters.js +22 -2
- package/dist/utils/keyboardShortcutRegistry.d.ts +152 -0
- package/dist/utils/keyboardShortcutRegistry.js +365 -0
- package/package.json +1 -1
|
@@ -151,7 +151,11 @@
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
//
|
|
154
|
+
// Collapsible details (toast.details)
|
|
155
|
+
let detailsOpen = $state(false);
|
|
156
|
+
const detailsId = $derived(`toast-details-${toast.id}`);
|
|
157
|
+
|
|
158
|
+
// DaisyUI alert class per type
|
|
155
159
|
const alertClass: Record<string, string> = {
|
|
156
160
|
info: 'alert-info',
|
|
157
161
|
success: 'alert-success',
|
|
@@ -223,7 +227,40 @@
|
|
|
223
227
|
></span>
|
|
224
228
|
{/if}
|
|
225
229
|
|
|
226
|
-
<
|
|
230
|
+
<div class="flex-1 min-w-0">
|
|
231
|
+
<span class="text-sm">{toast.message}</span>
|
|
232
|
+
|
|
233
|
+
{#if toast.details}
|
|
234
|
+
<button
|
|
235
|
+
type="button"
|
|
236
|
+
class="toast-details-toggle btn btn-ghost btn-xs mt-0.5 h-auto min-h-0 gap-1 px-0 font-semibold opacity-70"
|
|
237
|
+
aria-expanded={detailsOpen}
|
|
238
|
+
aria-controls={detailsId}
|
|
239
|
+
onclick={() => (detailsOpen = !detailsOpen)}
|
|
240
|
+
>
|
|
241
|
+
<svg
|
|
242
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
243
|
+
class="size-3"
|
|
244
|
+
class:rotate-90={detailsOpen}
|
|
245
|
+
viewBox="0 0 24 24"
|
|
246
|
+
fill="none"
|
|
247
|
+
stroke="currentColor"
|
|
248
|
+
stroke-width="2.5"
|
|
249
|
+
stroke-linecap="round"
|
|
250
|
+
stroke-linejoin="round"
|
|
251
|
+
>
|
|
252
|
+
<path d="m9 18 6-6-6-6" />
|
|
253
|
+
</svg>
|
|
254
|
+
Details
|
|
255
|
+
</button>
|
|
256
|
+
{#if detailsOpen}
|
|
257
|
+
<pre
|
|
258
|
+
id={detailsId}
|
|
259
|
+
class="toast-details mt-1 max-h-40 overflow-auto rounded border border-current/20 bg-base-content/5 p-2 font-mono text-xs whitespace-pre-wrap break-words"
|
|
260
|
+
>{toast.details}</pre>
|
|
261
|
+
{/if}
|
|
262
|
+
{/if}
|
|
263
|
+
</div>
|
|
227
264
|
|
|
228
265
|
{#if toast.onUndo}
|
|
229
266
|
<button
|
|
@@ -274,7 +311,15 @@
|
|
|
274
311
|
to { transform: scaleX(0); }
|
|
275
312
|
}
|
|
276
313
|
|
|
314
|
+
.toast-details-toggle svg {
|
|
315
|
+
transition: transform var(--motion-fast) var(--motion-glide);
|
|
316
|
+
}
|
|
317
|
+
|
|
277
318
|
@media (prefers-reduced-motion: reduce) {
|
|
319
|
+
.toast-details-toggle svg {
|
|
320
|
+
transition: none;
|
|
321
|
+
}
|
|
322
|
+
|
|
278
323
|
.toast-progress {
|
|
279
324
|
animation: none;
|
|
280
325
|
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* VariantMatrixPicker Component
|
|
4
|
+
*
|
|
5
|
+
* Category/option chip grid for building a combinatorial variant matrix
|
|
6
|
+
* (jatui-m4uz3.8, ported from vid-gen's FrameVariantGenerator selection UI,
|
|
7
|
+
* lines 72–197 / 500–620, with the hardcoded presets stripped).
|
|
8
|
+
*
|
|
9
|
+
* Every category renders as a tab with its options as toggleable chips.
|
|
10
|
+
* Each category carries an `additive`/`multiplicative` badge:
|
|
11
|
+
* - multiplicative: each selection multiplies the total combination count
|
|
12
|
+
* (cartesian product across multiplicative categories);
|
|
13
|
+
* - additive: selections stack flat onto every combination.
|
|
14
|
+
* A live combination count renders in the footer via `countCombinations`.
|
|
15
|
+
*
|
|
16
|
+
* The algebra lives in `./variantCombinations.ts` (pure, unit-tested);
|
|
17
|
+
* the host passes `categories` and reads/binds `selected`.
|
|
18
|
+
*/
|
|
19
|
+
import {
|
|
20
|
+
countCombinations,
|
|
21
|
+
variantCategoryMode,
|
|
22
|
+
type VariantCategory,
|
|
23
|
+
type VariantSelection,
|
|
24
|
+
type VariantSelectionMode
|
|
25
|
+
} from './variantCombinations';
|
|
26
|
+
|
|
27
|
+
interface Props {
|
|
28
|
+
/** Category/option matrix — caller-supplied, no presets inside the component. */
|
|
29
|
+
categories: VariantCategory[];
|
|
30
|
+
/** categoryId → selected option ids. Bind to drive the matrix externally. */
|
|
31
|
+
selected: VariantSelection;
|
|
32
|
+
/** Force every category to one mode (`null` respects each category's own). */
|
|
33
|
+
forceMode?: VariantSelectionMode | null;
|
|
34
|
+
/** Show the live combination count footer (default true). */
|
|
35
|
+
showCount?: boolean;
|
|
36
|
+
/** Optional label for the count footer (default "combinations"). */
|
|
37
|
+
countLabel?: string;
|
|
38
|
+
/** Fired after every selection change with the new selection. */
|
|
39
|
+
onChange?: (selected: VariantSelection) => void;
|
|
40
|
+
/** Additional CSS class for the container. */
|
|
41
|
+
class?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let {
|
|
45
|
+
categories,
|
|
46
|
+
selected = $bindable({}),
|
|
47
|
+
forceMode = null,
|
|
48
|
+
showCount = true,
|
|
49
|
+
countLabel = 'combinations',
|
|
50
|
+
onChange,
|
|
51
|
+
class: className = ''
|
|
52
|
+
}: Props = $props();
|
|
53
|
+
|
|
54
|
+
let activeTab = $state('');
|
|
55
|
+
|
|
56
|
+
// Follow the category list if it changes identity.
|
|
57
|
+
$effect(() => {
|
|
58
|
+
if (!categories.some((c) => c.id === activeTab)) {
|
|
59
|
+
activeTab = categories[0]?.id ?? '';
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const combinationCount = $derived(countCombinations(categories, selected, forceMode));
|
|
64
|
+
const selectedCount = (categoryId: string) => selected[categoryId]?.length ?? 0;
|
|
65
|
+
const activeCategory = $derived(categories.find((c) => c.id === activeTab));
|
|
66
|
+
|
|
67
|
+
function toggleOption(categoryId: string, optionId: string) {
|
|
68
|
+
const current = selected[categoryId] ?? [];
|
|
69
|
+
const next = current.includes(optionId)
|
|
70
|
+
? current.filter((id) => id !== optionId)
|
|
71
|
+
: [...current, optionId];
|
|
72
|
+
selected = { ...selected, [categoryId]: next };
|
|
73
|
+
onChange?.(selected);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function selectAll(categoryId: string) {
|
|
77
|
+
const category = categories.find((c) => c.id === categoryId);
|
|
78
|
+
if (!category) return;
|
|
79
|
+
selected = { ...selected, [categoryId]: category.options.map((o) => o.id) };
|
|
80
|
+
onChange?.(selected);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function clearCategory(categoryId: string) {
|
|
84
|
+
selected = { ...selected, [categoryId]: [] };
|
|
85
|
+
onChange?.(selected);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function clearAll() {
|
|
89
|
+
const next: VariantSelection = {};
|
|
90
|
+
for (const c of categories) next[c.id] = [];
|
|
91
|
+
selected = next;
|
|
92
|
+
onChange?.(next);
|
|
93
|
+
}
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<div class="{className}">
|
|
97
|
+
<!-- Category tabs: icon, label, live selection count -->
|
|
98
|
+
<div role="tablist" aria-label="Variant categories" class="flex flex-wrap gap-1 mb-3">
|
|
99
|
+
{#each categories as category (category.id)}
|
|
100
|
+
{@const count = selectedCount(category.id)}
|
|
101
|
+
<button
|
|
102
|
+
role="tab"
|
|
103
|
+
aria-selected={activeTab === category.id}
|
|
104
|
+
class="btn btn-sm gap-2 {activeTab === category.id ? 'btn-primary' : 'btn-ghost'}"
|
|
105
|
+
onclick={() => (activeTab = category.id)}
|
|
106
|
+
>
|
|
107
|
+
{#if category.icon}<span class="text-base">{category.icon}</span>{/if}
|
|
108
|
+
<span>{category.label}</span>
|
|
109
|
+
{#if count > 0}<span class="badge badge-sm">{count}</span>{/if}
|
|
110
|
+
</button>
|
|
111
|
+
{/each}
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
{#if activeCategory}
|
|
115
|
+
{@const count = selectedCount(activeCategory.id)}
|
|
116
|
+
{@const isAdditive = variantCategoryMode(activeCategory, forceMode) === 'additive'}
|
|
117
|
+
<div class="card bg-base-200 shadow-sm">
|
|
118
|
+
<div class="card-body p-4">
|
|
119
|
+
<!-- Category header: mode badge + bulk actions -->
|
|
120
|
+
<div class="flex items-center justify-between gap-2 mb-3">
|
|
121
|
+
<div class="flex items-center gap-2">
|
|
122
|
+
{#if activeCategory.icon}<span class="text-xl">{activeCategory.icon}</span>{/if}
|
|
123
|
+
<h3 class="font-bold">{activeCategory.label}</h3>
|
|
124
|
+
<span
|
|
125
|
+
class="badge badge-sm {isAdditive ? 'badge-success' : 'badge-info'}"
|
|
126
|
+
title={isAdditive
|
|
127
|
+
? 'Additive — selections stack onto every combination'
|
|
128
|
+
: 'Multiplicative — each selection multiplies the combination count'}
|
|
129
|
+
>
|
|
130
|
+
{isAdditive ? '➕ Additive' : '✖️ Multiplicative'}
|
|
131
|
+
</span>
|
|
132
|
+
{#if count > 0}<span class="badge badge-sm badge-primary">{count}</span>{/if}
|
|
133
|
+
</div>
|
|
134
|
+
<div class="flex items-center gap-1">
|
|
135
|
+
<button
|
|
136
|
+
class="btn btn-xs"
|
|
137
|
+
onclick={() => selectAll(activeCategory.id)}
|
|
138
|
+
disabled={activeCategory.options.length === 0}
|
|
139
|
+
>
|
|
140
|
+
Select all
|
|
141
|
+
</button>
|
|
142
|
+
{#if count > 0}
|
|
143
|
+
<button class="btn btn-xs btn-ghost" onclick={() => clearCategory(activeCategory.id)}>
|
|
144
|
+
Clear
|
|
145
|
+
</button>
|
|
146
|
+
{/if}
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<!-- Option chip grid -->
|
|
151
|
+
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
|
|
152
|
+
{#each activeCategory.options as option (option.id)}
|
|
153
|
+
{@const isSelected = selected[activeCategory.id]?.includes(option.id)}
|
|
154
|
+
<button
|
|
155
|
+
class="btn btn-sm normal-case justify-start gap-1 {isSelected
|
|
156
|
+
? 'btn-info'
|
|
157
|
+
: 'btn-outline'}"
|
|
158
|
+
aria-pressed={isSelected}
|
|
159
|
+
onclick={() => toggleOption(activeCategory.id, option.id)}
|
|
160
|
+
>
|
|
161
|
+
{isSelected ? '✓' : '➕'}
|
|
162
|
+
<span class="truncate">{option.label}</span>
|
|
163
|
+
</button>
|
|
164
|
+
{/each}
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
{/if}
|
|
169
|
+
|
|
170
|
+
<!-- Footer: live combination count -->
|
|
171
|
+
{#if showCount}
|
|
172
|
+
<div class="flex items-center justify-between mt-3 text-sm">
|
|
173
|
+
<span class="text-base-content/60">
|
|
174
|
+
<strong class="text-base-content">{combinationCount}</strong>
|
|
175
|
+
{countLabel}
|
|
176
|
+
{#if combinationCount === 0}<span class="text-base-content/40"> — select an option to start</span>{/if}
|
|
177
|
+
</span>
|
|
178
|
+
<button class="btn btn-xs btn-ghost" onclick={clearAll}>Clear all</button>
|
|
179
|
+
</div>
|
|
180
|
+
{/if}
|
|
181
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VariantMatrixPicker Component
|
|
3
|
+
*
|
|
4
|
+
* Category/option chip grid for building a combinatorial variant matrix
|
|
5
|
+
* (jatui-m4uz3.8, ported from vid-gen's FrameVariantGenerator selection UI,
|
|
6
|
+
* lines 72–197 / 500–620, with the hardcoded presets stripped).
|
|
7
|
+
*
|
|
8
|
+
* Every category renders as a tab with its options as toggleable chips.
|
|
9
|
+
* Each category carries an `additive`/`multiplicative` badge:
|
|
10
|
+
* - multiplicative: each selection multiplies the total combination count
|
|
11
|
+
* (cartesian product across multiplicative categories);
|
|
12
|
+
* - additive: selections stack flat onto every combination.
|
|
13
|
+
* A live combination count renders in the footer via `countCombinations`.
|
|
14
|
+
*
|
|
15
|
+
* The algebra lives in `./variantCombinations.ts` (pure, unit-tested);
|
|
16
|
+
* the host passes `categories` and reads/binds `selected`.
|
|
17
|
+
*/
|
|
18
|
+
import { type VariantCategory, type VariantSelection, type VariantSelectionMode } from './variantCombinations';
|
|
19
|
+
interface Props {
|
|
20
|
+
/** Category/option matrix — caller-supplied, no presets inside the component. */
|
|
21
|
+
categories: VariantCategory[];
|
|
22
|
+
/** categoryId → selected option ids. Bind to drive the matrix externally. */
|
|
23
|
+
selected: VariantSelection;
|
|
24
|
+
/** Force every category to one mode (`null` respects each category's own). */
|
|
25
|
+
forceMode?: VariantSelectionMode | null;
|
|
26
|
+
/** Show the live combination count footer (default true). */
|
|
27
|
+
showCount?: boolean;
|
|
28
|
+
/** Optional label for the count footer (default "combinations"). */
|
|
29
|
+
countLabel?: string;
|
|
30
|
+
/** Fired after every selection change with the new selection. */
|
|
31
|
+
onChange?: (selected: VariantSelection) => void;
|
|
32
|
+
/** Additional CSS class for the container. */
|
|
33
|
+
class?: string;
|
|
34
|
+
}
|
|
35
|
+
declare const VariantMatrixPicker: import("svelte").Component<Props, {}, "selected">;
|
|
36
|
+
type VariantMatrixPicker = ReturnType<typeof VariantMatrixPicker>;
|
|
37
|
+
export default VariantMatrixPicker;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure combination algebra behind `VariantMatrixPicker` (jatui-m4uz3.8).
|
|
3
|
+
*
|
|
4
|
+
* Ported from vid-gen's `variantPresets.js` (generateCombinations + friends),
|
|
5
|
+
* with the hardcoded apparel/background/lighting preset map stripped out:
|
|
6
|
+
* every category and option is caller-supplied, so the algebra works for any
|
|
7
|
+
* combinatorial domain (image variants, A/B matrices, test permutations…).
|
|
8
|
+
*
|
|
9
|
+
* Two category modes drive the math:
|
|
10
|
+
* - `multiplicative`: each selected option pairs with every selection in the
|
|
11
|
+
* other multiplicative categories → cartesian product, one new variant
|
|
12
|
+
* per pick.
|
|
13
|
+
* - `additive`: all selected options stack flat into every combination —
|
|
14
|
+
* they ride along instead of multiplying.
|
|
15
|
+
*
|
|
16
|
+
* No DOM, no runes — kept separate so the math is unit-testable under plain
|
|
17
|
+
* node:test (mirrors the `batch/` module split from jatui-m4uz3.7).
|
|
18
|
+
*/
|
|
19
|
+
export type VariantSelectionMode = 'multiplicative' | 'additive';
|
|
20
|
+
export interface VariantOption {
|
|
21
|
+
id: string;
|
|
22
|
+
label: string;
|
|
23
|
+
/** Optional host payload — vid-gen used image-edit prompts; joined with ', ' into `VariantCombination.prompt`. */
|
|
24
|
+
prompt?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface VariantCategory {
|
|
27
|
+
id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
/** Emoji or short glyph shown on the category tab. */
|
|
30
|
+
icon?: string;
|
|
31
|
+
/** Defaults to `multiplicative`. */
|
|
32
|
+
mode?: VariantSelectionMode;
|
|
33
|
+
options: VariantOption[];
|
|
34
|
+
}
|
|
35
|
+
/** categoryId → selected option ids (mirror of vid-gen's selectedModifiers). */
|
|
36
|
+
export type VariantSelection = Record<string, string[]>;
|
|
37
|
+
export interface VariantCombination {
|
|
38
|
+
/** Flat list of every option id in the combination (multiplicative picks + stacked additive picks). */
|
|
39
|
+
modifierIds: string[];
|
|
40
|
+
/** All `prompt`s joined with ', ' — empty string when no option carries a prompt. */
|
|
41
|
+
prompt: string;
|
|
42
|
+
/** Resolved option objects, in category order. */
|
|
43
|
+
options: VariantOption[];
|
|
44
|
+
}
|
|
45
|
+
export interface GenerateCombinationsOptions {
|
|
46
|
+
/** Override every category's mode. `null` (default) respects each category's own mode. */
|
|
47
|
+
forceMode?: VariantSelectionMode | null;
|
|
48
|
+
}
|
|
49
|
+
/** Resolve a category's effective mode: forceMode wins, then the category's own, then multiplicative. */
|
|
50
|
+
export declare function variantCategoryMode(category: VariantCategory, forceMode?: VariantSelectionMode | null): VariantSelectionMode;
|
|
51
|
+
/** Look up an option by category + id across a caller-supplied category list. */
|
|
52
|
+
export declare function findVariantOption(categories: VariantCategory[], categoryId: string, optionId: string): VariantOption | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Number of combinations `generateCombinations` would produce — the live count
|
|
55
|
+
* the picker footer renders. Multiplicative categories multiply; a selection
|
|
56
|
+
* with only additive categories counts as exactly 1 stacked combination.
|
|
57
|
+
*/
|
|
58
|
+
export declare function countCombinations(categories: VariantCategory[], selected: VariantSelection, forceMode?: VariantSelectionMode | null): number;
|
|
59
|
+
/**
|
|
60
|
+
* Generate all combinations from the current selection.
|
|
61
|
+
*
|
|
62
|
+
* Mirrors vid-gen's `generateCombinations(selectedModifiers, options)`:
|
|
63
|
+
* - categories with nothing selected are skipped entirely (all-empty → []);
|
|
64
|
+
* - multiplicative categories contribute one option per combination via
|
|
65
|
+
* cartesian product; additive selections stack flat onto every combination;
|
|
66
|
+
* - with no multiplicative selections at all, a single additive-only
|
|
67
|
+
* combination is produced.
|
|
68
|
+
*/
|
|
69
|
+
export declare function generateCombinations(categories: VariantCategory[], selected: VariantSelection, options?: GenerateCombinationsOptions): VariantCombination[];
|
|
70
|
+
/**
|
|
71
|
+
* Build a variant filename from an original filename and modifier ids
|
|
72
|
+
* (vid-gen's `generateVariantFilename`, generic — no preset knowledge):
|
|
73
|
+
* `photo.png` + ['a', 'b'] → `photo_a_b.png`, ids sorted for consistency.
|
|
74
|
+
*/
|
|
75
|
+
export declare function generateVariantFilename(originalFilename: string, modifierIds: string[]): string;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure combination algebra behind `VariantMatrixPicker` (jatui-m4uz3.8).
|
|
3
|
+
*
|
|
4
|
+
* Ported from vid-gen's `variantPresets.js` (generateCombinations + friends),
|
|
5
|
+
* with the hardcoded apparel/background/lighting preset map stripped out:
|
|
6
|
+
* every category and option is caller-supplied, so the algebra works for any
|
|
7
|
+
* combinatorial domain (image variants, A/B matrices, test permutations…).
|
|
8
|
+
*
|
|
9
|
+
* Two category modes drive the math:
|
|
10
|
+
* - `multiplicative`: each selected option pairs with every selection in the
|
|
11
|
+
* other multiplicative categories → cartesian product, one new variant
|
|
12
|
+
* per pick.
|
|
13
|
+
* - `additive`: all selected options stack flat into every combination —
|
|
14
|
+
* they ride along instead of multiplying.
|
|
15
|
+
*
|
|
16
|
+
* No DOM, no runes — kept separate so the math is unit-testable under plain
|
|
17
|
+
* node:test (mirrors the `batch/` module split from jatui-m4uz3.7).
|
|
18
|
+
*/
|
|
19
|
+
/** Resolve a category's effective mode: forceMode wins, then the category's own, then multiplicative. */
|
|
20
|
+
export function variantCategoryMode(category, forceMode = null) {
|
|
21
|
+
return forceMode ?? category.mode ?? 'multiplicative';
|
|
22
|
+
}
|
|
23
|
+
/** Look up an option by category + id across a caller-supplied category list. */
|
|
24
|
+
export function findVariantOption(categories, categoryId, optionId) {
|
|
25
|
+
return categories.find((c) => c.id === categoryId)?.options.find((o) => o.id === optionId);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Number of combinations `generateCombinations` would produce — the live count
|
|
29
|
+
* the picker footer renders. Multiplicative categories multiply; a selection
|
|
30
|
+
* with only additive categories counts as exactly 1 stacked combination.
|
|
31
|
+
*/
|
|
32
|
+
export function countCombinations(categories, selected, forceMode = null) {
|
|
33
|
+
const active = categories.filter((c) => (selected[c.id]?.length ?? 0) > 0);
|
|
34
|
+
if (active.length === 0)
|
|
35
|
+
return 0;
|
|
36
|
+
let count = 1;
|
|
37
|
+
let multiplicativeSeen = false;
|
|
38
|
+
for (const category of active) {
|
|
39
|
+
const n = selected[category.id].length;
|
|
40
|
+
if (variantCategoryMode(category, forceMode) === 'multiplicative') {
|
|
41
|
+
multiplicativeSeen = true;
|
|
42
|
+
count *= n;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Only-additive selections produce a single stacked combination, not zero.
|
|
46
|
+
return multiplicativeSeen ? count : 1;
|
|
47
|
+
}
|
|
48
|
+
/** Cartesian product of arrays (vid-gen's helper, verbatim semantics). */
|
|
49
|
+
function cartesian(...arrays) {
|
|
50
|
+
return arrays.reduce((acc, array) => acc.flatMap((x) => array.map((y) => [...x, y])), [[]]);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Generate all combinations from the current selection.
|
|
54
|
+
*
|
|
55
|
+
* Mirrors vid-gen's `generateCombinations(selectedModifiers, options)`:
|
|
56
|
+
* - categories with nothing selected are skipped entirely (all-empty → []);
|
|
57
|
+
* - multiplicative categories contribute one option per combination via
|
|
58
|
+
* cartesian product; additive selections stack flat onto every combination;
|
|
59
|
+
* - with no multiplicative selections at all, a single additive-only
|
|
60
|
+
* combination is produced.
|
|
61
|
+
*/
|
|
62
|
+
export function generateCombinations(categories, selected, options = {}) {
|
|
63
|
+
const { forceMode = null } = options;
|
|
64
|
+
const active = categories.filter((c) => (selected[c.id]?.length ?? 0) > 0);
|
|
65
|
+
if (active.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
const multiplicativeArrays = active
|
|
68
|
+
.filter((c) => variantCategoryMode(c, forceMode) === 'multiplicative')
|
|
69
|
+
.map((c) => selected[c.id].map((optionId) => ({ categoryId: c.id, optionId })));
|
|
70
|
+
const additivePicks = active
|
|
71
|
+
.filter((c) => variantCategoryMode(c, forceMode) === 'additive')
|
|
72
|
+
.flatMap((c) => selected[c.id].map((optionId) => ({ categoryId: c.id, optionId })));
|
|
73
|
+
const multiplicativeCombos = cartesian(...multiplicativeArrays);
|
|
74
|
+
const combos = multiplicativeArrays.length
|
|
75
|
+
? multiplicativeCombos.map((combo) => [...combo, ...additivePicks])
|
|
76
|
+
: [additivePicks];
|
|
77
|
+
return combos.map((combo) => {
|
|
78
|
+
const resolved = combo
|
|
79
|
+
.map(({ categoryId, optionId }) => findVariantOption(categories, categoryId, optionId))
|
|
80
|
+
.filter((o) => o !== undefined);
|
|
81
|
+
return {
|
|
82
|
+
modifierIds: combo.map(({ optionId }) => optionId),
|
|
83
|
+
prompt: resolved
|
|
84
|
+
.map((o) => o.prompt)
|
|
85
|
+
.filter((p) => p !== undefined)
|
|
86
|
+
.join(', '),
|
|
87
|
+
options: resolved
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Build a variant filename from an original filename and modifier ids
|
|
93
|
+
* (vid-gen's `generateVariantFilename`, generic — no preset knowledge):
|
|
94
|
+
* `photo.png` + ['a', 'b'] → `photo_a_b.png`, ids sorted for consistency.
|
|
95
|
+
*/
|
|
96
|
+
export function generateVariantFilename(originalFilename, modifierIds) {
|
|
97
|
+
const stem = originalFilename.replace(/\.[^/.]+$/, '');
|
|
98
|
+
const suffix = [...modifierIds].sort().join('_');
|
|
99
|
+
return suffix ? `${stem}_${suffix}.png` : `${stem}.png`;
|
|
100
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export { collapse } from './actions/collapse';
|
|
|
6
6
|
export type { CollapseOptions } from './actions/collapse';
|
|
7
7
|
export { default as Collapse } from './components/Collapse.svelte';
|
|
8
8
|
export { default as LinkedColumns } from './components/linked-columns/LinkedColumns.svelte';
|
|
9
|
-
export type { ColumnLink } from './components/linked-columns/
|
|
9
|
+
export type { ColumnLink } from './components/linked-columns/types.js';
|
|
10
10
|
export { default as ChapterTimeline } from './components/replay/ChapterTimeline.svelte';
|
|
11
|
-
export type { ChapterBlock } from './components/replay/ChapterTimeline.svelte';
|
|
11
|
+
export type { ChapterBlock, ChapterStateVisual } from './components/replay/ChapterTimeline.svelte';
|
|
12
12
|
export { default as TranscriptPlayer } from './components/TranscriptPlayer.svelte';
|
|
13
13
|
export type { TranscriptSegment, TranscriptBookmark, TranscriptChapter, TranscriptSpeakerTalkTime, } from './components/TranscriptPlayer.svelte';
|
|
14
14
|
export { default as VideoPlayer } from './components/VideoPlayer.svelte';
|
|
@@ -56,6 +56,10 @@ export { createDirtyGuard } from './utils/dirtyGuard';
|
|
|
56
56
|
export type { DirtyGuard, DirtyGuardOptions, BeforeNavigateFn } from './utils/dirtyGuard';
|
|
57
57
|
export { default as MediaLightbox } from './components/MediaLightbox.svelte';
|
|
58
58
|
export type { MediaItem } from './components/MediaLightbox.svelte';
|
|
59
|
+
export { default as InfiniteGrid } from './components/InfiniteGrid.svelte';
|
|
60
|
+
export { default as InfiniteSearchGrid } from './components/InfiniteSearchGrid.svelte';
|
|
61
|
+
export { createInfiniteLoader } from './components/infiniteGridLoader';
|
|
62
|
+
export type { InfinitePage, InfiniteLoadContext, InfiniteLoadFn, InfiniteLoader, InfiniteLoaderState, InfiniteStatus } from './components/infiniteGridLoader';
|
|
59
63
|
export { default as Button } from './components/Button.svelte';
|
|
60
64
|
export { default as Badge } from './components/Badge.svelte';
|
|
61
65
|
export { default as Card } from './components/Card.svelte';
|
|
@@ -78,6 +82,10 @@ export { default as LazyImage } from './components/LazyImage.svelte';
|
|
|
78
82
|
export { default as ResizablePanel } from './components/ResizablePanel.svelte';
|
|
79
83
|
export { default as VoicePlayer } from './components/VoicePlayer.svelte';
|
|
80
84
|
export { default as SpeechForm } from './components/SpeechForm.svelte';
|
|
85
|
+
export { default as AudioRecorder } from './components/AudioRecorder.svelte';
|
|
86
|
+
export type { AudioRecordingResult } from './utils/audioRecorderCore';
|
|
87
|
+
export { createAudioRecorder } from './utils/audioRecorder';
|
|
88
|
+
export type { AudioRecorder, AudioRecorderCore, AudioRecorderError, AudioRecorderErrorKind, AudioRecorderFrame, AudioRecorderMode, AudioRecorderOptions, AudioRecorderPhase, AudioRecorderSnapshot } from './utils/audioRecorderCore';
|
|
81
89
|
export { default as ThemeSelector } from './components/ThemeSelector.svelte';
|
|
82
90
|
export { default as Sparkline } from './components/Sparkline.svelte';
|
|
83
91
|
export { default as BurndownChart } from './components/BurndownChart.svelte';
|
|
@@ -93,6 +101,8 @@ export type { FileDropzoneFile } from './components/FileDropzone.svelte';
|
|
|
93
101
|
export { default as VariablePicker } from './components/VariablePicker.svelte';
|
|
94
102
|
export type { TemplateVar, TemplateVarGroup } from './types/templateVars';
|
|
95
103
|
export { default as EmojiPicker } from './components/EmojiPicker.svelte';
|
|
104
|
+
export { default as IconSelector } from './components/IconSelector.svelte';
|
|
105
|
+
export type { IconSelectorOption, IconComponentProps } from './components/IconSelector.svelte';
|
|
96
106
|
export { EMOJI_DATA, ALL_EMOJIS, searchEmojis } from './data/emojis';
|
|
97
107
|
export type { EmojiEntry, EmojiGroup } from './data/emojis';
|
|
98
108
|
export { default as LinkShortener } from './components/LinkShortener.svelte';
|
|
@@ -120,7 +130,7 @@ export type { Milestone, MilestoneStatus } from './types/milestone';
|
|
|
120
130
|
export type { LocationType, BookingStatus, OverrideType, Host, EventType, WeeklyAvailability, DateOverride, Booking, BookingAttendee, TimeSlot, BookingFormData, AvailabilityCounts } from './types/booking';
|
|
121
131
|
export { DAYS_OF_WEEK, DAYS_SHORT, LOCATION_LABELS, LOCATION_ICONS } from './types/booking';
|
|
122
132
|
export type { ImageVariantSpec, ImageProcessingSpec, VariantResult, VariantState, } from './types/smartImageEditor';
|
|
123
|
-
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, type PacingLevel, type PacingResult, } from './utils/dateFormatters';
|
|
133
|
+
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, formatPacingDuration, type PacingLevel, type PacingResult, type PacingOptions, } from './utils/dateFormatters';
|
|
124
134
|
export { statusColor, priorityColor, typeIcon, statusLabel, } from './utils/taskUtils';
|
|
125
135
|
export { stripPhoneNumber, formatPhoneNumber, isCompletePhoneNumber, isValidPhoneNumber, updatePhoneInput } from './utils/phoneFormat';
|
|
126
136
|
export { toE164, formatPhoneForDisplay, isValidPhone, listCountries, DEFAULT_COUNTRY, PRIORITY_COUNTRIES, type CountryOption, } from './utils/phone';
|
|
@@ -166,6 +176,8 @@ export type { MarkupTool, Point, MarkupShape, ArrowShape, RectangleShape, Ellips
|
|
|
166
176
|
export type { Annotation, AnnotationProfile, AnnotationThread, AnnotationCallbacks, } from './types/annotation';
|
|
167
177
|
export { default as KeyboardShortcutsOverlay } from './components/KeyboardShortcutsOverlay.svelte';
|
|
168
178
|
export type { KeyboardShortcut, SectionEntry as KeyboardShortcutSectionEntry, ShortcutSection as KeyboardShortcutSection, } from './components/KeyboardShortcutsOverlay.svelte';
|
|
179
|
+
export { createShortcutRegistry, getShortcutRegistry, formatShortcut, parseCombo as parseShortcutCombo, isTypingTarget, detectPlatform as detectShortcutPlatform, SIDEBAR_TOGGLE_KEY, } from './utils/keyboardShortcutRegistry';
|
|
180
|
+
export type { ShortcutRegistry, ShortcutDefinition, ShortcutModifier, ShortcutPlatform, PushContextOptions as ShortcutContextOptions, RegistrySection as ShortcutRegistrySection, ToSectionsOptions as ShortcutSectionsOptions, ShortcutRegistryOptions, ShortcutEventTarget, } from './utils/keyboardShortcutRegistry';
|
|
169
181
|
export { default as MapView } from './components/MapView.svelte';
|
|
170
182
|
export { default as LocationMap } from './components/LocationMap.svelte';
|
|
171
183
|
export { default as GPSTracker } from './components/GPSTracker.svelte';
|
|
@@ -177,6 +189,10 @@ export { staggerEntrance } from './actions/staggerEntrance';
|
|
|
177
189
|
export type { StaggerEntranceOptions } from './actions/staggerEntrance';
|
|
178
190
|
export { attention } from './actions/attention';
|
|
179
191
|
export type { AttentionEffect, AttentionOptions } from './actions/attention';
|
|
192
|
+
export { reveal, REVEAL_HIDDEN_CLASS, REVEAL_BASE_CLASS } from './actions/reveal';
|
|
193
|
+
export type { RevealOptions, RevealVariant } from './actions/reveal';
|
|
194
|
+
export { default as ThumbnailGrid } from './components/ThumbnailGrid.svelte';
|
|
195
|
+
export type { ThumbnailItem } from './components/ThumbnailGrid.svelte';
|
|
180
196
|
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
181
197
|
export type { FloatingOptions, Placement } from './actions/floating';
|
|
182
198
|
export { glide } from './transitions/glide';
|
|
@@ -184,6 +200,7 @@ export type { GlideOrigin, GlideParams } from './transitions/glide';
|
|
|
184
200
|
export { themeWipe } from './utils/themeWipe';
|
|
185
201
|
export { viewTransition } from './utils/viewTransition';
|
|
186
202
|
export { play as playSound, registerSound, isSoundEnabled, setSoundEnabled } from './utils/sound';
|
|
203
|
+
export { copyText, readClipboardText } from './utils/clipboard';
|
|
187
204
|
export { splitText } from './utils/splitText';
|
|
188
205
|
export type { SplitBy, SplitTextOptions, SplitTextResult } from './utils/splitText';
|
|
189
206
|
export { default as ToastHost } from './components/toast/ToastHost.svelte';
|
|
@@ -227,3 +244,17 @@ export { default as Slider } from './components/basic/Slider.svelte';
|
|
|
227
244
|
export { default as Pagination } from './components/basic/Pagination.svelte';
|
|
228
245
|
export { MAX_UNDO_DEPTH, createHistory, pushState, beginChange, endChange, untracked, undo, redo, clearHistory } from './history';
|
|
229
246
|
export type { History } from './history';
|
|
247
|
+
export { default as BatchJobTable } from './components/batch/BatchJobTable.svelte';
|
|
248
|
+
export type { JobContext, RowControls, BatchControls, BatchPhase } from './components/batch/BatchJobTable.svelte';
|
|
249
|
+
export { default as QuotaMeter } from './components/batch/QuotaMeter.svelte';
|
|
250
|
+
export { toJobRows, nextJobsToStart, isProcessLimitReached, moveJob, summarizeJobs, formatElapsed } from './components/batch/batchQueue';
|
|
251
|
+
export type { JobRow, JobStatus, BatchSummary, DispatchLimits } from './components/batch/batchQueue';
|
|
252
|
+
export { rollingAverage, estimateRemainingMs } from './components/batch/elapsedEstimate';
|
|
253
|
+
export type { EtaInput } from './components/batch/elapsedEstimate';
|
|
254
|
+
export { useElapsedEstimate } from './components/batch/useElapsedEstimate';
|
|
255
|
+
export type { ElapsedEstimate } from './components/batch/useElapsedEstimate';
|
|
256
|
+
export { pollOperation, PollTimeoutError } from './components/batch/pollOperation';
|
|
257
|
+
export type { PollStep, PollContext, PollOptions } from './components/batch/pollOperation';
|
|
258
|
+
export { default as VariantMatrixPicker } from './components/variant/VariantMatrixPicker.svelte';
|
|
259
|
+
export { countCombinations, generateCombinations, generateVariantFilename, findVariantOption, variantCategoryMode } from './components/variant/variantCombinations';
|
|
260
|
+
export type { VariantCategory, VariantOption, VariantSelection, VariantSelectionMode, VariantCombination } from './components/variant/variantCombinations';
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,10 @@ export { default as PresenceStack } from './components/PresenceStack.svelte';
|
|
|
73
73
|
export { default as DirtyFormHost } from './components/DirtyFormHost.svelte';
|
|
74
74
|
export { createDirtyGuard } from './utils/dirtyGuard';
|
|
75
75
|
export { default as MediaLightbox } from './components/MediaLightbox.svelte';
|
|
76
|
+
// Cursor-paged infinite-scroll grids, harvested from chimaro (jatui-m4uz3.4).
|
|
77
|
+
export { default as InfiniteGrid } from './components/InfiniteGrid.svelte';
|
|
78
|
+
export { default as InfiniteSearchGrid } from './components/InfiniteSearchGrid.svelte';
|
|
79
|
+
export { createInfiniteLoader } from './components/infiniteGridLoader';
|
|
76
80
|
// Components — from Flush
|
|
77
81
|
export { default as Button } from './components/Button.svelte';
|
|
78
82
|
export { default as Badge } from './components/Badge.svelte';
|
|
@@ -97,6 +101,9 @@ export { default as LazyImage } from './components/LazyImage.svelte';
|
|
|
97
101
|
export { default as ResizablePanel } from './components/ResizablePanel.svelte';
|
|
98
102
|
export { default as VoicePlayer } from './components/VoicePlayer.svelte';
|
|
99
103
|
export { default as SpeechForm } from './components/SpeechForm.svelte';
|
|
104
|
+
export { default as AudioRecorder } from './components/AudioRecorder.svelte';
|
|
105
|
+
// Headless audio capture — the factory behind AudioRecorder (jatui-is2ow.8)
|
|
106
|
+
export { createAudioRecorder } from './utils/audioRecorder';
|
|
100
107
|
// Components — from Headcount
|
|
101
108
|
export { default as ThemeSelector } from './components/ThemeSelector.svelte';
|
|
102
109
|
export { default as Sparkline } from './components/Sparkline.svelte';
|
|
@@ -112,6 +119,8 @@ export { default as EntityPreviewCard } from './components/EntityPreviewCard.sve
|
|
|
112
119
|
export { default as VariablePicker } from './components/VariablePicker.svelte';
|
|
113
120
|
// Components — Emoji
|
|
114
121
|
export { default as EmojiPicker } from './components/EmojiPicker.svelte';
|
|
122
|
+
// Components — Icon selection
|
|
123
|
+
export { default as IconSelector } from './components/IconSelector.svelte';
|
|
115
124
|
// Emoji data
|
|
116
125
|
export { EMOJI_DATA, ALL_EMOJIS, searchEmojis } from './data/emojis';
|
|
117
126
|
// Components — from Meadow
|
|
@@ -130,7 +139,7 @@ export { default as AvailabilityModal } from './components/AvailabilityModal.sve
|
|
|
130
139
|
export { default as BookingForm } from './components/BookingForm.svelte';
|
|
131
140
|
export { DAYS_OF_WEEK, DAYS_SHORT, LOCATION_LABELS, LOCATION_ICONS } from './types/booking';
|
|
132
141
|
// Utilities — date formatting
|
|
133
|
-
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, } from './utils/dateFormatters';
|
|
142
|
+
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, formatPacingDuration, } from './utils/dateFormatters';
|
|
134
143
|
// Utilities — task display helpers
|
|
135
144
|
export { statusColor, priorityColor, typeIcon, statusLabel, } from './utils/taskUtils';
|
|
136
145
|
// Utilities — phone formatting (legacy US-only)
|
|
@@ -183,6 +192,7 @@ export { default as AnnotationPanel } from './components/AnnotationPanel.svelte'
|
|
|
183
192
|
export { MARKUP_COLORS, DEFAULT_STROKE_WIDTH, renderShape, renderAllShapes, nextShapeId, } from './components/markup';
|
|
184
193
|
// Components — Keyboard Navigation
|
|
185
194
|
export { default as KeyboardShortcutsOverlay } from './components/KeyboardShortcutsOverlay.svelte';
|
|
195
|
+
export { createShortcutRegistry, getShortcutRegistry, formatShortcut, parseCombo as parseShortcutCombo, isTypingTarget, detectPlatform as detectShortcutPlatform, SIDEBAR_TOGGLE_KEY, } from './utils/keyboardShortcutRegistry';
|
|
186
196
|
// Components — Google Maps (DispatchMap fork + location primitives)
|
|
187
197
|
export { default as MapView } from './components/MapView.svelte';
|
|
188
198
|
export { default as LocationMap } from './components/LocationMap.svelte';
|
|
@@ -202,6 +212,13 @@ export { loadGoogleMapsAPI, isGoogleMapsLoaded, isPlacesLoaded, isGeometryLoaded
|
|
|
202
212
|
export { tooltip } from './actions/tooltip';
|
|
203
213
|
export { staggerEntrance } from './actions/staggerEntrance';
|
|
204
214
|
export { attention } from './actions/attention';
|
|
215
|
+
// Scroll-reveal (jatui-m4uz3.3, chimaro port): IntersectionObserver
|
|
216
|
+
// scroll-reveal whose variants live in styles/motion.css as jatui-reveal-*
|
|
217
|
+
// classes on the --motion-* tokens — no shipped animista.css.
|
|
218
|
+
export { reveal, REVEAL_HIDDEN_CLASS, REVEAL_BASE_CLASS } from './actions/reveal';
|
|
219
|
+
// Thumbnail grid (jatui-m4uz3.3, chimaro port): generic {id,url,alt} strip
|
|
220
|
+
// with overflow counter, remove/add affordances and a cell snippet override.
|
|
221
|
+
export { default as ThumbnailGrid } from './components/ThumbnailGrid.svelte';
|
|
205
222
|
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
206
223
|
export { glide } from './transitions/glide';
|
|
207
224
|
// View Transitions kit
|
|
@@ -209,6 +226,8 @@ export { themeWipe } from './utils/themeWipe';
|
|
|
209
226
|
export { viewTransition } from './utils/viewTransition';
|
|
210
227
|
// Sound kit (functional feedback, opt-in)
|
|
211
228
|
export { play as playSound, registerSound, isSoundEnabled, setSoundEnabled } from './utils/sound';
|
|
229
|
+
// Clipboard (secure-context aware: execCommand fallback for plain-HTTP origins)
|
|
230
|
+
export { copyText, readClipboardText } from './utils/clipboard';
|
|
212
231
|
// Text utilities
|
|
213
232
|
export { splitText } from './utils/splitText';
|
|
214
233
|
// Toast system
|
|
@@ -262,3 +281,13 @@ export { default as Slider } from './components/basic/Slider.svelte';
|
|
|
262
281
|
export { default as Pagination } from './components/basic/Pagination.svelte';
|
|
263
282
|
// Snapshot undo/redo history (wayflow-core) — also importable as 'jatui/history' (jatui-00jfh).
|
|
264
283
|
export { MAX_UNDO_DEPTH, createHistory, pushState, beginChange, endChange, untracked, undo, redo, clearHistory } from './history';
|
|
284
|
+
// Batch queue runner (harvested from vid-gen BatchGenerator — jatui-m4uz3.7).
|
|
285
|
+
export { default as BatchJobTable } from './components/batch/BatchJobTable.svelte';
|
|
286
|
+
export { default as QuotaMeter } from './components/batch/QuotaMeter.svelte';
|
|
287
|
+
export { toJobRows, nextJobsToStart, isProcessLimitReached, moveJob, summarizeJobs, formatElapsed } from './components/batch/batchQueue';
|
|
288
|
+
export { rollingAverage, estimateRemainingMs } from './components/batch/elapsedEstimate';
|
|
289
|
+
export { useElapsedEstimate } from './components/batch/useElapsedEstimate';
|
|
290
|
+
export { pollOperation, PollTimeoutError } from './components/batch/pollOperation';
|
|
291
|
+
// Variant matrix picker + combination algebra (harvested from vid-gen FrameVariantGenerator — jatui-m4uz3.8).
|
|
292
|
+
export { default as VariantMatrixPicker } from './components/variant/VariantMatrixPicker.svelte';
|
|
293
|
+
export { countCombinations, generateCombinations, generateVariantFilename, findVariantOption, variantCategoryMode } from './components/variant/variantCombinations';
|