@aicut/core 0.4.3 → 0.5.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.
@@ -0,0 +1,70 @@
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 };
@@ -0,0 +1,70 @@
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 };
@@ -0,0 +1,75 @@
1
+ import { P as Project, M as Ms } from './types-CHplD9V5.cjs';
2
+
3
+ /**
4
+ * Construction context the Editor hands to a playback engine. The
5
+ * engine mounts itself into `host` (typically the editor's preview
6
+ * element) and owns whatever DOM / canvas / video elements it needs.
7
+ */
8
+ interface PlaybackEngineOptions {
9
+ /** Mount point. Engine appends its preview surface here. */
10
+ host: HTMLElement;
11
+ /** Initial project — engine pre-warms sources, etc. */
12
+ project: Project;
13
+ }
14
+ /**
15
+ * The contract every preview engine satisfies. Editor talks ONLY
16
+ * through this surface — implementations are interchangeable.
17
+ *
18
+ * Built-in implementations:
19
+ * - `HtmlVideoEngine` default; one HTMLVideoElement per source,
20
+ * swap on clip boundaries. Zero deps,
21
+ * GPU-accelerated decode by the browser, but
22
+ * seek snaps to keyframes (browser controls
23
+ * the decode pipeline).
24
+ * - `WebCodecsEngine` opt-in (v0.6+); manual VideoDecoder loop +
25
+ * canvas blit. Frame-accurate seek; will
26
+ * underpin multi-track compositing, transitions,
27
+ * and shaders in later versions.
28
+ *
29
+ * Hosts can ship their own implementation (e.g., a WebGL compositor,
30
+ * a WebRTC stream consumer, a desktop-wrapper IPC bridge) and inject
31
+ * it via `Editor.create({ playbackEngine: myFactory })`.
32
+ */
33
+ interface PlaybackEngine {
34
+ /** Replace the project. Engine re-warms sources + re-resolves the
35
+ * active clip for the current playhead. Idempotent. */
36
+ setProject(next: Project): void;
37
+ play(): void;
38
+ pause(): void;
39
+ isPlaying(): boolean;
40
+ /** Current playhead (ms from project start). */
41
+ getTime(): Ms;
42
+ /** Move the playhead. Engine clamps to [0, totalDuration]. */
43
+ seek(timeMs: Ms): void;
44
+ /** Free all resources (DOM nodes, decoders, AudioContexts, rAF). */
45
+ destroy(): void;
46
+ /** Fired on each rAF / decoded frame with the current playhead. */
47
+ onTimeUpdate?: (ms: Ms) => void;
48
+ /** Fired once when the project's end is reached during playback. */
49
+ onEnded?: () => void;
50
+ /** Decode / network / capability failures. */
51
+ onError?: (err: Error) => void;
52
+ /**
53
+ * Fired the first time a fresh playback target is "ready to play"
54
+ * — analogue of HTMLMediaElement's `loadedmetadata`. Editor uses
55
+ * it to gate scaling / auto-fit work.
56
+ */
57
+ onReady?: () => void;
58
+ /**
59
+ * Fired when an individual source's duration becomes known. Editor
60
+ * folds this into the project model so the timeline can size clips
61
+ * correctly even when the host didn't ship a `duration` upfront.
62
+ */
63
+ onSourceMetadata?: (sourceId: string, durationMs: Ms) => void;
64
+ }
65
+ /**
66
+ * A factory that builds an engine for a given mount/project. Hosts
67
+ * pass one of these to `Editor.create({ playbackEngine })` to swap
68
+ * implementations. The factory shape — rather than a class reference
69
+ * — keeps Editor decoupled from constructor signatures and lets
70
+ * factories close over host-side configuration (auth tokens, render
71
+ * backend URL, custom shaders, etc.) without polluting the interface.
72
+ */
73
+ type PlaybackEngineFactory = (opts: PlaybackEngineOptions) => PlaybackEngine;
74
+
75
+ export type { PlaybackEngine as P, PlaybackEngineOptions as a, PlaybackEngineFactory as b };
@@ -0,0 +1,75 @@
1
+ import { P as Project, M as Ms } from './types-CHplD9V5.js';
2
+
3
+ /**
4
+ * Construction context the Editor hands to a playback engine. The
5
+ * engine mounts itself into `host` (typically the editor's preview
6
+ * element) and owns whatever DOM / canvas / video elements it needs.
7
+ */
8
+ interface PlaybackEngineOptions {
9
+ /** Mount point. Engine appends its preview surface here. */
10
+ host: HTMLElement;
11
+ /** Initial project — engine pre-warms sources, etc. */
12
+ project: Project;
13
+ }
14
+ /**
15
+ * The contract every preview engine satisfies. Editor talks ONLY
16
+ * through this surface — implementations are interchangeable.
17
+ *
18
+ * Built-in implementations:
19
+ * - `HtmlVideoEngine` default; one HTMLVideoElement per source,
20
+ * swap on clip boundaries. Zero deps,
21
+ * GPU-accelerated decode by the browser, but
22
+ * seek snaps to keyframes (browser controls
23
+ * the decode pipeline).
24
+ * - `WebCodecsEngine` opt-in (v0.6+); manual VideoDecoder loop +
25
+ * canvas blit. Frame-accurate seek; will
26
+ * underpin multi-track compositing, transitions,
27
+ * and shaders in later versions.
28
+ *
29
+ * Hosts can ship their own implementation (e.g., a WebGL compositor,
30
+ * a WebRTC stream consumer, a desktop-wrapper IPC bridge) and inject
31
+ * it via `Editor.create({ playbackEngine: myFactory })`.
32
+ */
33
+ interface PlaybackEngine {
34
+ /** Replace the project. Engine re-warms sources + re-resolves the
35
+ * active clip for the current playhead. Idempotent. */
36
+ setProject(next: Project): void;
37
+ play(): void;
38
+ pause(): void;
39
+ isPlaying(): boolean;
40
+ /** Current playhead (ms from project start). */
41
+ getTime(): Ms;
42
+ /** Move the playhead. Engine clamps to [0, totalDuration]. */
43
+ seek(timeMs: Ms): void;
44
+ /** Free all resources (DOM nodes, decoders, AudioContexts, rAF). */
45
+ destroy(): void;
46
+ /** Fired on each rAF / decoded frame with the current playhead. */
47
+ onTimeUpdate?: (ms: Ms) => void;
48
+ /** Fired once when the project's end is reached during playback. */
49
+ onEnded?: () => void;
50
+ /** Decode / network / capability failures. */
51
+ onError?: (err: Error) => void;
52
+ /**
53
+ * Fired the first time a fresh playback target is "ready to play"
54
+ * — analogue of HTMLMediaElement's `loadedmetadata`. Editor uses
55
+ * it to gate scaling / auto-fit work.
56
+ */
57
+ onReady?: () => void;
58
+ /**
59
+ * Fired when an individual source's duration becomes known. Editor
60
+ * folds this into the project model so the timeline can size clips
61
+ * correctly even when the host didn't ship a `duration` upfront.
62
+ */
63
+ onSourceMetadata?: (sourceId: string, durationMs: Ms) => void;
64
+ }
65
+ /**
66
+ * A factory that builds an engine for a given mount/project. Hosts
67
+ * pass one of these to `Editor.create({ playbackEngine })` to swap
68
+ * implementations. The factory shape — rather than a class reference
69
+ * — keeps Editor decoupled from constructor signatures and lets
70
+ * factories close over host-side configuration (auth tokens, render
71
+ * backend URL, custom shaders, etc.) without polluting the interface.
72
+ */
73
+ type PlaybackEngineFactory = (opts: PlaybackEngineOptions) => PlaybackEngine;
74
+
75
+ export type { PlaybackEngine as P, PlaybackEngineOptions as a, PlaybackEngineFactory as b };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aicut/core",
3
- "version": "0.4.3",
4
- "description": "Framework-agnostic core for the AiCut video editor — canvas timeline, data model, HTML5 playback engine, plus an opt-in 3D lighting picker.",
3
+ "version": "0.5.0",
4
+ "description": "Framework-agnostic core for the AiCut video editor — canvas timeline, data model, pluggable PlaybackEngine (HTML5 / Canvas / WebCodecs), plus opt-in 3D lighting picker.",
5
5
  "license": "MIT",
6
6
  "author": "ziqiang <ziqiangytu@gmail.com>",
7
7
  "homepage": "https://github.com/ziqiangai/AiCut#readme",
@@ -57,6 +57,11 @@
57
57
  "import": "./dist/lighting/index.js",
58
58
  "require": "./dist/lighting/index.cjs"
59
59
  },
60
+ "./webcodecs": {
61
+ "types": "./dist/playback/webcodecs/index.d.ts",
62
+ "import": "./dist/playback/webcodecs/index.js",
63
+ "require": "./dist/playback/webcodecs/index.cjs"
64
+ },
60
65
  "./styles.css": "./styles/theme.css"
61
66
  },
62
67
  "files": [
@@ -65,12 +70,16 @@
65
70
  "README.md"
66
71
  ],
67
72
  "dependencies": {
73
+ "mp4box": "^2.4.1",
68
74
  "three": "^0.159.0"
69
75
  },
70
76
  "devDependencies": {
71
77
  "@types/three": "^0.159.0",
78
+ "@vitest/coverage-v8": "^4.1.9",
79
+ "happy-dom": "^20.10.6",
72
80
  "tsup": "^8.3.5",
73
- "typescript": "^5.7.2"
81
+ "typescript": "^5.7.2",
82
+ "vitest": "^4.1.9"
74
83
  },
75
84
  "publishConfig": {
76
85
  "access": "public"
@@ -78,6 +87,8 @@
78
87
  "scripts": {
79
88
  "build": "tsup",
80
89
  "dev": "tsup --watch",
81
- "typecheck": "tsc --noEmit"
90
+ "typecheck": "tsc --noEmit",
91
+ "test": "vitest run",
92
+ "test:watch": "vitest"
82
93
  }
83
94
  }
package/styles/theme.css CHANGED
@@ -430,8 +430,13 @@
430
430
  position: relative;
431
431
  flex: 0 0 auto;
432
432
  background: var(--aicut-controls-bg);
433
- height: 240px;
434
- min-height: 200px;
433
+ /* Override via EditorOptions.timelineHeight (sets the custom property
434
+ on the root container). Default 240 matches historical behavior;
435
+ small-viewport hosts often want 140–180. min-height is intentionally
436
+ a hair below the smallest sensible default so the option can dip
437
+ into the compact range without the min winning. */
438
+ height: var(--aicut-timeline-height, 240px);
439
+ min-height: 120px;
435
440
  overflow: hidden;
436
441
  }
437
442
 
@@ -1,120 +0,0 @@
1
- /**
2
- * UI strings the editor paints into the DOM (toolbar tooltips, the
3
- * fullscreen exit button) and onto the timeline canvas (phantom new-
4
- * track label, track header labels). Every user-visible literal in
5
- * `@aicut/core` flows through this interface — there are no hidden
6
- * hard-coded translations elsewhere in the library.
7
- *
8
- * Defaults to English. Hosts that want Chinese (or any other locale)
9
- * pass `locale: localeZh` to `Editor.create` / `Timeline.create`, or
10
- * override individual keys with `locale: { undo: "撤销" }`.
11
- */
12
- interface Locale {
13
- undo: string;
14
- redo: string;
15
- split: string;
16
- trimLeft: string;
17
- trimRight: string;
18
- speedComingSoon: string;
19
- playPause: string;
20
- fullscreen: string;
21
- snap: string;
22
- /** Title shown on the snap button when snap is ON (clicking turns OFF). */
23
- snapOnTitle: string;
24
- /** Title shown when snap is OFF (clicking turns ON). */
25
- snapOffTitle: string;
26
- zoomOut: string;
27
- zoomIn: string;
28
- reset: string;
29
- exitFullscreen: string;
30
- exitFullscreenTitle: string;
31
- /** Phantom row that appears under the last track during a drag. */
32
- newTrack: string;
33
- /** Track header — `{n}` is replaced with the 1-based track index. */
34
- videoTrackLabel: string;
35
- /** Same template format as videoTrackLabel. */
36
- audioTrackLabel: string;
37
- }
38
- /** English. The library default — chosen over Chinese as the OSS norm. */
39
- declare const localeEn: Locale;
40
- /** Simplified Chinese. */
41
- declare const localeZh: Locale;
42
- /** Spread defaults under host overrides — host can supply a partial. */
43
- declare function mergeLocale(partial: Partial<Locale> | undefined): Locale;
44
- /**
45
- * Replace `{key}` placeholders in a template. We only need `{n}`
46
- * substitution today; the implementation is generic so additional
47
- * keys (e.g. `{name}`) won't need a second pass.
48
- */
49
- declare function formatLabel(template: string, vars: Record<string, string | number>): string;
50
-
51
- /**
52
- * Milliseconds. All timing in the project is expressed as integer ms to
53
- * keep JSON serialization unambiguous (no frame-rate coupling in the
54
- * data model — the renderer can present time as frames if it wants).
55
- */
56
- type Ms = number;
57
- interface MediaSource {
58
- id: string;
59
- url: string;
60
- kind: "video" | "audio";
61
- /** Optional — probed lazily from the <video> element if absent. */
62
- duration?: Ms;
63
- name?: string;
64
- }
65
- interface Clip {
66
- id: string;
67
- sourceId: string;
68
- /** Window into the source — `in` inclusive, `out` exclusive. */
69
- in: Ms;
70
- out: Ms;
71
- /** Position on the timeline. */
72
- start: Ms;
73
- /**
74
- * Playback rate. 1 = normal, 2 = 2× speed. Default 1.
75
- * Persisted in the project JSON so a host can restore exactly.
76
- */
77
- speed?: number;
78
- }
79
- interface Track {
80
- id: string;
81
- kind: "video" | "audio";
82
- /** Clips on this track. Must be kept sorted by `start` and non-overlapping. */
83
- clips: Clip[];
84
- }
85
- interface Project {
86
- /** Schema version — bump when breaking the JSON shape. */
87
- version: 1;
88
- sources: MediaSource[];
89
- tracks: Track[];
90
- }
91
- /**
92
- * Subset of CSS variables the editor honors. Pass any custom values
93
- * via `Editor` options; everything is forwarded as `--aicut-*` on the
94
- * editor's root container, so a host can also override via plain CSS.
95
- */
96
- interface Theme {
97
- brand?: string;
98
- secondary?: string;
99
- surface?: string;
100
- dark?: string;
101
- muted?: string;
102
- card?: string;
103
- success?: string;
104
- warning?: string;
105
- info?: string;
106
- error?: string;
107
- /** Toolbar / ruler chrome. Background of the editor frame. */
108
- controlsBg?: string;
109
- controlsBorder?: string;
110
- controlsText?: string;
111
- controlsHover?: string;
112
- controlsActive?: string;
113
- /** Letterbox color around the preview video. Defaults to black. */
114
- previewBg?: string;
115
- radiusSm?: string;
116
- radiusMd?: string;
117
- radiusLg?: string;
118
- }
119
-
120
- export { type Clip as C, type Locale as L, type Ms as M, type Project as P, type Track as T, type MediaSource as a, type Theme as b, localeZh as c, formatLabel as f, localeEn as l, mergeLocale as m };
@@ -1,120 +0,0 @@
1
- /**
2
- * UI strings the editor paints into the DOM (toolbar tooltips, the
3
- * fullscreen exit button) and onto the timeline canvas (phantom new-
4
- * track label, track header labels). Every user-visible literal in
5
- * `@aicut/core` flows through this interface — there are no hidden
6
- * hard-coded translations elsewhere in the library.
7
- *
8
- * Defaults to English. Hosts that want Chinese (or any other locale)
9
- * pass `locale: localeZh` to `Editor.create` / `Timeline.create`, or
10
- * override individual keys with `locale: { undo: "撤销" }`.
11
- */
12
- interface Locale {
13
- undo: string;
14
- redo: string;
15
- split: string;
16
- trimLeft: string;
17
- trimRight: string;
18
- speedComingSoon: string;
19
- playPause: string;
20
- fullscreen: string;
21
- snap: string;
22
- /** Title shown on the snap button when snap is ON (clicking turns OFF). */
23
- snapOnTitle: string;
24
- /** Title shown when snap is OFF (clicking turns ON). */
25
- snapOffTitle: string;
26
- zoomOut: string;
27
- zoomIn: string;
28
- reset: string;
29
- exitFullscreen: string;
30
- exitFullscreenTitle: string;
31
- /** Phantom row that appears under the last track during a drag. */
32
- newTrack: string;
33
- /** Track header — `{n}` is replaced with the 1-based track index. */
34
- videoTrackLabel: string;
35
- /** Same template format as videoTrackLabel. */
36
- audioTrackLabel: string;
37
- }
38
- /** English. The library default — chosen over Chinese as the OSS norm. */
39
- declare const localeEn: Locale;
40
- /** Simplified Chinese. */
41
- declare const localeZh: Locale;
42
- /** Spread defaults under host overrides — host can supply a partial. */
43
- declare function mergeLocale(partial: Partial<Locale> | undefined): Locale;
44
- /**
45
- * Replace `{key}` placeholders in a template. We only need `{n}`
46
- * substitution today; the implementation is generic so additional
47
- * keys (e.g. `{name}`) won't need a second pass.
48
- */
49
- declare function formatLabel(template: string, vars: Record<string, string | number>): string;
50
-
51
- /**
52
- * Milliseconds. All timing in the project is expressed as integer ms to
53
- * keep JSON serialization unambiguous (no frame-rate coupling in the
54
- * data model — the renderer can present time as frames if it wants).
55
- */
56
- type Ms = number;
57
- interface MediaSource {
58
- id: string;
59
- url: string;
60
- kind: "video" | "audio";
61
- /** Optional — probed lazily from the <video> element if absent. */
62
- duration?: Ms;
63
- name?: string;
64
- }
65
- interface Clip {
66
- id: string;
67
- sourceId: string;
68
- /** Window into the source — `in` inclusive, `out` exclusive. */
69
- in: Ms;
70
- out: Ms;
71
- /** Position on the timeline. */
72
- start: Ms;
73
- /**
74
- * Playback rate. 1 = normal, 2 = 2× speed. Default 1.
75
- * Persisted in the project JSON so a host can restore exactly.
76
- */
77
- speed?: number;
78
- }
79
- interface Track {
80
- id: string;
81
- kind: "video" | "audio";
82
- /** Clips on this track. Must be kept sorted by `start` and non-overlapping. */
83
- clips: Clip[];
84
- }
85
- interface Project {
86
- /** Schema version — bump when breaking the JSON shape. */
87
- version: 1;
88
- sources: MediaSource[];
89
- tracks: Track[];
90
- }
91
- /**
92
- * Subset of CSS variables the editor honors. Pass any custom values
93
- * via `Editor` options; everything is forwarded as `--aicut-*` on the
94
- * editor's root container, so a host can also override via plain CSS.
95
- */
96
- interface Theme {
97
- brand?: string;
98
- secondary?: string;
99
- surface?: string;
100
- dark?: string;
101
- muted?: string;
102
- card?: string;
103
- success?: string;
104
- warning?: string;
105
- info?: string;
106
- error?: string;
107
- /** Toolbar / ruler chrome. Background of the editor frame. */
108
- controlsBg?: string;
109
- controlsBorder?: string;
110
- controlsText?: string;
111
- controlsHover?: string;
112
- controlsActive?: string;
113
- /** Letterbox color around the preview video. Defaults to black. */
114
- previewBg?: string;
115
- radiusSm?: string;
116
- radiusMd?: string;
117
- radiusLg?: string;
118
- }
119
-
120
- export { type Clip as C, type Locale as L, type Ms as M, type Project as P, type Track as T, type MediaSource as a, type Theme as b, localeZh as c, formatLabel as f, localeEn as l, mergeLocale as m };