@aicut/core 0.5.0 → 0.6.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/README.md +66 -0
- package/dist/chunk-H6AY6NW4.js +123 -0
- package/dist/chunk-H6AY6NW4.js.map +1 -0
- package/dist/chunk-WTCK3XQ6.js +93 -0
- package/dist/chunk-WTCK3XQ6.js.map +1 -0
- package/dist/{i18n-B-DFWgKe.d.cts → i18n-B24k4XVG.d.cts} +34 -1
- package/dist/{i18n-B-DFWgKe.d.ts → i18n-B24k4XVG.d.ts} +34 -1
- package/dist/index.cjs +1917 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +348 -25
- package/dist/index.d.ts +348 -25
- package/dist/index.js +1779 -86
- package/dist/index.js.map +1 -1
- package/dist/lighting/index.cjs +24 -6
- package/dist/lighting/index.cjs.map +1 -1
- package/dist/lighting/index.d.cts +2 -2
- package/dist/lighting/index.d.ts +2 -2
- package/dist/lighting/index.js +1 -1
- package/dist/playback/webcodecs/index.cjs +113 -6
- package/dist/playback/webcodecs/index.cjs.map +1 -1
- package/dist/playback/webcodecs/index.d.cts +18 -2
- package/dist/playback/webcodecs/index.d.ts +18 -2
- package/dist/playback/webcodecs/index.js +46 -6
- package/dist/playback/webcodecs/index.js.map +1 -1
- package/dist/{types-DvKlxylu.d.cts → types-BbZjOQLz.d.ts} +34 -1
- package/dist/{types-rwZx6FxE.d.ts → types-CjvRUPtZ.d.cts} +34 -1
- package/dist/types-CmS-UIEr.d.cts +137 -0
- package/dist/types-CmS-UIEr.d.ts +137 -0
- package/package.json +1 -1
- package/styles/theme.css +351 -0
- package/dist/chunk-CCDON7CU.js +0 -87
- package/dist/chunk-CCDON7CU.js.map +0 -1
- package/dist/types-CHplD9V5.d.cts +0 -70
- package/dist/types-CHplD9V5.d.ts +0 -70
package/styles/theme.css
CHANGED
|
@@ -99,6 +99,357 @@
|
|
|
99
99
|
min-height: 220px;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/* Keyframe transform panel — floats on the preview's top-left when
|
|
103
|
+
keyframe mode is on AND a keyframe is selected. Adapts to the
|
|
104
|
+
editor theme via the same `--aicut-controls-*` tokens the rest of
|
|
105
|
+
the chrome uses, so dark / light / custom themes get a coherent
|
|
106
|
+
look without a separate "floating panel" palette. */
|
|
107
|
+
.aicut-keyframe-panel {
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 12px;
|
|
110
|
+
left: 12px;
|
|
111
|
+
z-index: 4;
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: 8px;
|
|
115
|
+
min-width: 188px;
|
|
116
|
+
padding: 12px 14px 10px;
|
|
117
|
+
border-radius: 10px;
|
|
118
|
+
background: var(--aicut-controls-bg, #1f1f22);
|
|
119
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.85));
|
|
120
|
+
font: 12px system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
121
|
+
border: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.08));
|
|
122
|
+
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.aicut-keyframe-panel__title {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: baseline;
|
|
128
|
+
justify-content: space-between;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
font-size: 11px;
|
|
131
|
+
letter-spacing: 0.04em;
|
|
132
|
+
text-transform: uppercase;
|
|
133
|
+
/* Slightly muted variant of controls-text — same hue, less weight. */
|
|
134
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.85));
|
|
135
|
+
opacity: 0.75;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.aicut-keyframe-panel__time {
|
|
139
|
+
font: 10px ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
140
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.85));
|
|
141
|
+
opacity: 0.55;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.aicut-keyframe-panel__row {
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: 8px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.aicut-keyframe-panel__row label {
|
|
151
|
+
flex: 0 0 44px;
|
|
152
|
+
font-size: 11px;
|
|
153
|
+
letter-spacing: 0.02em;
|
|
154
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.85));
|
|
155
|
+
opacity: 0.7;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.aicut-keyframe-panel__row input {
|
|
159
|
+
flex: 1;
|
|
160
|
+
width: 84px;
|
|
161
|
+
min-width: 0;
|
|
162
|
+
padding: 5px 8px;
|
|
163
|
+
font: 12px ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
164
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.92));
|
|
165
|
+
background: var(--aicut-controls-hover, rgba(255, 255, 255, 0.06));
|
|
166
|
+
border: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.12));
|
|
167
|
+
border-radius: 6px;
|
|
168
|
+
-moz-appearance: textfield;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.aicut-keyframe-panel__row input::-webkit-outer-spin-button,
|
|
172
|
+
.aicut-keyframe-panel__row input::-webkit-inner-spin-button {
|
|
173
|
+
-webkit-appearance: none;
|
|
174
|
+
margin: 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.aicut-keyframe-panel__row input:hover {
|
|
178
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.aicut-keyframe-panel__row input:focus {
|
|
182
|
+
outline: none;
|
|
183
|
+
border-color: var(--color-brand, #ff3386);
|
|
184
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
185
|
+
box-shadow: 0 0 0 2px rgba(255, 51, 134, 0.22);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Small dot to the right of each input — filled = this prop pins
|
|
189
|
+
THIS moment, outlined = doesn't (display shows the interpolated
|
|
190
|
+
value; editing will create a kf at this time). */
|
|
191
|
+
.aicut-keyframe-panel__badge {
|
|
192
|
+
display: inline-block;
|
|
193
|
+
width: 8px;
|
|
194
|
+
height: 8px;
|
|
195
|
+
margin-left: 2px;
|
|
196
|
+
border-radius: 50%;
|
|
197
|
+
border: 1.5px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.36));
|
|
198
|
+
background: transparent;
|
|
199
|
+
flex: 0 0 8px;
|
|
200
|
+
transition:
|
|
201
|
+
background-color 100ms ease-out,
|
|
202
|
+
border-color 100ms ease-out;
|
|
203
|
+
}
|
|
204
|
+
.aicut-keyframe-panel__badge--on {
|
|
205
|
+
background: var(--color-brand, #ff3386);
|
|
206
|
+
border-color: var(--color-brand, #ff3386);
|
|
207
|
+
box-shadow: 0 0 6px rgba(255, 51, 134, 0.5);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* Custom easing dropdown — themed to match the rest of the panel.
|
|
211
|
+
Trigger acts like a button, the floating menu is brand-aware and
|
|
212
|
+
uses a subtle gradient + box-shadow for elevation. */
|
|
213
|
+
.aicut-keyframe-panel__dropdown {
|
|
214
|
+
flex: 1;
|
|
215
|
+
position: relative;
|
|
216
|
+
min-width: 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.aicut-keyframe-panel__dropdown-trigger {
|
|
220
|
+
appearance: none;
|
|
221
|
+
display: inline-flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: space-between;
|
|
224
|
+
gap: 8px;
|
|
225
|
+
width: 100%;
|
|
226
|
+
padding: 5px 8px 5px 10px;
|
|
227
|
+
font: 12px ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
228
|
+
text-align: left;
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.92));
|
|
231
|
+
background: var(--aicut-controls-hover, rgba(255, 255, 255, 0.06));
|
|
232
|
+
border: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.12));
|
|
233
|
+
border-radius: 6px;
|
|
234
|
+
transition:
|
|
235
|
+
border-color 120ms ease-out,
|
|
236
|
+
background-color 120ms ease-out,
|
|
237
|
+
box-shadow 120ms ease-out;
|
|
238
|
+
}
|
|
239
|
+
.aicut-keyframe-panel__dropdown-trigger:hover {
|
|
240
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
241
|
+
border-color: var(--color-brand, #ff3386);
|
|
242
|
+
}
|
|
243
|
+
.aicut-keyframe-panel__dropdown-trigger:focus-visible {
|
|
244
|
+
outline: none;
|
|
245
|
+
border-color: var(--color-brand, #ff3386);
|
|
246
|
+
box-shadow: 0 0 0 2px rgba(255, 51, 134, 0.22);
|
|
247
|
+
}
|
|
248
|
+
.aicut-keyframe-panel__dropdown-trigger--open {
|
|
249
|
+
border-color: var(--color-brand, #ff3386);
|
|
250
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
251
|
+
box-shadow: 0 0 0 2px rgba(255, 51, 134, 0.22);
|
|
252
|
+
}
|
|
253
|
+
.aicut-keyframe-panel__dropdown-trigger--disabled,
|
|
254
|
+
.aicut-keyframe-panel__dropdown-trigger:disabled {
|
|
255
|
+
opacity: 0.45;
|
|
256
|
+
cursor: not-allowed;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.aicut-keyframe-panel__dropdown-trigger-label {
|
|
260
|
+
flex: 1;
|
|
261
|
+
min-width: 0;
|
|
262
|
+
overflow: hidden;
|
|
263
|
+
text-overflow: ellipsis;
|
|
264
|
+
white-space: nowrap;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* Chevron — pure CSS triangle, rotates when the menu opens. */
|
|
268
|
+
.aicut-keyframe-panel__dropdown-chevron {
|
|
269
|
+
flex: 0 0 6px;
|
|
270
|
+
width: 0;
|
|
271
|
+
height: 0;
|
|
272
|
+
border-left: 4px solid transparent;
|
|
273
|
+
border-right: 4px solid transparent;
|
|
274
|
+
border-top: 5px solid currentColor;
|
|
275
|
+
opacity: 0.75;
|
|
276
|
+
transition:
|
|
277
|
+
transform 140ms ease-out,
|
|
278
|
+
opacity 120ms ease-out;
|
|
279
|
+
transform-origin: 50% 35%;
|
|
280
|
+
}
|
|
281
|
+
.aicut-keyframe-panel__dropdown-trigger--open
|
|
282
|
+
.aicut-keyframe-panel__dropdown-chevron {
|
|
283
|
+
transform: rotate(180deg);
|
|
284
|
+
opacity: 1;
|
|
285
|
+
color: var(--color-brand, #ff3386);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* Floating menu. Positioned right under the trigger; the panel
|
|
289
|
+
uses `position: relative` on `.dropdown` so absolute-positioning
|
|
290
|
+
here means "anchored to the trigger". */
|
|
291
|
+
.aicut-keyframe-panel__dropdown-menu {
|
|
292
|
+
position: absolute;
|
|
293
|
+
top: calc(100% + 4px);
|
|
294
|
+
left: 0;
|
|
295
|
+
right: 0;
|
|
296
|
+
z-index: 50;
|
|
297
|
+
margin: 0;
|
|
298
|
+
padding: 4px;
|
|
299
|
+
list-style: none;
|
|
300
|
+
background: var(--aicut-controls-bg, rgba(20, 20, 22, 0.96));
|
|
301
|
+
border: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.12));
|
|
302
|
+
border-radius: 8px;
|
|
303
|
+
box-shadow:
|
|
304
|
+
0 8px 24px rgba(0, 0, 0, 0.32),
|
|
305
|
+
0 0 0 1px rgba(255, 51, 134, 0.06);
|
|
306
|
+
backdrop-filter: blur(8px);
|
|
307
|
+
animation: aicut-keyframe-dropdown-in 120ms ease-out;
|
|
308
|
+
}
|
|
309
|
+
@keyframes aicut-keyframe-dropdown-in {
|
|
310
|
+
from {
|
|
311
|
+
opacity: 0;
|
|
312
|
+
transform: translateY(-4px);
|
|
313
|
+
}
|
|
314
|
+
to {
|
|
315
|
+
opacity: 1;
|
|
316
|
+
transform: translateY(0);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.aicut-keyframe-panel__dropdown-item {
|
|
321
|
+
display: flex;
|
|
322
|
+
align-items: center;
|
|
323
|
+
gap: 8px;
|
|
324
|
+
padding: 7px 10px 7px 26px;
|
|
325
|
+
position: relative;
|
|
326
|
+
font: 12px ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
327
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.92));
|
|
328
|
+
border-radius: 5px;
|
|
329
|
+
cursor: pointer;
|
|
330
|
+
user-select: none;
|
|
331
|
+
outline: none;
|
|
332
|
+
transition: background-color 80ms ease-out;
|
|
333
|
+
}
|
|
334
|
+
.aicut-keyframe-panel__dropdown-item:hover,
|
|
335
|
+
.aicut-keyframe-panel__dropdown-item:focus {
|
|
336
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
337
|
+
}
|
|
338
|
+
.aicut-keyframe-panel__dropdown-item--selected {
|
|
339
|
+
color: var(--color-brand, #ff3386);
|
|
340
|
+
}
|
|
341
|
+
/* Checkmark for the selected item — drawn with two CSS borders. */
|
|
342
|
+
.aicut-keyframe-panel__dropdown-item--selected::before {
|
|
343
|
+
content: "";
|
|
344
|
+
position: absolute;
|
|
345
|
+
left: 10px;
|
|
346
|
+
top: 50%;
|
|
347
|
+
width: 4px;
|
|
348
|
+
height: 8px;
|
|
349
|
+
margin-top: -5px;
|
|
350
|
+
border-right: 2px solid currentColor;
|
|
351
|
+
border-bottom: 2px solid currentColor;
|
|
352
|
+
transform: rotate(45deg);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.aicut-keyframe-panel__actions {
|
|
356
|
+
display: flex;
|
|
357
|
+
gap: 6px;
|
|
358
|
+
margin-top: 4px;
|
|
359
|
+
padding-top: 8px;
|
|
360
|
+
border-top: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.08));
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.aicut-keyframe-panel__reset {
|
|
364
|
+
flex: 1;
|
|
365
|
+
padding: 6px 10px;
|
|
366
|
+
font-size: 11px;
|
|
367
|
+
font-weight: 500;
|
|
368
|
+
letter-spacing: 0.02em;
|
|
369
|
+
color: var(--aicut-controls-text, rgba(255, 255, 255, 0.85));
|
|
370
|
+
background: var(--aicut-controls-hover, rgba(255, 255, 255, 0.06));
|
|
371
|
+
border: 1px solid var(--aicut-controls-border, rgba(255, 255, 255, 0.14));
|
|
372
|
+
border-radius: 6px;
|
|
373
|
+
cursor: pointer;
|
|
374
|
+
transition:
|
|
375
|
+
background-color 80ms ease-out,
|
|
376
|
+
border-color 80ms ease-out,
|
|
377
|
+
color 80ms ease-out;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.aicut-keyframe-panel__reset:hover:not(:disabled) {
|
|
381
|
+
background: var(--aicut-controls-active, rgba(255, 255, 255, 0.1));
|
|
382
|
+
border-color: var(--color-brand, #ff3386);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.aicut-keyframe-panel__reset:disabled {
|
|
386
|
+
opacity: 0.35;
|
|
387
|
+
cursor: not-allowed;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/* Direct-manipulation overlay on top of the preview — frame border
|
|
391
|
+
+ corner handles. Hidden when keyframes are off (display:none from
|
|
392
|
+
the controlling class). Pointer events: the overlay itself passes
|
|
393
|
+
through; only the frame body + handles capture clicks. */
|
|
394
|
+
.aicut-keyframe-overlay {
|
|
395
|
+
position: absolute;
|
|
396
|
+
inset: 0;
|
|
397
|
+
pointer-events: none;
|
|
398
|
+
z-index: 3;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.aicut-keyframe-overlay__frame {
|
|
402
|
+
position: absolute;
|
|
403
|
+
border: 1.5px dashed var(--color-brand, #ff3386);
|
|
404
|
+
background: transparent;
|
|
405
|
+
pointer-events: auto;
|
|
406
|
+
cursor: move;
|
|
407
|
+
box-sizing: border-box;
|
|
408
|
+
transition:
|
|
409
|
+
border-color 100ms ease-out,
|
|
410
|
+
border-style 100ms ease-out,
|
|
411
|
+
box-shadow 120ms ease-out;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* Warn state — content doesn't fully cover the output frame, i.e.
|
|
415
|
+
letterbox is exposed. Strong visual distinction from the brand
|
|
416
|
+
pink: a solid 2px red border + soft red glow, so even on dark
|
|
417
|
+
themes where brand and warning hues read similar it's obvious. */
|
|
418
|
+
.aicut-keyframe-overlay__frame--warn {
|
|
419
|
+
border-style: solid;
|
|
420
|
+
border-width: 2px;
|
|
421
|
+
border-color: #ff3b30;
|
|
422
|
+
box-shadow:
|
|
423
|
+
0 0 0 1px rgba(255, 59, 48, 0.35),
|
|
424
|
+
0 0 14px rgba(255, 59, 48, 0.55);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.aicut-keyframe-overlay__handle {
|
|
428
|
+
position: absolute;
|
|
429
|
+
width: 12px;
|
|
430
|
+
height: 12px;
|
|
431
|
+
background: var(--aicut-controls-bg, #1f1f22);
|
|
432
|
+
border: 1.5px solid var(--color-brand, #ff3386);
|
|
433
|
+
border-radius: 2px;
|
|
434
|
+
pointer-events: auto;
|
|
435
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
|
436
|
+
transition: transform 80ms ease-out;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.aicut-keyframe-overlay__handle:hover {
|
|
440
|
+
transform: scale(1.3);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.aicut-keyframe-overlay__handle--tl,
|
|
444
|
+
.aicut-keyframe-overlay__handle--br {
|
|
445
|
+
cursor: nwse-resize;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.aicut-keyframe-overlay__handle--tr,
|
|
449
|
+
.aicut-keyframe-overlay__handle--bl {
|
|
450
|
+
cursor: nesw-resize;
|
|
451
|
+
}
|
|
452
|
+
|
|
102
453
|
.aicut-fullscreen-exit {
|
|
103
454
|
position: absolute;
|
|
104
455
|
top: 16px;
|
package/dist/chunk-CCDON7CU.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// src/i18n.ts
|
|
2
|
-
var localeEn = {
|
|
3
|
-
undo: "Undo",
|
|
4
|
-
redo: "Redo",
|
|
5
|
-
split: "Split",
|
|
6
|
-
trimLeft: "Trim left edge",
|
|
7
|
-
trimRight: "Trim right edge",
|
|
8
|
-
speedComingSoon: "Speed (coming soon)",
|
|
9
|
-
playPause: "Play / Pause (Space)",
|
|
10
|
-
fullscreen: "Fullscreen preview",
|
|
11
|
-
snap: "Snap",
|
|
12
|
-
snapOnTitle: "Turn off snap",
|
|
13
|
-
snapOffTitle: "Turn on snap",
|
|
14
|
-
zoomOut: "Zoom out",
|
|
15
|
-
zoomIn: "Zoom in",
|
|
16
|
-
reset: "Reset edits (keep sources)",
|
|
17
|
-
exitFullscreen: "Exit fullscreen",
|
|
18
|
-
exitFullscreenTitle: "Exit fullscreen (Esc)",
|
|
19
|
-
newTrack: "+ New track",
|
|
20
|
-
videoTrackLabel: "Video {n}",
|
|
21
|
-
audioTrackLabel: "Audio {n}"
|
|
22
|
-
};
|
|
23
|
-
var localeZh = {
|
|
24
|
-
undo: "\u64A4\u9500",
|
|
25
|
-
redo: "\u91CD\u505A",
|
|
26
|
-
split: "\u5206\u5272",
|
|
27
|
-
trimLeft: "\u5411\u5DE6\u88C1\u526A",
|
|
28
|
-
trimRight: "\u5411\u53F3\u88C1\u526A",
|
|
29
|
-
speedComingSoon: "\u53D8\u901F\uFF08\u5373\u5C06\u5230\u6765\uFF09",
|
|
30
|
-
playPause: "\u64AD\u653E / \u6682\u505C (Space)",
|
|
31
|
-
fullscreen: "\u5168\u5C4F\u9884\u89C8",
|
|
32
|
-
snap: "\u5438\u9644",
|
|
33
|
-
snapOnTitle: "\u5173\u95ED\u5438\u9644",
|
|
34
|
-
snapOffTitle: "\u5F00\u542F\u5438\u9644",
|
|
35
|
-
zoomOut: "\u7F29\u5C0F",
|
|
36
|
-
zoomIn: "\u653E\u5927",
|
|
37
|
-
reset: "\u91CD\u7F6E\u7F16\u8F91\uFF08\u4FDD\u7559\u89C6\u9891\u6E90\uFF09",
|
|
38
|
-
exitFullscreen: "\u9000\u51FA\u5168\u5C4F",
|
|
39
|
-
exitFullscreenTitle: "\u9000\u51FA\u5168\u5C4F (Esc)",
|
|
40
|
-
newTrack: "+ \u65B0\u8F68\u9053",
|
|
41
|
-
videoTrackLabel: "\u89C6\u9891 {n}",
|
|
42
|
-
audioTrackLabel: "\u97F3\u9891 {n}"
|
|
43
|
-
};
|
|
44
|
-
function mergeLocale(partial) {
|
|
45
|
-
return partial ? { ...localeEn, ...partial } : localeEn;
|
|
46
|
-
}
|
|
47
|
-
function formatLabel(template, vars) {
|
|
48
|
-
return template.replace(
|
|
49
|
-
/\{(\w+)\}/g,
|
|
50
|
-
(_, k) => k in vars ? String(vars[k]) : `{${k}}`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/theme.ts
|
|
55
|
-
var THEME_VARS = {
|
|
56
|
-
brand: "--color-brand",
|
|
57
|
-
secondary: "--color-secondary",
|
|
58
|
-
surface: "--color-surface",
|
|
59
|
-
dark: "--color-dark",
|
|
60
|
-
muted: "--color-muted",
|
|
61
|
-
card: "--color-card",
|
|
62
|
-
success: "--color-success",
|
|
63
|
-
warning: "--color-warning",
|
|
64
|
-
info: "--color-info",
|
|
65
|
-
error: "--color-error",
|
|
66
|
-
controlsBg: "--aicut-controls-bg",
|
|
67
|
-
controlsBorder: "--aicut-controls-border",
|
|
68
|
-
controlsText: "--aicut-controls-text",
|
|
69
|
-
controlsHover: "--aicut-controls-hover",
|
|
70
|
-
controlsActive: "--aicut-controls-active",
|
|
71
|
-
previewBg: "--aicut-preview-bg",
|
|
72
|
-
radiusSm: "--aicut-radius-sm",
|
|
73
|
-
radiusMd: "--aicut-radius-md",
|
|
74
|
-
radiusLg: "--aicut-radius-lg"
|
|
75
|
-
};
|
|
76
|
-
function applyTheme(root, theme) {
|
|
77
|
-
if (!theme) return;
|
|
78
|
-
for (const key of Object.keys(theme)) {
|
|
79
|
-
const cssVar = THEME_VARS[key];
|
|
80
|
-
const value = theme[key];
|
|
81
|
-
if (cssVar && value) root.style.setProperty(cssVar, value);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { applyTheme, formatLabel, localeEn, localeZh, mergeLocale };
|
|
86
|
-
//# sourceMappingURL=chunk-CCDON7CU.js.map
|
|
87
|
-
//# sourceMappingURL=chunk-CCDON7CU.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n.ts","../src/theme.ts"],"names":[],"mappings":"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","file":"chunk-CCDON7CU.js","sourcesContent":["/**\n * UI strings the editor paints into the DOM (toolbar tooltips, the\n * fullscreen exit button) and onto the timeline canvas (phantom new-\n * track label, track header labels). Every user-visible literal in\n * `@aicut/core` flows through this interface — there are no hidden\n * hard-coded translations elsewhere in the library.\n *\n * Defaults to English. Hosts that want Chinese (or any other locale)\n * pass `locale: localeZh` to `Editor.create` / `Timeline.create`, or\n * override individual keys with `locale: { undo: \"撤销\" }`.\n */\nexport interface Locale {\n // Toolbar tooltips\n undo: string;\n redo: string;\n split: string;\n trimLeft: string;\n trimRight: string;\n speedComingSoon: string;\n playPause: string;\n fullscreen: string;\n snap: string;\n /** Title shown on the snap button when snap is ON (clicking turns OFF). */\n snapOnTitle: string;\n /** Title shown when snap is OFF (clicking turns ON). */\n snapOffTitle: string;\n zoomOut: string;\n zoomIn: string;\n reset: string;\n\n // Fullscreen exit overlay\n exitFullscreen: string;\n exitFullscreenTitle: string;\n\n // Timeline canvas labels\n /** Phantom row that appears under the last track during a drag. */\n newTrack: string;\n /** Track header — `{n}` is replaced with the 1-based track index. */\n videoTrackLabel: string;\n /** Same template format as videoTrackLabel. */\n audioTrackLabel: string;\n}\n\n/** English. The library default — chosen over Chinese as the OSS norm. */\nexport const localeEn: Locale = {\n undo: \"Undo\",\n redo: \"Redo\",\n split: \"Split\",\n trimLeft: \"Trim left edge\",\n trimRight: \"Trim right edge\",\n speedComingSoon: \"Speed (coming soon)\",\n playPause: \"Play / Pause (Space)\",\n fullscreen: \"Fullscreen preview\",\n snap: \"Snap\",\n snapOnTitle: \"Turn off snap\",\n snapOffTitle: \"Turn on snap\",\n zoomOut: \"Zoom out\",\n zoomIn: \"Zoom in\",\n reset: \"Reset edits (keep sources)\",\n exitFullscreen: \"Exit fullscreen\",\n exitFullscreenTitle: \"Exit fullscreen (Esc)\",\n newTrack: \"+ New track\",\n videoTrackLabel: \"Video {n}\",\n audioTrackLabel: \"Audio {n}\",\n};\n\n/** Simplified Chinese. */\nexport const localeZh: Locale = {\n undo: \"撤销\",\n redo: \"重做\",\n split: \"分割\",\n trimLeft: \"向左裁剪\",\n trimRight: \"向右裁剪\",\n speedComingSoon: \"变速(即将到来)\",\n playPause: \"播放 / 暂停 (Space)\",\n fullscreen: \"全屏预览\",\n snap: \"吸附\",\n snapOnTitle: \"关闭吸附\",\n snapOffTitle: \"开启吸附\",\n zoomOut: \"缩小\",\n zoomIn: \"放大\",\n reset: \"重置编辑(保留视频源)\",\n exitFullscreen: \"退出全屏\",\n exitFullscreenTitle: \"退出全屏 (Esc)\",\n newTrack: \"+ 新轨道\",\n videoTrackLabel: \"视频 {n}\",\n audioTrackLabel: \"音频 {n}\",\n};\n\n/** Spread defaults under host overrides — host can supply a partial. */\nexport function mergeLocale(partial: Partial<Locale> | undefined): Locale {\n return partial ? { ...localeEn, ...partial } : localeEn;\n}\n\n/**\n * Replace `{key}` placeholders in a template. We only need `{n}`\n * substitution today; the implementation is generic so additional\n * keys (e.g. `{name}`) won't need a second pass.\n */\nexport function formatLabel(\n template: string,\n vars: Record<string, string | number>,\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (_, k) =>\n k in vars ? String(vars[k]) : `{${k}}`,\n );\n}\n","import type { Theme } from \"./types.js\";\n\n/**\n * Map `Theme` keys to the CSS custom property they write.\n *\n * Brand/palette keys share names with iqvise's globals.css so hosts\n * that already define `--color-brand` etc. at the page level get the\n * editor in their palette for free — `theme` props ONLY needed when\n * scoping to this editor instance.\n *\n * Chrome keys keep the `--aicut-controls-*` prefix because they have\n * no analogue in the host palette.\n */\nconst THEME_VARS: Record<keyof Theme, string> = {\n brand: \"--color-brand\",\n secondary: \"--color-secondary\",\n surface: \"--color-surface\",\n dark: \"--color-dark\",\n muted: \"--color-muted\",\n card: \"--color-card\",\n success: \"--color-success\",\n warning: \"--color-warning\",\n info: \"--color-info\",\n error: \"--color-error\",\n controlsBg: \"--aicut-controls-bg\",\n controlsBorder: \"--aicut-controls-border\",\n controlsText: \"--aicut-controls-text\",\n controlsHover: \"--aicut-controls-hover\",\n controlsActive: \"--aicut-controls-active\",\n previewBg: \"--aicut-preview-bg\",\n radiusSm: \"--aicut-radius-sm\",\n radiusMd: \"--aicut-radius-md\",\n radiusLg: \"--aicut-radius-lg\",\n};\n\nexport function applyTheme(root: HTMLElement, theme: Theme | undefined): void {\n if (!theme) return;\n for (const key of Object.keys(theme) as Array<keyof Theme>) {\n const cssVar = THEME_VARS[key];\n const value = theme[key];\n if (cssVar && value) root.style.setProperty(cssVar, value);\n }\n}\n"]}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Milliseconds. All timing in the project is expressed as integer ms to
|
|
3
|
-
* keep JSON serialization unambiguous (no frame-rate coupling in the
|
|
4
|
-
* data model — the renderer can present time as frames if it wants).
|
|
5
|
-
*/
|
|
6
|
-
type Ms = number;
|
|
7
|
-
interface MediaSource {
|
|
8
|
-
id: string;
|
|
9
|
-
url: string;
|
|
10
|
-
kind: "video" | "audio";
|
|
11
|
-
/** Optional — probed lazily from the <video> element if absent. */
|
|
12
|
-
duration?: Ms;
|
|
13
|
-
name?: string;
|
|
14
|
-
}
|
|
15
|
-
interface Clip {
|
|
16
|
-
id: string;
|
|
17
|
-
sourceId: string;
|
|
18
|
-
/** Window into the source — `in` inclusive, `out` exclusive. */
|
|
19
|
-
in: Ms;
|
|
20
|
-
out: Ms;
|
|
21
|
-
/** Position on the timeline. */
|
|
22
|
-
start: Ms;
|
|
23
|
-
/**
|
|
24
|
-
* Playback rate. 1 = normal, 2 = 2× speed. Default 1.
|
|
25
|
-
* Persisted in the project JSON so a host can restore exactly.
|
|
26
|
-
*/
|
|
27
|
-
speed?: number;
|
|
28
|
-
}
|
|
29
|
-
interface Track {
|
|
30
|
-
id: string;
|
|
31
|
-
kind: "video" | "audio";
|
|
32
|
-
/** Clips on this track. Must be kept sorted by `start` and non-overlapping. */
|
|
33
|
-
clips: Clip[];
|
|
34
|
-
}
|
|
35
|
-
interface Project {
|
|
36
|
-
/** Schema version — bump when breaking the JSON shape. */
|
|
37
|
-
version: 1;
|
|
38
|
-
sources: MediaSource[];
|
|
39
|
-
tracks: Track[];
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Subset of CSS variables the editor honors. Pass any custom values
|
|
43
|
-
* via `Editor` options; everything is forwarded as `--aicut-*` on the
|
|
44
|
-
* editor's root container, so a host can also override via plain CSS.
|
|
45
|
-
*/
|
|
46
|
-
interface Theme {
|
|
47
|
-
brand?: string;
|
|
48
|
-
secondary?: string;
|
|
49
|
-
surface?: string;
|
|
50
|
-
dark?: string;
|
|
51
|
-
muted?: string;
|
|
52
|
-
card?: string;
|
|
53
|
-
success?: string;
|
|
54
|
-
warning?: string;
|
|
55
|
-
info?: string;
|
|
56
|
-
error?: string;
|
|
57
|
-
/** Toolbar / ruler chrome. Background of the editor frame. */
|
|
58
|
-
controlsBg?: string;
|
|
59
|
-
controlsBorder?: string;
|
|
60
|
-
controlsText?: string;
|
|
61
|
-
controlsHover?: string;
|
|
62
|
-
controlsActive?: string;
|
|
63
|
-
/** Letterbox color around the preview video. Defaults to black. */
|
|
64
|
-
previewBg?: string;
|
|
65
|
-
radiusSm?: string;
|
|
66
|
-
radiusMd?: string;
|
|
67
|
-
radiusLg?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type { Clip as C, Ms as M, Project as P, Track as T, MediaSource as a, Theme as b };
|
package/dist/types-CHplD9V5.d.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Milliseconds. All timing in the project is expressed as integer ms to
|
|
3
|
-
* keep JSON serialization unambiguous (no frame-rate coupling in the
|
|
4
|
-
* data model — the renderer can present time as frames if it wants).
|
|
5
|
-
*/
|
|
6
|
-
type Ms = number;
|
|
7
|
-
interface MediaSource {
|
|
8
|
-
id: string;
|
|
9
|
-
url: string;
|
|
10
|
-
kind: "video" | "audio";
|
|
11
|
-
/** Optional — probed lazily from the <video> element if absent. */
|
|
12
|
-
duration?: Ms;
|
|
13
|
-
name?: string;
|
|
14
|
-
}
|
|
15
|
-
interface Clip {
|
|
16
|
-
id: string;
|
|
17
|
-
sourceId: string;
|
|
18
|
-
/** Window into the source — `in` inclusive, `out` exclusive. */
|
|
19
|
-
in: Ms;
|
|
20
|
-
out: Ms;
|
|
21
|
-
/** Position on the timeline. */
|
|
22
|
-
start: Ms;
|
|
23
|
-
/**
|
|
24
|
-
* Playback rate. 1 = normal, 2 = 2× speed. Default 1.
|
|
25
|
-
* Persisted in the project JSON so a host can restore exactly.
|
|
26
|
-
*/
|
|
27
|
-
speed?: number;
|
|
28
|
-
}
|
|
29
|
-
interface Track {
|
|
30
|
-
id: string;
|
|
31
|
-
kind: "video" | "audio";
|
|
32
|
-
/** Clips on this track. Must be kept sorted by `start` and non-overlapping. */
|
|
33
|
-
clips: Clip[];
|
|
34
|
-
}
|
|
35
|
-
interface Project {
|
|
36
|
-
/** Schema version — bump when breaking the JSON shape. */
|
|
37
|
-
version: 1;
|
|
38
|
-
sources: MediaSource[];
|
|
39
|
-
tracks: Track[];
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Subset of CSS variables the editor honors. Pass any custom values
|
|
43
|
-
* via `Editor` options; everything is forwarded as `--aicut-*` on the
|
|
44
|
-
* editor's root container, so a host can also override via plain CSS.
|
|
45
|
-
*/
|
|
46
|
-
interface Theme {
|
|
47
|
-
brand?: string;
|
|
48
|
-
secondary?: string;
|
|
49
|
-
surface?: string;
|
|
50
|
-
dark?: string;
|
|
51
|
-
muted?: string;
|
|
52
|
-
card?: string;
|
|
53
|
-
success?: string;
|
|
54
|
-
warning?: string;
|
|
55
|
-
info?: string;
|
|
56
|
-
error?: string;
|
|
57
|
-
/** Toolbar / ruler chrome. Background of the editor frame. */
|
|
58
|
-
controlsBg?: string;
|
|
59
|
-
controlsBorder?: string;
|
|
60
|
-
controlsText?: string;
|
|
61
|
-
controlsHover?: string;
|
|
62
|
-
controlsActive?: string;
|
|
63
|
-
/** Letterbox color around the preview video. Defaults to black. */
|
|
64
|
-
previewBg?: string;
|
|
65
|
-
radiusSm?: string;
|
|
66
|
-
radiusMd?: string;
|
|
67
|
-
radiusLg?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type { Clip as C, Ms as M, Project as P, Track as T, MediaSource as a, Theme as b };
|