@editframe/elements 0.30.0-beta.14 → 0.30.2-beta.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/dist/elements/EFAudio.d.ts +2 -2
- package/dist/elements/EFCaptions.d.ts +12 -12
- package/dist/elements/EFMedia.d.ts +2 -2
- package/dist/elements/EFText.d.ts +4 -4
- package/dist/elements/EFText.js +11 -30
- package/dist/elements/EFText.js.map +1 -1
- package/dist/elements/EFTextSegment.d.ts +4 -4
- package/dist/elements/EFTextSegment.js.map +1 -1
- package/dist/elements/EFTimegroup.js +3 -3
- package/dist/elements/EFTimegroup.js.map +1 -1
- package/dist/elements/EFVideo.d.ts +4 -4
- package/dist/elements/EFWaveform.d.ts +4 -4
- package/dist/elements/updateAnimations.js +348 -108
- package/dist/elements/updateAnimations.js.map +1 -1
- package/dist/gui/EFConfiguration.d.ts +4 -4
- package/dist/gui/EFTogglePlay.d.ts +1 -0
- package/dist/gui/EFTogglePlay.js +18 -1
- package/dist/gui/EFTogglePlay.js.map +1 -1
- package/dist/gui/EFWorkbench.d.ts +4 -4
- package/dist/gui/PlaybackController.d.ts +1 -0
- package/dist/gui/PlaybackController.js +18 -3
- package/dist/gui/PlaybackController.js.map +1 -1
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TWMixin.js.map +1 -1
- package/dist/style.css +0 -4
- package/package.json +2 -2
- package/types.json +1 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit12 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html12 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFConfiguration.d.ts
|
|
6
6
|
declare class EFConfiguration extends LitElement {
|
|
7
|
-
static styles:
|
|
7
|
+
static styles: lit12.CSSResult[];
|
|
8
8
|
efConfiguration: this;
|
|
9
9
|
apiHost?: string;
|
|
10
10
|
signingURL: string;
|
|
11
11
|
mediaEngine?: "cloud" | "local";
|
|
12
|
-
render():
|
|
12
|
+
render(): lit_html12.TemplateResult<1>;
|
|
13
13
|
}
|
|
14
14
|
declare global {
|
|
15
15
|
interface HTMLElementTagNameMap {
|
package/dist/gui/EFTogglePlay.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { playingContext } from "./playingContext.js";
|
|
2
2
|
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
3
|
+
import { isEFTemporal } from "../elements/EFTemporal.js";
|
|
3
4
|
import { efContext } from "./efContext.js";
|
|
4
5
|
import { attachContextRoot } from "../attachContextRoot.js";
|
|
5
6
|
import { TargetOrContextMixin } from "./TargetOrContextMixin.js";
|
|
@@ -15,7 +16,17 @@ let EFTogglePlay = class EFTogglePlay$1 extends TargetOrContextMixin(LitElement,
|
|
|
15
16
|
this.playing = false;
|
|
16
17
|
this.togglePlay = () => {
|
|
17
18
|
if (this.efContext) if (this.playing) this.efContext.pause();
|
|
18
|
-
else
|
|
19
|
+
else {
|
|
20
|
+
const playbackController = this.getPlaybackController();
|
|
21
|
+
if (playbackController) try {
|
|
22
|
+
const audioContext = new AudioContext({ latencyHint: "playback" });
|
|
23
|
+
audioContext.resume();
|
|
24
|
+
playbackController.setPendingAudioContext(audioContext);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.warn("Failed to create/resume AudioContext synchronously:", error);
|
|
27
|
+
}
|
|
28
|
+
this.efContext.play();
|
|
29
|
+
}
|
|
19
30
|
};
|
|
20
31
|
}
|
|
21
32
|
static {
|
|
@@ -44,6 +55,12 @@ let EFTogglePlay = class EFTogglePlay$1 extends TargetOrContextMixin(LitElement,
|
|
|
44
55
|
</div>
|
|
45
56
|
`;
|
|
46
57
|
}
|
|
58
|
+
getPlaybackController() {
|
|
59
|
+
const context = this.efContext;
|
|
60
|
+
if (!context) return null;
|
|
61
|
+
if (isEFTemporal(context) && context.playbackController) return context.playbackController;
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
47
64
|
};
|
|
48
65
|
__decorate([consume({
|
|
49
66
|
context: playingContext,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EFTogglePlay.js","names":["EFTogglePlay"],"sources":["../../src/gui/EFTogglePlay.ts"],"sourcesContent":["import { consume } from \"@lit/context\";\nimport { css, html, LitElement } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\nimport { attachContextRoot } from \"../attachContextRoot.js\";\nimport type { ControllableInterface } from \"./Controllable.js\";\nimport { efContext } from \"./efContext.js\";\nimport { playingContext } from \"./playingContext.js\";\nimport { TargetOrContextMixin } from \"./TargetOrContextMixin.js\";\n\nattachContextRoot();\n\n@customElement(\"ef-toggle-play\")\nexport class EFTogglePlay extends TargetOrContextMixin(LitElement, efContext) {\n static styles = [\n css`\n :host {}\n div {\n all: inherit;\n }\n `,\n ];\n\n @consume({ context: playingContext, subscribe: true })\n @state()\n playing = false;\n\n get efContext(): ControllableInterface | null {\n return this.effectiveContext;\n }\n\n // Attach click listener to host\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener(\"click\", this.togglePlay);\n }\n\n // Detach click listener from host\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"click\", this.togglePlay);\n }\n\n render() {\n return html`\n <div>\n ${\n this.playing\n ? html`<slot name=\"pause\"></slot>`\n : html`<slot name=\"play\"></slot>`\n }\n </div>\n `;\n }\n\n togglePlay = () => {\n if (this.efContext) {\n if (this.playing) {\n this.efContext.pause();\n } else {\n this.efContext.play();\n }\n }\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-toggle-play\": EFTogglePlay;\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"EFTogglePlay.js","names":["EFTogglePlay"],"sources":["../../src/gui/EFTogglePlay.ts"],"sourcesContent":["import { consume } from \"@lit/context\";\nimport { css, html, LitElement } from \"lit\";\nimport { customElement, state } from \"lit/decorators.js\";\nimport { attachContextRoot } from \"../attachContextRoot.js\";\nimport { isEFTemporal } from \"../elements/EFTemporal.js\";\nimport type { ControllableInterface } from \"./Controllable.js\";\nimport { efContext } from \"./efContext.js\";\nimport { playingContext } from \"./playingContext.js\";\nimport type { PlaybackController } from \"./PlaybackController.js\";\nimport { TargetOrContextMixin } from \"./TargetOrContextMixin.js\";\n\nattachContextRoot();\n\n@customElement(\"ef-toggle-play\")\nexport class EFTogglePlay extends TargetOrContextMixin(LitElement, efContext) {\n static styles = [\n css`\n :host {}\n div {\n all: inherit;\n }\n `,\n ];\n\n @consume({ context: playingContext, subscribe: true })\n @state()\n playing = false;\n\n get efContext(): ControllableInterface | null {\n return this.effectiveContext;\n }\n\n // Attach click listener to host\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener(\"click\", this.togglePlay);\n }\n\n // Detach click listener from host\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"click\", this.togglePlay);\n }\n\n render() {\n return html`\n <div>\n ${\n this.playing\n ? html`<slot name=\"pause\"></slot>`\n : html`<slot name=\"play\"></slot>`\n }\n </div>\n `;\n }\n\n togglePlay = () => {\n if (this.efContext) {\n if (this.playing) {\n this.efContext.pause();\n } else {\n // Create and resume AudioContext synchronously within user interaction handler\n // This is required on mobile devices where AudioContext.resume() must be called\n // synchronously within a user interaction event handler\n const playbackController = this.getPlaybackController();\n if (playbackController) {\n try {\n const audioContext = new AudioContext({\n latencyHint: \"playback\",\n });\n // Resume synchronously (doesn't await, but initiates resume)\n // Once resumed via user interaction, the context stays \"unlocked\"\n audioContext.resume();\n playbackController.setPendingAudioContext(audioContext);\n } catch (error) {\n // If context creation/resume fails, continue with normal async flow\n // The fallback in startPlayback() will attempt resume (may not work on mobile)\n console.warn(\n \"Failed to create/resume AudioContext synchronously:\",\n error,\n );\n }\n }\n this.efContext.play();\n }\n }\n };\n\n private getPlaybackController(): PlaybackController | null {\n const context = this.efContext;\n if (!context) {\n return null;\n }\n\n // Check if context is a temporal element with playbackController\n if (isEFTemporal(context) && context.playbackController) {\n return context.playbackController;\n }\n\n return null;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ef-toggle-play\": EFTogglePlay;\n }\n}\n"],"mappings":";;;;;;;;;;;AAWA,mBAAmB;AAGZ,yBAAMA,uBAAqB,qBAAqB,YAAY,UAAU,CAAC;;;iBAYlE;0BA8BS;AACjB,OAAI,KAAK,UACP,KAAI,KAAK,QACP,MAAK,UAAU,OAAO;QACjB;IAIL,MAAM,qBAAqB,KAAK,uBAAuB;AACvD,QAAI,mBACF,KAAI;KACF,MAAM,eAAe,IAAI,aAAa,EACpC,aAAa,YACd,CAAC;AAGF,kBAAa,QAAQ;AACrB,wBAAmB,uBAAuB,aAAa;aAChD,OAAO;AAGd,aAAQ,KACN,uDACA,MACD;;AAGL,SAAK,UAAU,MAAM;;;;;gBApEX,CACd,GAAG;;;;;MAMJ;;CAMD,IAAI,YAA0C;AAC5C,SAAO,KAAK;;CAId,oBAAoB;AAClB,QAAM,mBAAmB;AACzB,OAAK,iBAAiB,SAAS,KAAK,WAAW;;CAIjD,uBAAuB;AACrB,QAAM,sBAAsB;AAC5B,OAAK,oBAAoB,SAAS,KAAK,WAAW;;CAGpD,SAAS;AACP,SAAO,IAAI;;UAGL,KAAK,UACD,IAAI,+BACJ,IAAI,4BACT;;;;CAqCP,AAAQ,wBAAmD;EACzD,MAAM,UAAU,KAAK;AACrB,MAAI,CAAC,QACH,QAAO;AAIT,MAAI,aAAa,QAAQ,IAAI,QAAQ,mBACnC,QAAO,QAAQ;AAGjB,SAAO;;;YA3ER,QAAQ;CAAE,SAAS;CAAgB,WAAW;CAAM,CAAC,EACrD,OAAO;2BAZT,cAAc,iBAAiB"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ContextMixinInterface } from "./ContextMixin.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit11 from "lit";
|
|
3
3
|
import { LitElement, PropertyValueMap } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html11 from "lit-html";
|
|
5
5
|
import * as lit_html_directives_ref_js2 from "lit-html/directives/ref.js";
|
|
6
6
|
|
|
7
7
|
//#region src/gui/EFWorkbench.d.ts
|
|
8
8
|
declare const EFWorkbench_base: (new (...args: any[]) => ContextMixinInterface) & typeof LitElement;
|
|
9
9
|
declare class EFWorkbench extends EFWorkbench_base {
|
|
10
|
-
static styles:
|
|
10
|
+
static styles: lit11.CSSResult[];
|
|
11
11
|
rendering: boolean;
|
|
12
12
|
focusOverlay: lit_html_directives_ref_js2.Ref<HTMLDivElement>;
|
|
13
13
|
handleStageWheel(event: WheelEvent): void;
|
|
@@ -15,7 +15,7 @@ declare class EFWorkbench extends EFWorkbench_base {
|
|
|
15
15
|
disconnectedCallback(): void;
|
|
16
16
|
update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
17
17
|
drawOverlays: () => void;
|
|
18
|
-
render():
|
|
18
|
+
render(): lit_html11.TemplateResult<1>;
|
|
19
19
|
}
|
|
20
20
|
declare global {
|
|
21
21
|
interface HTMLElementTagNameMap {
|
|
@@ -62,6 +62,7 @@ declare class PlaybackController implements ReactiveController {
|
|
|
62
62
|
addListener(listener: (event: PlaybackControllerUpdateEvent) => void): void;
|
|
63
63
|
removeListener(listener: (event: PlaybackControllerUpdateEvent) => void): void;
|
|
64
64
|
remove(): void;
|
|
65
|
+
setPendingAudioContext(context: AudioContext): void;
|
|
65
66
|
private maybeLoopPlayback;
|
|
66
67
|
private stopPlayback;
|
|
67
68
|
private startPlayback;
|
|
@@ -32,6 +32,7 @@ var PlaybackController = class {
|
|
|
32
32
|
#MS_PER_FRAME = 1e3 / this.#FPS;
|
|
33
33
|
#playbackAudioContext = null;
|
|
34
34
|
#playbackAnimationFrameRequest = null;
|
|
35
|
+
#pendingAudioContext = null;
|
|
35
36
|
#AUDIO_PLAYBACK_SLICE_MS = 47 * 1024 / 48e3 * 1e3;
|
|
36
37
|
#frameTaskInProgress = false;
|
|
37
38
|
#pendingFrameTaskRun = false;
|
|
@@ -220,6 +221,9 @@ var PlaybackController = class {
|
|
|
220
221
|
this.#listeners.clear();
|
|
221
222
|
this.#host.removeController(this);
|
|
222
223
|
}
|
|
224
|
+
setPendingAudioContext(context) {
|
|
225
|
+
this.#pendingAudioContext = context;
|
|
226
|
+
}
|
|
223
227
|
#syncPlayheadToAudioContext(startMs) {
|
|
224
228
|
const audioContextTime = this.#playbackAudioContext?.currentTime ?? 0;
|
|
225
229
|
const endMs = this.#host.endTimeMs;
|
|
@@ -257,6 +261,7 @@ var PlaybackController = class {
|
|
|
257
261
|
if (this.#playbackAnimationFrameRequest) cancelAnimationFrame(this.#playbackAnimationFrameRequest);
|
|
258
262
|
this.#playbackAudioContext = null;
|
|
259
263
|
this.#playbackAnimationFrameRequest = null;
|
|
264
|
+
this.#pendingAudioContext = null;
|
|
260
265
|
}
|
|
261
266
|
async startPlayback() {
|
|
262
267
|
await this.stopPlayback();
|
|
@@ -271,14 +276,24 @@ var PlaybackController = class {
|
|
|
271
276
|
return;
|
|
272
277
|
}
|
|
273
278
|
let bufferCount = 0;
|
|
274
|
-
this.#
|
|
279
|
+
if (this.#pendingAudioContext) {
|
|
280
|
+
this.#playbackAudioContext = this.#pendingAudioContext;
|
|
281
|
+
this.#pendingAudioContext = null;
|
|
282
|
+
} else this.#playbackAudioContext = new AudioContext({ latencyHint: "playback" });
|
|
275
283
|
this.#loopingPlayback = this.#loop;
|
|
276
284
|
this.#playbackWrapTimeSeconds = 0;
|
|
277
285
|
if (this.#playbackAnimationFrameRequest) cancelAnimationFrame(this.#playbackAnimationFrameRequest);
|
|
278
286
|
this.#syncPlayheadToAudioContext(currentMs);
|
|
279
287
|
const playbackContext = this.#playbackAudioContext;
|
|
280
|
-
if (playbackContext.state === "suspended") {
|
|
281
|
-
|
|
288
|
+
if (playbackContext.state === "suspended") try {
|
|
289
|
+
await playbackContext.resume();
|
|
290
|
+
if (playbackContext.state === "suspended") {
|
|
291
|
+
console.warn("AudioContext is suspended and resume() failed. On mobile devices, AudioContext.resume() must be called synchronously within a user interaction handler. Media playback will not work until user has interacted with page.");
|
|
292
|
+
this.setPlaying(false);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
} catch (error) {
|
|
296
|
+
console.warn("Failed to resume AudioContext:", error, "On mobile devices, AudioContext.resume() must be called synchronously within a user interaction handler.");
|
|
282
297
|
this.setPlaying(false);
|
|
283
298
|
return;
|
|
284
299
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackController.js","names":["#FPS","#host","#pendingSeekTime","#currentTime","#currentTimeMsProvider","#notifyListeners","#seekInProgress","#playingProvider","#playing","#loopProvider","#loop","#durationMsProvider","#processingPendingSeek","#frameTaskInProgress","#pendingFrameTaskRun","#processingPendingFrameTask","#listeners","#playbackAudioContext","rawTimeMs: number","#playbackWrapTimeSeconds","#loopingPlayback","#MS_PER_FRAME","#updatePlaybackTime","#playbackAnimationFrameRequest","#syncPlayheadToAudioContext","#AUDIO_PLAYBACK_SLICE_MS"],"sources":["../../src/gui/PlaybackController.ts"],"sourcesContent":["import { ContextProvider } from \"@lit/context\";\nimport { Task, TaskStatus } from \"@lit/task\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { EF_INTERACTIVE } from \"../EF_INTERACTIVE.js\";\nimport { currentTimeContext } from \"./currentTimeContext.js\";\nimport { durationContext } from \"./durationContext.js\";\nimport { loopContext, playingContext } from \"./playingContext.js\";\n\ninterface PlaybackHost extends HTMLElement, ReactiveControllerHost {\n currentTimeMs: number;\n durationMs: number;\n endTimeMs: number;\n frameTask: { run(): void; taskComplete: Promise<unknown> };\n renderAudio?(fromMs: number, toMs: number): Promise<AudioBuffer>;\n waitForMediaDurations?(): Promise<void>;\n saveTimeToLocalStorage?(time: number): void;\n loadTimeFromLocalStorage?(): number | undefined;\n requestUpdate(property?: string): void;\n updateComplete: Promise<boolean>;\n playing: boolean;\n loop: boolean;\n play(): void;\n pause(): void;\n playbackController?: PlaybackController;\n parentTimegroup?: any;\n rootTimegroup?: any;\n}\n\nexport type PlaybackControllerUpdateEvent = {\n property: \"playing\" | \"loop\" | \"currentTimeMs\";\n value: boolean | number;\n};\n\n/**\n * Manages playback state and audio-driven timing for root temporal elements\n *\n * Created automatically when a temporal element becomes a root (no parent timegroup)\n * Provides playback contexts (playing, loop, currentTimeMs, durationMs) to descendants\n * Handles:\n * - Audio-driven playback with Web Audio API\n * - Seek and frame rendering throttling\n * - Time state management with pending seek handling\n * - Playback loop behavior\n *\n * Works with any temporal element (timegroups or standalone media) via PlaybackHost interface\n */\nexport class PlaybackController implements ReactiveController {\n #host: PlaybackHost;\n #playing = false;\n #loop = false;\n #listeners = new Set<(event: PlaybackControllerUpdateEvent) => void>();\n #playingProvider: ContextProvider<typeof playingContext>;\n #loopProvider: ContextProvider<typeof loopContext>;\n #currentTimeMsProvider: ContextProvider<typeof currentTimeContext>;\n #durationMsProvider: ContextProvider<typeof durationContext>;\n\n #FPS = 30;\n #MS_PER_FRAME = 1000 / this.#FPS;\n #playbackAudioContext: AudioContext | null = null;\n #playbackAnimationFrameRequest: number | null = null;\n #AUDIO_PLAYBACK_SLICE_MS = ((47 * 1024) / 48000) * 1000;\n\n #frameTaskInProgress = false;\n #pendingFrameTaskRun = false;\n #processingPendingFrameTask = false;\n\n #currentTime: number | undefined = undefined;\n #seekInProgress = false;\n #pendingSeekTime: number | undefined;\n #processingPendingSeek = false;\n #loopingPlayback = false; // Track if we're in a looping playback session\n #playbackWrapTimeSeconds = 0; // The AudioContext time when we wrapped\n\n seekTask!: Task<readonly [number | undefined], number | undefined>;\n\n constructor(host: PlaybackHost) {\n this.#host = host;\n host.addController(this);\n\n this.seekTask = new Task(this.#host, {\n autoRun: false,\n args: () => [this.#pendingSeekTime ?? this.#currentTime] as const,\n onComplete: () => {},\n task: async ([targetTime]) => {\n await this.#host.waitForMediaDurations?.();\n const newTime = Math.max(\n 0,\n Math.min(targetTime ?? 0, this.#host.durationMs / 1000),\n );\n this.#currentTime = newTime;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: this.currentTimeMs,\n });\n await this.runThrottledFrameTask();\n this.#host.saveTimeToLocalStorage?.(newTime);\n this.#seekInProgress = false;\n return newTime;\n },\n });\n\n this.#playingProvider = new ContextProvider(host, {\n context: playingContext,\n initialValue: this.#playing,\n });\n this.#loopProvider = new ContextProvider(host, {\n context: loopContext,\n initialValue: this.#loop,\n });\n this.#currentTimeMsProvider = new ContextProvider(host, {\n context: currentTimeContext,\n initialValue: host.currentTimeMs,\n });\n this.#durationMsProvider = new ContextProvider(host, {\n context: durationContext,\n initialValue: host.durationMs,\n });\n }\n\n get currentTime(): number {\n const rawTime = this.#currentTime ?? 0;\n // Quantize to frame boundaries based on host's fps\n const fps = (this.#host as any).fps ?? 30;\n if (!fps || fps <= 0) return rawTime;\n const frameDurationS = 1 / fps;\n return Math.round(rawTime / frameDurationS) * frameDurationS;\n }\n\n set currentTime(time: number) {\n time = Math.max(0, Math.min(this.#host.durationMs / 1000, time));\n if (Number.isNaN(time)) {\n return;\n }\n if (time === this.#currentTime && !this.#processingPendingSeek) {\n return;\n }\n if (this.#pendingSeekTime === time) {\n return;\n }\n\n if (this.#seekInProgress) {\n this.#pendingSeekTime = time;\n this.#currentTime = time;\n return;\n }\n\n this.#currentTime = time;\n this.#seekInProgress = true;\n\n this.seekTask.run().finally(() => {\n if (\n this.#pendingSeekTime !== undefined &&\n this.#pendingSeekTime !== time\n ) {\n const pendingTime = this.#pendingSeekTime;\n this.#pendingSeekTime = undefined;\n this.#processingPendingSeek = true;\n try {\n this.currentTime = pendingTime;\n } finally {\n this.#processingPendingSeek = false;\n }\n } else {\n this.#pendingSeekTime = undefined;\n }\n });\n }\n\n get playing(): boolean {\n return this.#playing;\n }\n\n setPlaying(value: boolean): void {\n if (this.#playing === value) return;\n this.#playing = value;\n this.#playingProvider.setValue(value);\n this.#host.requestUpdate(\"playing\");\n this.#notifyListeners({ property: \"playing\", value });\n\n if (value) {\n this.startPlayback();\n } else {\n this.stopPlayback();\n }\n }\n\n get loop(): boolean {\n return this.#loop;\n }\n\n setLoop(value: boolean): void {\n if (this.#loop === value) return;\n this.#loop = value;\n this.#loopProvider.setValue(value);\n this.#host.requestUpdate(\"loop\");\n this.#notifyListeners({ property: \"loop\", value });\n }\n\n get currentTimeMs(): number {\n return this.currentTime * 1000;\n }\n\n setCurrentTimeMs(value: number): void {\n this.currentTime = value / 1000;\n }\n\n // Update time during playback without triggering a seek\n // Used by #syncPlayheadToAudioContext to avoid frame drops\n #updatePlaybackTime(timeMs: number): void {\n const timeSec = timeMs / 1000;\n if (this.#currentTime === timeSec) {\n return;\n }\n this.#currentTime = timeSec;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(timeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: timeMs,\n });\n // Trigger frame rendering without the async seek mechanism\n this.runThrottledFrameTask();\n }\n\n play(): void {\n this.setPlaying(true);\n }\n\n pause(): void {\n this.setPlaying(false);\n }\n\n hostConnected(): void {\n if (this.#playing) {\n this.startPlayback();\n } else {\n this.#host.waitForMediaDurations?.().then(() => {\n const maybeLoadedTime = this.#host.loadTimeFromLocalStorage?.();\n if (maybeLoadedTime !== undefined) {\n this.currentTime = maybeLoadedTime;\n } else if (this.#currentTime === undefined) {\n this.#currentTime = 0;\n }\n if (EF_INTERACTIVE && this.seekTask.status === TaskStatus.INITIAL) {\n this.seekTask.run();\n }\n });\n }\n }\n\n hostDisconnected(): void {\n this.pause();\n }\n\n hostUpdated(): void {\n this.#durationMsProvider.setValue(this.#host.durationMs);\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n }\n\n async runThrottledFrameTask(): Promise<void> {\n if (this.#frameTaskInProgress) {\n this.#pendingFrameTaskRun = true;\n while (this.#frameTaskInProgress) {\n await this.#host.frameTask.taskComplete;\n }\n return;\n }\n\n this.#frameTaskInProgress = true;\n\n try {\n await this.#host.frameTask.run();\n } catch (error) {\n console.error(\"Frame task error:\", error);\n } finally {\n this.#frameTaskInProgress = false;\n\n if (this.#pendingFrameTaskRun && !this.#processingPendingFrameTask) {\n this.#pendingFrameTaskRun = false;\n this.#processingPendingFrameTask = true;\n try {\n await this.runThrottledFrameTask();\n } finally {\n this.#processingPendingFrameTask = false;\n }\n } else {\n this.#pendingFrameTaskRun = false;\n }\n }\n }\n\n addListener(listener: (event: PlaybackControllerUpdateEvent) => void): void {\n this.#listeners.add(listener);\n }\n\n removeListener(\n listener: (event: PlaybackControllerUpdateEvent) => void,\n ): void {\n this.#listeners.delete(listener);\n }\n\n #notifyListeners(event: PlaybackControllerUpdateEvent): void {\n for (const listener of this.#listeners) {\n listener(event);\n }\n }\n\n remove(): void {\n this.stopPlayback();\n this.#listeners.clear();\n this.#host.removeController(this);\n }\n\n #syncPlayheadToAudioContext(startMs: number) {\n const audioContextTime = this.#playbackAudioContext?.currentTime ?? 0;\n const endMs = this.#host.endTimeMs;\n\n // Calculate raw time based on audio context\n let rawTimeMs: number;\n if (\n this.#playbackWrapTimeSeconds > 0 &&\n audioContextTime >= this.#playbackWrapTimeSeconds\n ) {\n // After wrap: time since wrap, wrapped to duration\n const timeSinceWrap =\n (audioContextTime - this.#playbackWrapTimeSeconds) * 1000;\n rawTimeMs = timeSinceWrap % endMs;\n } else {\n // Before wrap or no wrap: normal calculation\n rawTimeMs = startMs + audioContextTime * 1000;\n\n // If looping and we've reached the end, wrap around\n if (this.#loopingPlayback && rawTimeMs >= endMs) {\n rawTimeMs = rawTimeMs % endMs;\n }\n }\n\n const nextTimeMs =\n Math.round(rawTimeMs / this.#MS_PER_FRAME) * this.#MS_PER_FRAME;\n\n // During playback, update time directly without triggering seek\n // This avoids frame drops at the loop boundary\n this.#updatePlaybackTime(nextTimeMs);\n\n // Only check for end if we haven't already handled looping\n if (!this.#loopingPlayback && nextTimeMs >= endMs) {\n this.maybeLoopPlayback();\n return;\n }\n\n this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {\n this.#syncPlayheadToAudioContext(startMs);\n });\n }\n\n private async maybeLoopPlayback() {\n if (this.#loop) {\n // Loop enabled: reset to beginning and restart playback\n // We restart the audio system directly without changing #playing state\n // to keep the play button in sync\n this.setCurrentTimeMs(0);\n // Restart in next frame without awaiting to minimize gap\n requestAnimationFrame(() => {\n this.startPlayback();\n });\n } else {\n // No loop: reset to beginning and stop\n // This ensures play button works when clicked again\n this.setCurrentTimeMs(0);\n this.pause();\n }\n }\n\n private async stopPlayback() {\n if (this.#playbackAudioContext) {\n if (this.#playbackAudioContext.state !== \"closed\") {\n await this.#playbackAudioContext.close();\n }\n }\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#playbackAudioContext = null;\n this.#playbackAnimationFrameRequest = null;\n }\n\n private async startPlayback() {\n await this.stopPlayback();\n const host = this.#host;\n if (!host) {\n return;\n }\n\n if (host.waitForMediaDurations) {\n await host.waitForMediaDurations();\n }\n\n const currentMs = this.currentTimeMs;\n const fromMs = currentMs;\n const toMs = host.endTimeMs;\n\n if (fromMs >= toMs) {\n this.pause();\n return;\n }\n\n let bufferCount = 0;\n this.#playbackAudioContext = new AudioContext({\n latencyHint: \"playback\",\n });\n this.#loopingPlayback = this.#loop; // Remember if we're in a looping session\n this.#playbackWrapTimeSeconds = 0; // Reset wrap time\n\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#syncPlayheadToAudioContext(currentMs);\n const playbackContext = this.#playbackAudioContext;\n if (playbackContext.state === \"suspended\") {\n console.warn(\n \"AudioContext is suspended, media playback will not work until user has interacted with page.\",\n );\n this.setPlaying(false);\n return;\n }\n await playbackContext.suspend();\n\n // Track the logical media time (what position in the media we're rendering)\n // vs the AudioContext schedule time (when to play it)\n let logicalTimeMs = currentMs;\n let audioContextTimeMs = 0; // Tracks the schedule position in the AudioContext timeline\n let hasWrapped = false;\n\n const fillBuffer = async () => {\n if (bufferCount > 2) {\n return;\n }\n const canFillBuffer = await queueBufferSource();\n if (canFillBuffer) {\n fillBuffer();\n }\n };\n\n const queueBufferSource = async () => {\n // Check if we've already wrapped and aren't looping anymore\n if (hasWrapped && !this.#loopingPlayback) {\n return false;\n }\n\n const startMs = logicalTimeMs;\n const endMs = Math.min(\n logicalTimeMs + this.#AUDIO_PLAYBACK_SLICE_MS,\n toMs,\n );\n\n // Will this slice reach the end?\n const willReachEnd = endMs >= toMs;\n\n if (!host.renderAudio) {\n return false;\n }\n\n const audioBuffer = await host.renderAudio(startMs, endMs);\n bufferCount++;\n const source = playbackContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(playbackContext.destination);\n // Schedule this buffer to play at the current audioContextTime position\n source.start(audioContextTimeMs / 1000);\n\n const sliceDurationMs = endMs - startMs;\n\n source.onended = () => {\n bufferCount--;\n\n if (willReachEnd) {\n if (!this.#loopingPlayback) {\n // Not looping, end playback\n this.maybeLoopPlayback();\n } else {\n // Looping: continue filling buffer after wrap\n fillBuffer();\n }\n } else {\n // Continue filling buffer\n fillBuffer();\n }\n };\n\n // Advance the AudioContext schedule time\n audioContextTimeMs += sliceDurationMs;\n\n // If this buffer reaches the end and we're looping, immediately queue the wraparound\n if (willReachEnd && this.#loopingPlayback) {\n // Mark that we've wrapped\n hasWrapped = true;\n // Store when we wrapped (relative to when playback started, which is time 0 in AudioContext)\n // This is the duration from start to end\n this.#playbackWrapTimeSeconds = (toMs - fromMs) / 1000;\n // Reset logical time to beginning\n logicalTimeMs = 0;\n // Continue buffering will happen in fillBuffer() call below\n } else {\n // Normal advance\n logicalTimeMs = endMs;\n }\n\n return true;\n };\n\n try {\n await fillBuffer();\n await playbackContext.resume();\n } catch (error) {\n // Ignore errors if AudioContext is closed or during test cleanup\n if (\n error instanceof Error &&\n (error.name === \"InvalidStateError\" || error.message.includes(\"closed\"))\n ) {\n return;\n }\n throw error;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlaybackController.js","names":["#FPS","#host","#pendingSeekTime","#currentTime","#currentTimeMsProvider","#notifyListeners","#seekInProgress","#playingProvider","#playing","#loopProvider","#loop","#durationMsProvider","#processingPendingSeek","#frameTaskInProgress","#pendingFrameTaskRun","#processingPendingFrameTask","#listeners","#pendingAudioContext","#playbackAudioContext","rawTimeMs: number","#playbackWrapTimeSeconds","#loopingPlayback","#MS_PER_FRAME","#updatePlaybackTime","#playbackAnimationFrameRequest","#syncPlayheadToAudioContext","#AUDIO_PLAYBACK_SLICE_MS"],"sources":["../../src/gui/PlaybackController.ts"],"sourcesContent":["import { ContextProvider } from \"@lit/context\";\nimport { Task, TaskStatus } from \"@lit/task\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { EF_INTERACTIVE } from \"../EF_INTERACTIVE.js\";\nimport { currentTimeContext } from \"./currentTimeContext.js\";\nimport { durationContext } from \"./durationContext.js\";\nimport { loopContext, playingContext } from \"./playingContext.js\";\n\ninterface PlaybackHost extends HTMLElement, ReactiveControllerHost {\n currentTimeMs: number;\n durationMs: number;\n endTimeMs: number;\n frameTask: { run(): void; taskComplete: Promise<unknown> };\n renderAudio?(fromMs: number, toMs: number): Promise<AudioBuffer>;\n waitForMediaDurations?(): Promise<void>;\n saveTimeToLocalStorage?(time: number): void;\n loadTimeFromLocalStorage?(): number | undefined;\n requestUpdate(property?: string): void;\n updateComplete: Promise<boolean>;\n playing: boolean;\n loop: boolean;\n play(): void;\n pause(): void;\n playbackController?: PlaybackController;\n parentTimegroup?: any;\n rootTimegroup?: any;\n}\n\nexport type PlaybackControllerUpdateEvent = {\n property: \"playing\" | \"loop\" | \"currentTimeMs\";\n value: boolean | number;\n};\n\n/**\n * Manages playback state and audio-driven timing for root temporal elements\n *\n * Created automatically when a temporal element becomes a root (no parent timegroup)\n * Provides playback contexts (playing, loop, currentTimeMs, durationMs) to descendants\n * Handles:\n * - Audio-driven playback with Web Audio API\n * - Seek and frame rendering throttling\n * - Time state management with pending seek handling\n * - Playback loop behavior\n *\n * Works with any temporal element (timegroups or standalone media) via PlaybackHost interface\n */\nexport class PlaybackController implements ReactiveController {\n #host: PlaybackHost;\n #playing = false;\n #loop = false;\n #listeners = new Set<(event: PlaybackControllerUpdateEvent) => void>();\n #playingProvider: ContextProvider<typeof playingContext>;\n #loopProvider: ContextProvider<typeof loopContext>;\n #currentTimeMsProvider: ContextProvider<typeof currentTimeContext>;\n #durationMsProvider: ContextProvider<typeof durationContext>;\n\n #FPS = 30;\n #MS_PER_FRAME = 1000 / this.#FPS;\n #playbackAudioContext: AudioContext | null = null;\n #playbackAnimationFrameRequest: number | null = null;\n #pendingAudioContext: AudioContext | null = null;\n #AUDIO_PLAYBACK_SLICE_MS = ((47 * 1024) / 48000) * 1000;\n\n #frameTaskInProgress = false;\n #pendingFrameTaskRun = false;\n #processingPendingFrameTask = false;\n\n #currentTime: number | undefined = undefined;\n #seekInProgress = false;\n #pendingSeekTime: number | undefined;\n #processingPendingSeek = false;\n #loopingPlayback = false; // Track if we're in a looping playback session\n #playbackWrapTimeSeconds = 0; // The AudioContext time when we wrapped\n\n seekTask!: Task<readonly [number | undefined], number | undefined>;\n\n constructor(host: PlaybackHost) {\n this.#host = host;\n host.addController(this);\n\n this.seekTask = new Task(this.#host, {\n autoRun: false,\n args: () => [this.#pendingSeekTime ?? this.#currentTime] as const,\n onComplete: () => {},\n task: async ([targetTime]) => {\n await this.#host.waitForMediaDurations?.();\n const newTime = Math.max(\n 0,\n Math.min(targetTime ?? 0, this.#host.durationMs / 1000),\n );\n this.#currentTime = newTime;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: this.currentTimeMs,\n });\n await this.runThrottledFrameTask();\n this.#host.saveTimeToLocalStorage?.(newTime);\n this.#seekInProgress = false;\n return newTime;\n },\n });\n\n this.#playingProvider = new ContextProvider(host, {\n context: playingContext,\n initialValue: this.#playing,\n });\n this.#loopProvider = new ContextProvider(host, {\n context: loopContext,\n initialValue: this.#loop,\n });\n this.#currentTimeMsProvider = new ContextProvider(host, {\n context: currentTimeContext,\n initialValue: host.currentTimeMs,\n });\n this.#durationMsProvider = new ContextProvider(host, {\n context: durationContext,\n initialValue: host.durationMs,\n });\n }\n\n get currentTime(): number {\n const rawTime = this.#currentTime ?? 0;\n // Quantize to frame boundaries based on host's fps\n const fps = (this.#host as any).fps ?? 30;\n if (!fps || fps <= 0) return rawTime;\n const frameDurationS = 1 / fps;\n return Math.round(rawTime / frameDurationS) * frameDurationS;\n }\n\n set currentTime(time: number) {\n time = Math.max(0, Math.min(this.#host.durationMs / 1000, time));\n if (Number.isNaN(time)) {\n return;\n }\n if (time === this.#currentTime && !this.#processingPendingSeek) {\n return;\n }\n if (this.#pendingSeekTime === time) {\n return;\n }\n\n if (this.#seekInProgress) {\n this.#pendingSeekTime = time;\n this.#currentTime = time;\n return;\n }\n\n this.#currentTime = time;\n this.#seekInProgress = true;\n\n this.seekTask.run().finally(() => {\n if (\n this.#pendingSeekTime !== undefined &&\n this.#pendingSeekTime !== time\n ) {\n const pendingTime = this.#pendingSeekTime;\n this.#pendingSeekTime = undefined;\n this.#processingPendingSeek = true;\n try {\n this.currentTime = pendingTime;\n } finally {\n this.#processingPendingSeek = false;\n }\n } else {\n this.#pendingSeekTime = undefined;\n }\n });\n }\n\n get playing(): boolean {\n return this.#playing;\n }\n\n setPlaying(value: boolean): void {\n if (this.#playing === value) return;\n this.#playing = value;\n this.#playingProvider.setValue(value);\n this.#host.requestUpdate(\"playing\");\n this.#notifyListeners({ property: \"playing\", value });\n\n if (value) {\n this.startPlayback();\n } else {\n this.stopPlayback();\n }\n }\n\n get loop(): boolean {\n return this.#loop;\n }\n\n setLoop(value: boolean): void {\n if (this.#loop === value) return;\n this.#loop = value;\n this.#loopProvider.setValue(value);\n this.#host.requestUpdate(\"loop\");\n this.#notifyListeners({ property: \"loop\", value });\n }\n\n get currentTimeMs(): number {\n return this.currentTime * 1000;\n }\n\n setCurrentTimeMs(value: number): void {\n this.currentTime = value / 1000;\n }\n\n // Update time during playback without triggering a seek\n // Used by #syncPlayheadToAudioContext to avoid frame drops\n #updatePlaybackTime(timeMs: number): void {\n const timeSec = timeMs / 1000;\n if (this.#currentTime === timeSec) {\n return;\n }\n this.#currentTime = timeSec;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(timeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: timeMs,\n });\n // Trigger frame rendering without the async seek mechanism\n this.runThrottledFrameTask();\n }\n\n play(): void {\n this.setPlaying(true);\n }\n\n pause(): void {\n this.setPlaying(false);\n }\n\n hostConnected(): void {\n if (this.#playing) {\n this.startPlayback();\n } else {\n this.#host.waitForMediaDurations?.().then(() => {\n const maybeLoadedTime = this.#host.loadTimeFromLocalStorage?.();\n if (maybeLoadedTime !== undefined) {\n this.currentTime = maybeLoadedTime;\n } else if (this.#currentTime === undefined) {\n this.#currentTime = 0;\n }\n if (EF_INTERACTIVE && this.seekTask.status === TaskStatus.INITIAL) {\n this.seekTask.run();\n }\n });\n }\n }\n\n hostDisconnected(): void {\n this.pause();\n }\n\n hostUpdated(): void {\n this.#durationMsProvider.setValue(this.#host.durationMs);\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n }\n\n async runThrottledFrameTask(): Promise<void> {\n if (this.#frameTaskInProgress) {\n this.#pendingFrameTaskRun = true;\n while (this.#frameTaskInProgress) {\n await this.#host.frameTask.taskComplete;\n }\n return;\n }\n\n this.#frameTaskInProgress = true;\n\n try {\n await this.#host.frameTask.run();\n } catch (error) {\n console.error(\"Frame task error:\", error);\n } finally {\n this.#frameTaskInProgress = false;\n\n if (this.#pendingFrameTaskRun && !this.#processingPendingFrameTask) {\n this.#pendingFrameTaskRun = false;\n this.#processingPendingFrameTask = true;\n try {\n await this.runThrottledFrameTask();\n } finally {\n this.#processingPendingFrameTask = false;\n }\n } else {\n this.#pendingFrameTaskRun = false;\n }\n }\n }\n\n addListener(listener: (event: PlaybackControllerUpdateEvent) => void): void {\n this.#listeners.add(listener);\n }\n\n removeListener(\n listener: (event: PlaybackControllerUpdateEvent) => void,\n ): void {\n this.#listeners.delete(listener);\n }\n\n #notifyListeners(event: PlaybackControllerUpdateEvent): void {\n for (const listener of this.#listeners) {\n listener(event);\n }\n }\n\n remove(): void {\n this.stopPlayback();\n this.#listeners.clear();\n this.#host.removeController(this);\n }\n\n setPendingAudioContext(context: AudioContext): void {\n this.#pendingAudioContext = context;\n }\n\n #syncPlayheadToAudioContext(startMs: number) {\n const audioContextTime = this.#playbackAudioContext?.currentTime ?? 0;\n const endMs = this.#host.endTimeMs;\n\n // Calculate raw time based on audio context\n let rawTimeMs: number;\n if (\n this.#playbackWrapTimeSeconds > 0 &&\n audioContextTime >= this.#playbackWrapTimeSeconds\n ) {\n // After wrap: time since wrap, wrapped to duration\n const timeSinceWrap =\n (audioContextTime - this.#playbackWrapTimeSeconds) * 1000;\n rawTimeMs = timeSinceWrap % endMs;\n } else {\n // Before wrap or no wrap: normal calculation\n rawTimeMs = startMs + audioContextTime * 1000;\n\n // If looping and we've reached the end, wrap around\n if (this.#loopingPlayback && rawTimeMs >= endMs) {\n rawTimeMs = rawTimeMs % endMs;\n }\n }\n\n const nextTimeMs =\n Math.round(rawTimeMs / this.#MS_PER_FRAME) * this.#MS_PER_FRAME;\n\n // During playback, update time directly without triggering seek\n // This avoids frame drops at the loop boundary\n this.#updatePlaybackTime(nextTimeMs);\n\n // Only check for end if we haven't already handled looping\n if (!this.#loopingPlayback && nextTimeMs >= endMs) {\n this.maybeLoopPlayback();\n return;\n }\n\n this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {\n this.#syncPlayheadToAudioContext(startMs);\n });\n }\n\n private async maybeLoopPlayback() {\n if (this.#loop) {\n // Loop enabled: reset to beginning and restart playback\n // We restart the audio system directly without changing #playing state\n // to keep the play button in sync\n this.setCurrentTimeMs(0);\n // Restart in next frame without awaiting to minimize gap\n requestAnimationFrame(() => {\n this.startPlayback();\n });\n } else {\n // No loop: reset to beginning and stop\n // This ensures play button works when clicked again\n this.setCurrentTimeMs(0);\n this.pause();\n }\n }\n\n private async stopPlayback() {\n if (this.#playbackAudioContext) {\n if (this.#playbackAudioContext.state !== \"closed\") {\n await this.#playbackAudioContext.close();\n }\n }\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#playbackAudioContext = null;\n this.#playbackAnimationFrameRequest = null;\n this.#pendingAudioContext = null;\n }\n\n private async startPlayback() {\n await this.stopPlayback();\n const host = this.#host;\n if (!host) {\n return;\n }\n\n if (host.waitForMediaDurations) {\n await host.waitForMediaDurations();\n }\n\n const currentMs = this.currentTimeMs;\n const fromMs = currentMs;\n const toMs = host.endTimeMs;\n\n if (fromMs >= toMs) {\n this.pause();\n return;\n }\n\n let bufferCount = 0;\n // Check for pre-resumed AudioContext from synchronous user interaction\n if (this.#pendingAudioContext) {\n this.#playbackAudioContext = this.#pendingAudioContext;\n this.#pendingAudioContext = null;\n } else {\n this.#playbackAudioContext = new AudioContext({\n latencyHint: \"playback\",\n });\n }\n this.#loopingPlayback = this.#loop; // Remember if we're in a looping session\n this.#playbackWrapTimeSeconds = 0; // Reset wrap time\n\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#syncPlayheadToAudioContext(currentMs);\n const playbackContext = this.#playbackAudioContext;\n\n // Check if context is suspended (fallback for newly-created contexts)\n if (playbackContext.state === \"suspended\") {\n // Attempt to resume (may not work on mobile if user interaction context is lost)\n try {\n await playbackContext.resume();\n // Check state again after resume attempt\n if (playbackContext.state === \"suspended\") {\n console.warn(\n \"AudioContext is suspended and resume() failed. \" +\n \"On mobile devices, AudioContext.resume() must be called synchronously within a user interaction handler. \" +\n \"Media playback will not work until user has interacted with page.\",\n );\n this.setPlaying(false);\n return;\n }\n } catch (error) {\n console.warn(\n \"Failed to resume AudioContext:\",\n error,\n \"On mobile devices, AudioContext.resume() must be called synchronously within a user interaction handler.\",\n );\n this.setPlaying(false);\n return;\n }\n }\n await playbackContext.suspend();\n\n // Track the logical media time (what position in the media we're rendering)\n // vs the AudioContext schedule time (when to play it)\n let logicalTimeMs = currentMs;\n let audioContextTimeMs = 0; // Tracks the schedule position in the AudioContext timeline\n let hasWrapped = false;\n\n const fillBuffer = async () => {\n if (bufferCount > 2) {\n return;\n }\n const canFillBuffer = await queueBufferSource();\n if (canFillBuffer) {\n fillBuffer();\n }\n };\n\n const queueBufferSource = async () => {\n // Check if we've already wrapped and aren't looping anymore\n if (hasWrapped && !this.#loopingPlayback) {\n return false;\n }\n\n const startMs = logicalTimeMs;\n const endMs = Math.min(\n logicalTimeMs + this.#AUDIO_PLAYBACK_SLICE_MS,\n toMs,\n );\n\n // Will this slice reach the end?\n const willReachEnd = endMs >= toMs;\n\n if (!host.renderAudio) {\n return false;\n }\n\n const audioBuffer = await host.renderAudio(startMs, endMs);\n bufferCount++;\n const source = playbackContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(playbackContext.destination);\n // Schedule this buffer to play at the current audioContextTime position\n source.start(audioContextTimeMs / 1000);\n\n const sliceDurationMs = endMs - startMs;\n\n source.onended = () => {\n bufferCount--;\n\n if (willReachEnd) {\n if (!this.#loopingPlayback) {\n // Not looping, end playback\n this.maybeLoopPlayback();\n } else {\n // Looping: continue filling buffer after wrap\n fillBuffer();\n }\n } else {\n // Continue filling buffer\n fillBuffer();\n }\n };\n\n // Advance the AudioContext schedule time\n audioContextTimeMs += sliceDurationMs;\n\n // If this buffer reaches the end and we're looping, immediately queue the wraparound\n if (willReachEnd && this.#loopingPlayback) {\n // Mark that we've wrapped\n hasWrapped = true;\n // Store when we wrapped (relative to when playback started, which is time 0 in AudioContext)\n // This is the duration from start to end\n this.#playbackWrapTimeSeconds = (toMs - fromMs) / 1000;\n // Reset logical time to beginning\n logicalTimeMs = 0;\n // Continue buffering will happen in fillBuffer() call below\n } else {\n // Normal advance\n logicalTimeMs = endMs;\n }\n\n return true;\n };\n\n try {\n await fillBuffer();\n await playbackContext.resume();\n } catch (error) {\n // Ignore errors if AudioContext is closed or during test cleanup\n if (\n error instanceof Error &&\n (error.name === \"InvalidStateError\" || error.message.includes(\"closed\"))\n ) {\n return;\n }\n throw error;\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/gui/TWMixin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/gui/TWMixin.css?inline
|
|
2
|
-
var TWMixin_default = "/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n/* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n::before,\n::after {\n --tw-content: '';\n}\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n7. Disable tap highlights on iOS\n*/\nhtml,\n:host {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n -webkit-tap-highlight-color: transparent; /* 7 */\n}\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n/*\nRemove the default font size and weight for headings.\n*/\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\na {\n color: inherit;\n text-decoration: inherit;\n}\n/*\nAdd the correct font weight in Edge and Safari.\n*/\nb,\nstrong {\n font-weight: bolder;\n}\n/*\n1. Use the user's configured `mono` font-family by default.\n2. Use the user's configured `mono` font-feature-settings by default.\n3. Use the user's configured `mono` font-variation-settings by default.\n4. Correct the odd `em` font sizing in all browsers.\n*/\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n/*\nAdd the correct font size in all browsers.\n*/\nsmall {\n font-size: 80%;\n}\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n letter-spacing: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\nbutton,\nselect {\n text-transform: none;\n}\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\nbutton,\ninput:where([type='button']),\ninput:where([type='reset']),\ninput:where([type='submit']) {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n:-moz-focusring {\n outline: auto;\n}\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n:-moz-ui-invalid {\n box-shadow: none;\n}\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\nprogress {\n vertical-align: baseline;\n}\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n/*\nAdd the correct display in Chrome and Safari.\n*/\nsummary {\n display: list-item;\n}\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\nfieldset {\n margin: 0;\n padding: 0;\n}\nlegend {\n padding: 0;\n}\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n/*\nPrevent resizing textareas horizontally by default.\n*/\ntextarea {\n resize: vertical;\n}\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n/*\nSet the default cursor for buttons.\n*/\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden]:where(:not([hidden=\"until-found\"])) {\n display: none;\n}\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n.pointer-events-none {\n pointer-events: none;\n}\n.visible {\n visibility: visible;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.inset-0 {\n inset: 0px;\n}\n.left-0 {\n left: 0px;\n}\n.top-0 {\n top: 0px;\n}\n.isolate {\n isolation: isolate;\n}\n.z-10 {\n z-index: 10;\n}\n.z-20 {\n z-index: 20;\n}\n.z-\\[20\\] {\n z-index: 20;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.col-span-2 {\n grid-column: span 2 / span 2;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.mb-\\[1px\\] {\n margin-bottom: 1px;\n}\n.block {\n display: block;\n}\n.inline-block {\n display: inline-block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.contents {\n display: contents;\n}\n.hidden {\n display: none;\n}\n.size-full {\n width: 100%;\n height: 100%;\n}\n.h-\\[1\\.1rem\\] {\n height: 1.1rem;\n}\n.h-\\[200px\\] {\n height: 200px;\n}\n.h-\\[270px\\] {\n height: 270px;\n}\n.h-\\[300px\\] {\n height: 300px;\n}\n.h-\\[360px\\] {\n height: 360px;\n}\n.h-\\[500px\\] {\n height: 500px;\n}\n.h-\\[5px\\] {\n height: 5px;\n}\n.h-full {\n height: 100%;\n}\n.w-1 {\n width: 0.25rem;\n}\n.w-\\[1000px\\] {\n width: 1000px;\n}\n.w-\\[2px\\] {\n width: 2px;\n}\n.w-\\[480px\\] {\n width: 480px;\n}\n.w-\\[600px\\] {\n width: 600px;\n}\n.w-\\[640px\\] {\n width: 640px;\n}\n.w-full {\n width: 100%;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-crosshair {\n cursor: crosshair;\n}\n.touch-none {\n touch-action: none;\n}\n.touch-pan-x {\n --tw-pan-x: pan-x;\n touch-action: var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom);\n}\n.resize {\n resize: both;\n}\n.place-content-center {\n place-content: center;\n}\n.items-center {\n align-items: center;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-visible {\n overflow: visible;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.text-nowrap {\n text-wrap: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.border {\n border-width: 1px;\n}\n.border-r-2 {\n border-right-width: 2px;\n}\n.bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\n}\n.bg-lime-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(163 230 53 / var(--tw-bg-opacity, 1));\n}\n.bg-slate-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));\n}\n.bg-yellow-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));\n}\n.bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-0\\.5 {\n padding-left: 0.125rem;\n padding-right: 0.125rem;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pl-1 {\n padding-left: 0.25rem;\n}\n.pl-2 {\n padding-left: 0.5rem;\n}\n.pr-0 {\n padding-right: 0px;\n}\n.pr-1 {\n padding-right: 0.25rem;\n}\n.pt-\\[8px\\] {\n padding-top: 8px;\n}\n.text-center {\n text-align: center;\n}\n.font-mono {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n.text-\\[8px\\] {\n font-size: 8px;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-bold {\n font-weight: 700;\n}\n.ordinal {\n --tw-ordinal: ordinal;\n font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);\n}\n.text-black {\n --tw-text-opacity: 1;\n color: rgb(0 0 0 / var(--tw-text-opacity, 1));\n}\n.text-green-200 {\n --tw-text-opacity: 1;\n color: rgb(187 247 208 / var(--tw-text-opacity, 1));\n}\n.text-green-900 {\n --tw-text-opacity: 1;\n color: rgb(20 83 45 / var(--tw-text-opacity, 1));\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline {\n outline-style: solid;\n}\n.blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.invert {\n --tw-invert: invert(100%);\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-filter {\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ease-in {\n transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.ease-out {\n transition-timing-function: cubic-bezier(0, 0, 0.2, 1);\n}\n";
|
|
2
|
+
var TWMixin_default = "/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n/* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n::before,\n::after {\n --tw-content: '';\n}\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n7. Disable tap highlights on iOS\n*/\nhtml,\n:host {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n -webkit-tap-highlight-color: transparent; /* 7 */\n}\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n/*\nRemove the default font size and weight for headings.\n*/\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\na {\n color: inherit;\n text-decoration: inherit;\n}\n/*\nAdd the correct font weight in Edge and Safari.\n*/\nb,\nstrong {\n font-weight: bolder;\n}\n/*\n1. Use the user's configured `mono` font-family by default.\n2. Use the user's configured `mono` font-feature-settings by default.\n3. Use the user's configured `mono` font-variation-settings by default.\n4. Correct the odd `em` font sizing in all browsers.\n*/\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n/*\nAdd the correct font size in all browsers.\n*/\nsmall {\n font-size: 80%;\n}\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n letter-spacing: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\nbutton,\nselect {\n text-transform: none;\n}\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\nbutton,\ninput:where([type='button']),\ninput:where([type='reset']),\ninput:where([type='submit']) {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n:-moz-focusring {\n outline: auto;\n}\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n:-moz-ui-invalid {\n box-shadow: none;\n}\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\nprogress {\n vertical-align: baseline;\n}\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n/*\nAdd the correct display in Chrome and Safari.\n*/\nsummary {\n display: list-item;\n}\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\nfieldset {\n margin: 0;\n padding: 0;\n}\nlegend {\n padding: 0;\n}\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n/*\nPrevent resizing textareas horizontally by default.\n*/\ntextarea {\n resize: vertical;\n}\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n/*\nSet the default cursor for buttons.\n*/\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden]:where(:not([hidden=\"until-found\"])) {\n display: none;\n}\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n.pointer-events-none {\n pointer-events: none;\n}\n.visible {\n visibility: visible;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.inset-0 {\n inset: 0px;\n}\n.left-0 {\n left: 0px;\n}\n.top-0 {\n top: 0px;\n}\n.isolate {\n isolation: isolate;\n}\n.z-10 {\n z-index: 10;\n}\n.z-20 {\n z-index: 20;\n}\n.z-\\[20\\] {\n z-index: 20;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.col-span-2 {\n grid-column: span 2 / span 2;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.mb-\\[1px\\] {\n margin-bottom: 1px;\n}\n.block {\n display: block;\n}\n.inline-block {\n display: inline-block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.contents {\n display: contents;\n}\n.hidden {\n display: none;\n}\n.size-full {\n width: 100%;\n height: 100%;\n}\n.h-\\[1\\.1rem\\] {\n height: 1.1rem;\n}\n.h-\\[200px\\] {\n height: 200px;\n}\n.h-\\[270px\\] {\n height: 270px;\n}\n.h-\\[300px\\] {\n height: 300px;\n}\n.h-\\[360px\\] {\n height: 360px;\n}\n.h-\\[500px\\] {\n height: 500px;\n}\n.h-\\[5px\\] {\n height: 5px;\n}\n.h-full {\n height: 100%;\n}\n.w-1 {\n width: 0.25rem;\n}\n.w-\\[1000px\\] {\n width: 1000px;\n}\n.w-\\[2px\\] {\n width: 2px;\n}\n.w-\\[480px\\] {\n width: 480px;\n}\n.w-\\[600px\\] {\n width: 600px;\n}\n.w-\\[640px\\] {\n width: 640px;\n}\n.w-full {\n width: 100%;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-crosshair {\n cursor: crosshair;\n}\n.touch-none {\n touch-action: none;\n}\n.touch-pan-x {\n --tw-pan-x: pan-x;\n touch-action: var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom);\n}\n.resize {\n resize: both;\n}\n.place-content-center {\n place-content: center;\n}\n.items-center {\n align-items: center;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-visible {\n overflow: visible;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.text-nowrap {\n text-wrap: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.border {\n border-width: 1px;\n}\n.border-r-2 {\n border-right-width: 2px;\n}\n.bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\n}\n.bg-lime-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(163 230 53 / var(--tw-bg-opacity, 1));\n}\n.bg-slate-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));\n}\n.bg-yellow-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));\n}\n.bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-0\\.5 {\n padding-left: 0.125rem;\n padding-right: 0.125rem;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pl-1 {\n padding-left: 0.25rem;\n}\n.pl-2 {\n padding-left: 0.5rem;\n}\n.pr-0 {\n padding-right: 0px;\n}\n.pr-1 {\n padding-right: 0.25rem;\n}\n.pt-\\[8px\\] {\n padding-top: 8px;\n}\n.text-center {\n text-align: center;\n}\n.font-mono {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n.text-\\[8px\\] {\n font-size: 8px;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-bold {\n font-weight: 700;\n}\n.ordinal {\n --tw-ordinal: ordinal;\n font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);\n}\n.text-black {\n --tw-text-opacity: 1;\n color: rgb(0 0 0 / var(--tw-text-opacity, 1));\n}\n.text-green-200 {\n --tw-text-opacity: 1;\n color: rgb(187 247 208 / var(--tw-text-opacity, 1));\n}\n.text-green-900 {\n --tw-text-opacity: 1;\n color: rgb(20 83 45 / var(--tw-text-opacity, 1));\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline {\n outline-style: solid;\n}\n.blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-filter {\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ease-in {\n transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.ease-out {\n transition-timing-function: cubic-bezier(0, 0, 0.2, 1);\n}\n";
|
|
3
3
|
|
|
4
4
|
//#endregion
|
|
5
5
|
export { TWMixin_default as default };
|
package/dist/gui/TWMixin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TWMixin.js","names":[],"sources":["../../src/gui/TWMixin.css?inline"],"sourcesContent":["export default \"/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n*, ::before, ::after {\\n --tw-border-spacing-x: 0;\\n --tw-border-spacing-y: 0;\\n --tw-translate-x: 0;\\n --tw-translate-y: 0;\\n --tw-rotate: 0;\\n --tw-skew-x: 0;\\n --tw-skew-y: 0;\\n --tw-scale-x: 1;\\n --tw-scale-y: 1;\\n --tw-pan-x: ;\\n --tw-pan-y: ;\\n --tw-pinch-zoom: ;\\n --tw-scroll-snap-strictness: proximity;\\n --tw-gradient-from-position: ;\\n --tw-gradient-via-position: ;\\n --tw-gradient-to-position: ;\\n --tw-ordinal: ;\\n --tw-slashed-zero: ;\\n --tw-numeric-figure: ;\\n --tw-numeric-spacing: ;\\n --tw-numeric-fraction: ;\\n --tw-ring-inset: ;\\n --tw-ring-offset-width: 0px;\\n --tw-ring-offset-color: #fff;\\n --tw-ring-color: rgb(59 130 246 / 0.5);\\n --tw-ring-offset-shadow: 0 0 #0000;\\n --tw-ring-shadow: 0 0 #0000;\\n --tw-shadow: 0 0 #0000;\\n --tw-shadow-colored: 0 0 #0000;\\n --tw-blur: ;\\n --tw-brightness: ;\\n --tw-contrast: ;\\n --tw-grayscale: ;\\n --tw-hue-rotate: ;\\n --tw-invert: ;\\n --tw-saturate: ;\\n --tw-sepia: ;\\n --tw-drop-shadow: ;\\n --tw-backdrop-blur: ;\\n --tw-backdrop-brightness: ;\\n --tw-backdrop-contrast: ;\\n --tw-backdrop-grayscale: ;\\n --tw-backdrop-hue-rotate: ;\\n --tw-backdrop-invert: ;\\n --tw-backdrop-opacity: ;\\n --tw-backdrop-saturate: ;\\n --tw-backdrop-sepia: ;\\n --tw-contain-size: ;\\n --tw-contain-layout: ;\\n --tw-contain-paint: ;\\n --tw-contain-style: ;\\n}\\n::backdrop {\\n --tw-border-spacing-x: 0;\\n --tw-border-spacing-y: 0;\\n --tw-translate-x: 0;\\n --tw-translate-y: 0;\\n --tw-rotate: 0;\\n --tw-skew-x: 0;\\n --tw-skew-y: 0;\\n --tw-scale-x: 1;\\n --tw-scale-y: 1;\\n --tw-pan-x: ;\\n --tw-pan-y: ;\\n --tw-pinch-zoom: ;\\n --tw-scroll-snap-strictness: proximity;\\n --tw-gradient-from-position: ;\\n --tw-gradient-via-position: ;\\n --tw-gradient-to-position: ;\\n --tw-ordinal: ;\\n --tw-slashed-zero: ;\\n --tw-numeric-figure: ;\\n --tw-numeric-spacing: ;\\n --tw-numeric-fraction: ;\\n --tw-ring-inset: ;\\n --tw-ring-offset-width: 0px;\\n --tw-ring-offset-color: #fff;\\n --tw-ring-color: rgb(59 130 246 / 0.5);\\n --tw-ring-offset-shadow: 0 0 #0000;\\n --tw-ring-shadow: 0 0 #0000;\\n --tw-shadow: 0 0 #0000;\\n --tw-shadow-colored: 0 0 #0000;\\n --tw-blur: ;\\n --tw-brightness: ;\\n --tw-contrast: ;\\n --tw-grayscale: ;\\n --tw-hue-rotate: ;\\n --tw-invert: ;\\n --tw-saturate: ;\\n --tw-sepia: ;\\n --tw-drop-shadow: ;\\n --tw-backdrop-blur: ;\\n --tw-backdrop-brightness: ;\\n --tw-backdrop-contrast: ;\\n --tw-backdrop-grayscale: ;\\n --tw-backdrop-hue-rotate: ;\\n --tw-backdrop-invert: ;\\n --tw-backdrop-opacity: ;\\n --tw-backdrop-saturate: ;\\n --tw-backdrop-sepia: ;\\n --tw-contain-size: ;\\n --tw-contain-layout: ;\\n --tw-contain-paint: ;\\n --tw-contain-style: ;\\n}\\n/* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */\\n/*\\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\\n*/\\n*,\\n::before,\\n::after {\\n box-sizing: border-box; /* 1 */\\n border-width: 0; /* 2 */\\n border-style: solid; /* 2 */\\n border-color: #e5e7eb; /* 2 */\\n}\\n::before,\\n::after {\\n --tw-content: '';\\n}\\n/*\\n1. Use a consistent sensible line-height in all browsers.\\n2. Prevent adjustments of font size after orientation changes in iOS.\\n3. Use a more readable tab size.\\n4. Use the user's configured `sans` font-family by default.\\n5. Use the user's configured `sans` font-feature-settings by default.\\n6. Use the user's configured `sans` font-variation-settings by default.\\n7. Disable tap highlights on iOS\\n*/\\nhtml,\\n:host {\\n line-height: 1.5; /* 1 */\\n -webkit-text-size-adjust: 100%; /* 2 */\\n -moz-tab-size: 4; /* 3 */\\n -o-tab-size: 4;\\n tab-size: 4; /* 3 */\\n font-family: ui-sans-serif, system-ui, sans-serif, \\\"Apple Color Emoji\\\", \\\"Segoe UI Emoji\\\", \\\"Segoe UI Symbol\\\", \\\"Noto Color Emoji\\\"; /* 4 */\\n font-feature-settings: normal; /* 5 */\\n font-variation-settings: normal; /* 6 */\\n -webkit-tap-highlight-color: transparent; /* 7 */\\n}\\n/*\\n1. Remove the margin in all browsers.\\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\\n*/\\nbody {\\n margin: 0; /* 1 */\\n line-height: inherit; /* 2 */\\n}\\n/*\\n1. Add the correct height in Firefox.\\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\\n3. Ensure horizontal rules are visible by default.\\n*/\\nhr {\\n height: 0; /* 1 */\\n color: inherit; /* 2 */\\n border-top-width: 1px; /* 3 */\\n}\\n/*\\nAdd the correct text decoration in Chrome, Edge, and Safari.\\n*/\\nabbr:where([title]) {\\n -webkit-text-decoration: underline dotted;\\n text-decoration: underline dotted;\\n}\\n/*\\nRemove the default font size and weight for headings.\\n*/\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6 {\\n font-size: inherit;\\n font-weight: inherit;\\n}\\n/*\\nReset links to optimize for opt-in styling instead of opt-out.\\n*/\\na {\\n color: inherit;\\n text-decoration: inherit;\\n}\\n/*\\nAdd the correct font weight in Edge and Safari.\\n*/\\nb,\\nstrong {\\n font-weight: bolder;\\n}\\n/*\\n1. Use the user's configured `mono` font-family by default.\\n2. Use the user's configured `mono` font-feature-settings by default.\\n3. Use the user's configured `mono` font-variation-settings by default.\\n4. Correct the odd `em` font sizing in all browsers.\\n*/\\ncode,\\nkbd,\\nsamp,\\npre {\\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace; /* 1 */\\n font-feature-settings: normal; /* 2 */\\n font-variation-settings: normal; /* 3 */\\n font-size: 1em; /* 4 */\\n}\\n/*\\nAdd the correct font size in all browsers.\\n*/\\nsmall {\\n font-size: 80%;\\n}\\n/*\\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\\n*/\\nsub,\\nsup {\\n font-size: 75%;\\n line-height: 0;\\n position: relative;\\n vertical-align: baseline;\\n}\\nsub {\\n bottom: -0.25em;\\n}\\nsup {\\n top: -0.5em;\\n}\\n/*\\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\\n3. Remove gaps between table borders by default.\\n*/\\ntable {\\n text-indent: 0; /* 1 */\\n border-color: inherit; /* 2 */\\n border-collapse: collapse; /* 3 */\\n}\\n/*\\n1. Change the font styles in all browsers.\\n2. Remove the margin in Firefox and Safari.\\n3. Remove default padding in all browsers.\\n*/\\nbutton,\\ninput,\\noptgroup,\\nselect,\\ntextarea {\\n font-family: inherit; /* 1 */\\n font-feature-settings: inherit; /* 1 */\\n font-variation-settings: inherit; /* 1 */\\n font-size: 100%; /* 1 */\\n font-weight: inherit; /* 1 */\\n line-height: inherit; /* 1 */\\n letter-spacing: inherit; /* 1 */\\n color: inherit; /* 1 */\\n margin: 0; /* 2 */\\n padding: 0; /* 3 */\\n}\\n/*\\nRemove the inheritance of text transform in Edge and Firefox.\\n*/\\nbutton,\\nselect {\\n text-transform: none;\\n}\\n/*\\n1. Correct the inability to style clickable types in iOS and Safari.\\n2. Remove default button styles.\\n*/\\nbutton,\\ninput:where([type='button']),\\ninput:where([type='reset']),\\ninput:where([type='submit']) {\\n -webkit-appearance: button; /* 1 */\\n background-color: transparent; /* 2 */\\n background-image: none; /* 2 */\\n}\\n/*\\nUse the modern Firefox focus style for all focusable elements.\\n*/\\n:-moz-focusring {\\n outline: auto;\\n}\\n/*\\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\\n*/\\n:-moz-ui-invalid {\\n box-shadow: none;\\n}\\n/*\\nAdd the correct vertical alignment in Chrome and Firefox.\\n*/\\nprogress {\\n vertical-align: baseline;\\n}\\n/*\\nCorrect the cursor style of increment and decrement buttons in Safari.\\n*/\\n::-webkit-inner-spin-button,\\n::-webkit-outer-spin-button {\\n height: auto;\\n}\\n/*\\n1. Correct the odd appearance in Chrome and Safari.\\n2. Correct the outline style in Safari.\\n*/\\n[type='search'] {\\n -webkit-appearance: textfield; /* 1 */\\n outline-offset: -2px; /* 2 */\\n}\\n/*\\nRemove the inner padding in Chrome and Safari on macOS.\\n*/\\n::-webkit-search-decoration {\\n -webkit-appearance: none;\\n}\\n/*\\n1. Correct the inability to style clickable types in iOS and Safari.\\n2. Change font properties to `inherit` in Safari.\\n*/\\n::-webkit-file-upload-button {\\n -webkit-appearance: button; /* 1 */\\n font: inherit; /* 2 */\\n}\\n/*\\nAdd the correct display in Chrome and Safari.\\n*/\\nsummary {\\n display: list-item;\\n}\\n/*\\nRemoves the default spacing and border for appropriate elements.\\n*/\\nblockquote,\\ndl,\\ndd,\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6,\\nhr,\\nfigure,\\np,\\npre {\\n margin: 0;\\n}\\nfieldset {\\n margin: 0;\\n padding: 0;\\n}\\nlegend {\\n padding: 0;\\n}\\nol,\\nul,\\nmenu {\\n list-style: none;\\n margin: 0;\\n padding: 0;\\n}\\n/*\\nReset default styling for dialogs.\\n*/\\ndialog {\\n padding: 0;\\n}\\n/*\\nPrevent resizing textareas horizontally by default.\\n*/\\ntextarea {\\n resize: vertical;\\n}\\n/*\\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\\n2. Set the default placeholder color to the user's configured gray 400 color.\\n*/\\ninput::-moz-placeholder, textarea::-moz-placeholder {\\n opacity: 1; /* 1 */\\n color: #9ca3af; /* 2 */\\n}\\ninput::placeholder,\\ntextarea::placeholder {\\n opacity: 1; /* 1 */\\n color: #9ca3af; /* 2 */\\n}\\n/*\\nSet the default cursor for buttons.\\n*/\\nbutton,\\n[role=\\\"button\\\"] {\\n cursor: pointer;\\n}\\n/*\\nMake sure disabled buttons don't get the pointer cursor.\\n*/\\n:disabled {\\n cursor: default;\\n}\\n/*\\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\\n This can trigger a poorly considered lint error in some tools but is included by design.\\n*/\\nimg,\\nsvg,\\nvideo,\\ncanvas,\\naudio,\\niframe,\\nembed,\\nobject {\\n display: block; /* 1 */\\n vertical-align: middle; /* 2 */\\n}\\n/*\\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\\n*/\\nimg,\\nvideo {\\n max-width: 100%;\\n height: auto;\\n}\\n/* Make elements with the HTML hidden attribute stay hidden by default */\\n[hidden]:where(:not([hidden=\\\"until-found\\\"])) {\\n display: none;\\n}\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n.container {\\n width: 100%;\\n}\\n@media (min-width: 640px) {\\n .container {\\n max-width: 640px;\\n }\\n}\\n@media (min-width: 768px) {\\n .container {\\n max-width: 768px;\\n }\\n}\\n@media (min-width: 1024px) {\\n .container {\\n max-width: 1024px;\\n }\\n}\\n@media (min-width: 1280px) {\\n .container {\\n max-width: 1280px;\\n }\\n}\\n@media (min-width: 1536px) {\\n .container {\\n max-width: 1536px;\\n }\\n}\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n.pointer-events-none {\\n pointer-events: none;\\n}\\n.visible {\\n visibility: visible;\\n}\\n.invisible {\\n visibility: hidden;\\n}\\n.static {\\n position: static;\\n}\\n.fixed {\\n position: fixed;\\n}\\n.absolute {\\n position: absolute;\\n}\\n.relative {\\n position: relative;\\n}\\n.inset-0 {\\n inset: 0px;\\n}\\n.left-0 {\\n left: 0px;\\n}\\n.top-0 {\\n top: 0px;\\n}\\n.isolate {\\n isolation: isolate;\\n}\\n.z-10 {\\n z-index: 10;\\n}\\n.z-20 {\\n z-index: 20;\\n}\\n.z-\\\\[20\\\\] {\\n z-index: 20;\\n}\\n.z-\\\\[5\\\\] {\\n z-index: 5;\\n}\\n.col-span-2 {\\n grid-column: span 2 / span 2;\\n}\\n.mx-2 {\\n margin-left: 0.5rem;\\n margin-right: 0.5rem;\\n}\\n.mb-\\\\[1px\\\\] {\\n margin-bottom: 1px;\\n}\\n.block {\\n display: block;\\n}\\n.inline-block {\\n display: inline-block;\\n}\\n.inline {\\n display: inline;\\n}\\n.flex {\\n display: flex;\\n}\\n.grid {\\n display: grid;\\n}\\n.contents {\\n display: contents;\\n}\\n.hidden {\\n display: none;\\n}\\n.size-full {\\n width: 100%;\\n height: 100%;\\n}\\n.h-\\\\[1\\\\.1rem\\\\] {\\n height: 1.1rem;\\n}\\n.h-\\\\[200px\\\\] {\\n height: 200px;\\n}\\n.h-\\\\[270px\\\\] {\\n height: 270px;\\n}\\n.h-\\\\[300px\\\\] {\\n height: 300px;\\n}\\n.h-\\\\[360px\\\\] {\\n height: 360px;\\n}\\n.h-\\\\[500px\\\\] {\\n height: 500px;\\n}\\n.h-\\\\[5px\\\\] {\\n height: 5px;\\n}\\n.h-full {\\n height: 100%;\\n}\\n.w-1 {\\n width: 0.25rem;\\n}\\n.w-\\\\[1000px\\\\] {\\n width: 1000px;\\n}\\n.w-\\\\[2px\\\\] {\\n width: 2px;\\n}\\n.w-\\\\[480px\\\\] {\\n width: 480px;\\n}\\n.w-\\\\[600px\\\\] {\\n width: 600px;\\n}\\n.w-\\\\[640px\\\\] {\\n width: 640px;\\n}\\n.w-full {\\n width: 100%;\\n}\\n.transform {\\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\\n}\\n.cursor-crosshair {\\n cursor: crosshair;\\n}\\n.touch-none {\\n touch-action: none;\\n}\\n.touch-pan-x {\\n --tw-pan-x: pan-x;\\n touch-action: var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom);\\n}\\n.resize {\\n resize: both;\\n}\\n.place-content-center {\\n place-content: center;\\n}\\n.items-center {\\n align-items: center;\\n}\\n.overflow-auto {\\n overflow: auto;\\n}\\n.overflow-hidden {\\n overflow: hidden;\\n}\\n.overflow-visible {\\n overflow: visible;\\n}\\n.whitespace-nowrap {\\n white-space: nowrap;\\n}\\n.text-nowrap {\\n text-wrap: nowrap;\\n}\\n.rounded {\\n border-radius: 0.25rem;\\n}\\n.border {\\n border-width: 1px;\\n}\\n.border-r-2 {\\n border-right-width: 2px;\\n}\\n.bg-black {\\n --tw-bg-opacity: 1;\\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\\n}\\n.bg-lime-400 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(163 230 53 / var(--tw-bg-opacity, 1));\\n}\\n.bg-slate-500 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));\\n}\\n.bg-yellow-400 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));\\n}\\n.bg-opacity-20 {\\n --tw-bg-opacity: 0.2;\\n}\\n.object-contain {\\n -o-object-fit: contain;\\n object-fit: contain;\\n}\\n.p-4 {\\n padding: 1rem;\\n}\\n.p-\\\\[1px\\\\] {\\n padding: 1px;\\n}\\n.px-0\\\\.5 {\\n padding-left: 0.125rem;\\n padding-right: 0.125rem;\\n}\\n.pb-0 {\\n padding-bottom: 0px;\\n}\\n.pl-1 {\\n padding-left: 0.25rem;\\n}\\n.pl-2 {\\n padding-left: 0.5rem;\\n}\\n.pr-0 {\\n padding-right: 0px;\\n}\\n.pr-1 {\\n padding-right: 0.25rem;\\n}\\n.pt-\\\\[8px\\\\] {\\n padding-top: 8px;\\n}\\n.text-center {\\n text-align: center;\\n}\\n.font-mono {\\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace;\\n}\\n.text-\\\\[8px\\\\] {\\n font-size: 8px;\\n}\\n.text-sm {\\n font-size: 0.875rem;\\n line-height: 1.25rem;\\n}\\n.text-xs {\\n font-size: 0.75rem;\\n line-height: 1rem;\\n}\\n.font-bold {\\n font-weight: 700;\\n}\\n.ordinal {\\n --tw-ordinal: ordinal;\\n font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);\\n}\\n.text-black {\\n --tw-text-opacity: 1;\\n color: rgb(0 0 0 / var(--tw-text-opacity, 1));\\n}\\n.text-green-200 {\\n --tw-text-opacity: 1;\\n color: rgb(187 247 208 / var(--tw-text-opacity, 1));\\n}\\n.text-green-900 {\\n --tw-text-opacity: 1;\\n color: rgb(20 83 45 / var(--tw-text-opacity, 1));\\n}\\n.line-through {\\n text-decoration-line: line-through;\\n}\\n.opacity-50 {\\n opacity: 0.5;\\n}\\n.shadow {\\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\\n}\\n.outline {\\n outline-style: solid;\\n}\\n.blur {\\n --tw-blur: blur(8px);\\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\\n}\\n.invert {\\n --tw-invert: invert(100%);\\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\\n}\\n.filter {\\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\\n}\\n.backdrop-filter {\\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\\n}\\n.transition {\\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;\\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\\n transition-duration: 150ms;\\n}\\n.ease-in {\\n transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\\n}\\n.ease-in-out {\\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\\n}\\n.ease-out {\\n transition-timing-function: cubic-bezier(0, 0, 0.2, 1);\\n}\\n\""],"mappings":";AAAA,sBAAe"}
|
|
1
|
+
{"version":3,"file":"TWMixin.js","names":[],"sources":["../../src/gui/TWMixin.css?inline"],"sourcesContent":["export default \"/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n*, ::before, ::after {\\n --tw-border-spacing-x: 0;\\n --tw-border-spacing-y: 0;\\n --tw-translate-x: 0;\\n --tw-translate-y: 0;\\n --tw-rotate: 0;\\n --tw-skew-x: 0;\\n --tw-skew-y: 0;\\n --tw-scale-x: 1;\\n --tw-scale-y: 1;\\n --tw-pan-x: ;\\n --tw-pan-y: ;\\n --tw-pinch-zoom: ;\\n --tw-scroll-snap-strictness: proximity;\\n --tw-gradient-from-position: ;\\n --tw-gradient-via-position: ;\\n --tw-gradient-to-position: ;\\n --tw-ordinal: ;\\n --tw-slashed-zero: ;\\n --tw-numeric-figure: ;\\n --tw-numeric-spacing: ;\\n --tw-numeric-fraction: ;\\n --tw-ring-inset: ;\\n --tw-ring-offset-width: 0px;\\n --tw-ring-offset-color: #fff;\\n --tw-ring-color: rgb(59 130 246 / 0.5);\\n --tw-ring-offset-shadow: 0 0 #0000;\\n --tw-ring-shadow: 0 0 #0000;\\n --tw-shadow: 0 0 #0000;\\n --tw-shadow-colored: 0 0 #0000;\\n --tw-blur: ;\\n --tw-brightness: ;\\n --tw-contrast: ;\\n --tw-grayscale: ;\\n --tw-hue-rotate: ;\\n --tw-invert: ;\\n --tw-saturate: ;\\n --tw-sepia: ;\\n --tw-drop-shadow: ;\\n --tw-backdrop-blur: ;\\n --tw-backdrop-brightness: ;\\n --tw-backdrop-contrast: ;\\n --tw-backdrop-grayscale: ;\\n --tw-backdrop-hue-rotate: ;\\n --tw-backdrop-invert: ;\\n --tw-backdrop-opacity: ;\\n --tw-backdrop-saturate: ;\\n --tw-backdrop-sepia: ;\\n --tw-contain-size: ;\\n --tw-contain-layout: ;\\n --tw-contain-paint: ;\\n --tw-contain-style: ;\\n}\\n::backdrop {\\n --tw-border-spacing-x: 0;\\n --tw-border-spacing-y: 0;\\n --tw-translate-x: 0;\\n --tw-translate-y: 0;\\n --tw-rotate: 0;\\n --tw-skew-x: 0;\\n --tw-skew-y: 0;\\n --tw-scale-x: 1;\\n --tw-scale-y: 1;\\n --tw-pan-x: ;\\n --tw-pan-y: ;\\n --tw-pinch-zoom: ;\\n --tw-scroll-snap-strictness: proximity;\\n --tw-gradient-from-position: ;\\n --tw-gradient-via-position: ;\\n --tw-gradient-to-position: ;\\n --tw-ordinal: ;\\n --tw-slashed-zero: ;\\n --tw-numeric-figure: ;\\n --tw-numeric-spacing: ;\\n --tw-numeric-fraction: ;\\n --tw-ring-inset: ;\\n --tw-ring-offset-width: 0px;\\n --tw-ring-offset-color: #fff;\\n --tw-ring-color: rgb(59 130 246 / 0.5);\\n --tw-ring-offset-shadow: 0 0 #0000;\\n --tw-ring-shadow: 0 0 #0000;\\n --tw-shadow: 0 0 #0000;\\n --tw-shadow-colored: 0 0 #0000;\\n --tw-blur: ;\\n --tw-brightness: ;\\n --tw-contrast: ;\\n --tw-grayscale: ;\\n --tw-hue-rotate: ;\\n --tw-invert: ;\\n --tw-saturate: ;\\n --tw-sepia: ;\\n --tw-drop-shadow: ;\\n --tw-backdrop-blur: ;\\n --tw-backdrop-brightness: ;\\n --tw-backdrop-contrast: ;\\n --tw-backdrop-grayscale: ;\\n --tw-backdrop-hue-rotate: ;\\n --tw-backdrop-invert: ;\\n --tw-backdrop-opacity: ;\\n --tw-backdrop-saturate: ;\\n --tw-backdrop-sepia: ;\\n --tw-contain-size: ;\\n --tw-contain-layout: ;\\n --tw-contain-paint: ;\\n --tw-contain-style: ;\\n}\\n/* ! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com */\\n/*\\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\\n*/\\n*,\\n::before,\\n::after {\\n box-sizing: border-box; /* 1 */\\n border-width: 0; /* 2 */\\n border-style: solid; /* 2 */\\n border-color: #e5e7eb; /* 2 */\\n}\\n::before,\\n::after {\\n --tw-content: '';\\n}\\n/*\\n1. Use a consistent sensible line-height in all browsers.\\n2. Prevent adjustments of font size after orientation changes in iOS.\\n3. Use a more readable tab size.\\n4. Use the user's configured `sans` font-family by default.\\n5. Use the user's configured `sans` font-feature-settings by default.\\n6. Use the user's configured `sans` font-variation-settings by default.\\n7. Disable tap highlights on iOS\\n*/\\nhtml,\\n:host {\\n line-height: 1.5; /* 1 */\\n -webkit-text-size-adjust: 100%; /* 2 */\\n -moz-tab-size: 4; /* 3 */\\n -o-tab-size: 4;\\n tab-size: 4; /* 3 */\\n font-family: ui-sans-serif, system-ui, sans-serif, \\\"Apple Color Emoji\\\", \\\"Segoe UI Emoji\\\", \\\"Segoe UI Symbol\\\", \\\"Noto Color Emoji\\\"; /* 4 */\\n font-feature-settings: normal; /* 5 */\\n font-variation-settings: normal; /* 6 */\\n -webkit-tap-highlight-color: transparent; /* 7 */\\n}\\n/*\\n1. Remove the margin in all browsers.\\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\\n*/\\nbody {\\n margin: 0; /* 1 */\\n line-height: inherit; /* 2 */\\n}\\n/*\\n1. Add the correct height in Firefox.\\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\\n3. Ensure horizontal rules are visible by default.\\n*/\\nhr {\\n height: 0; /* 1 */\\n color: inherit; /* 2 */\\n border-top-width: 1px; /* 3 */\\n}\\n/*\\nAdd the correct text decoration in Chrome, Edge, and Safari.\\n*/\\nabbr:where([title]) {\\n -webkit-text-decoration: underline dotted;\\n text-decoration: underline dotted;\\n}\\n/*\\nRemove the default font size and weight for headings.\\n*/\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6 {\\n font-size: inherit;\\n font-weight: inherit;\\n}\\n/*\\nReset links to optimize for opt-in styling instead of opt-out.\\n*/\\na {\\n color: inherit;\\n text-decoration: inherit;\\n}\\n/*\\nAdd the correct font weight in Edge and Safari.\\n*/\\nb,\\nstrong {\\n font-weight: bolder;\\n}\\n/*\\n1. Use the user's configured `mono` font-family by default.\\n2. Use the user's configured `mono` font-feature-settings by default.\\n3. Use the user's configured `mono` font-variation-settings by default.\\n4. Correct the odd `em` font sizing in all browsers.\\n*/\\ncode,\\nkbd,\\nsamp,\\npre {\\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace; /* 1 */\\n font-feature-settings: normal; /* 2 */\\n font-variation-settings: normal; /* 3 */\\n font-size: 1em; /* 4 */\\n}\\n/*\\nAdd the correct font size in all browsers.\\n*/\\nsmall {\\n font-size: 80%;\\n}\\n/*\\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\\n*/\\nsub,\\nsup {\\n font-size: 75%;\\n line-height: 0;\\n position: relative;\\n vertical-align: baseline;\\n}\\nsub {\\n bottom: -0.25em;\\n}\\nsup {\\n top: -0.5em;\\n}\\n/*\\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\\n3. Remove gaps between table borders by default.\\n*/\\ntable {\\n text-indent: 0; /* 1 */\\n border-color: inherit; /* 2 */\\n border-collapse: collapse; /* 3 */\\n}\\n/*\\n1. Change the font styles in all browsers.\\n2. Remove the margin in Firefox and Safari.\\n3. Remove default padding in all browsers.\\n*/\\nbutton,\\ninput,\\noptgroup,\\nselect,\\ntextarea {\\n font-family: inherit; /* 1 */\\n font-feature-settings: inherit; /* 1 */\\n font-variation-settings: inherit; /* 1 */\\n font-size: 100%; /* 1 */\\n font-weight: inherit; /* 1 */\\n line-height: inherit; /* 1 */\\n letter-spacing: inherit; /* 1 */\\n color: inherit; /* 1 */\\n margin: 0; /* 2 */\\n padding: 0; /* 3 */\\n}\\n/*\\nRemove the inheritance of text transform in Edge and Firefox.\\n*/\\nbutton,\\nselect {\\n text-transform: none;\\n}\\n/*\\n1. Correct the inability to style clickable types in iOS and Safari.\\n2. Remove default button styles.\\n*/\\nbutton,\\ninput:where([type='button']),\\ninput:where([type='reset']),\\ninput:where([type='submit']) {\\n -webkit-appearance: button; /* 1 */\\n background-color: transparent; /* 2 */\\n background-image: none; /* 2 */\\n}\\n/*\\nUse the modern Firefox focus style for all focusable elements.\\n*/\\n:-moz-focusring {\\n outline: auto;\\n}\\n/*\\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\\n*/\\n:-moz-ui-invalid {\\n box-shadow: none;\\n}\\n/*\\nAdd the correct vertical alignment in Chrome and Firefox.\\n*/\\nprogress {\\n vertical-align: baseline;\\n}\\n/*\\nCorrect the cursor style of increment and decrement buttons in Safari.\\n*/\\n::-webkit-inner-spin-button,\\n::-webkit-outer-spin-button {\\n height: auto;\\n}\\n/*\\n1. Correct the odd appearance in Chrome and Safari.\\n2. Correct the outline style in Safari.\\n*/\\n[type='search'] {\\n -webkit-appearance: textfield; /* 1 */\\n outline-offset: -2px; /* 2 */\\n}\\n/*\\nRemove the inner padding in Chrome and Safari on macOS.\\n*/\\n::-webkit-search-decoration {\\n -webkit-appearance: none;\\n}\\n/*\\n1. Correct the inability to style clickable types in iOS and Safari.\\n2. Change font properties to `inherit` in Safari.\\n*/\\n::-webkit-file-upload-button {\\n -webkit-appearance: button; /* 1 */\\n font: inherit; /* 2 */\\n}\\n/*\\nAdd the correct display in Chrome and Safari.\\n*/\\nsummary {\\n display: list-item;\\n}\\n/*\\nRemoves the default spacing and border for appropriate elements.\\n*/\\nblockquote,\\ndl,\\ndd,\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6,\\nhr,\\nfigure,\\np,\\npre {\\n margin: 0;\\n}\\nfieldset {\\n margin: 0;\\n padding: 0;\\n}\\nlegend {\\n padding: 0;\\n}\\nol,\\nul,\\nmenu {\\n list-style: none;\\n margin: 0;\\n padding: 0;\\n}\\n/*\\nReset default styling for dialogs.\\n*/\\ndialog {\\n padding: 0;\\n}\\n/*\\nPrevent resizing textareas horizontally by default.\\n*/\\ntextarea {\\n resize: vertical;\\n}\\n/*\\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\\n2. Set the default placeholder color to the user's configured gray 400 color.\\n*/\\ninput::-moz-placeholder, textarea::-moz-placeholder {\\n opacity: 1; /* 1 */\\n color: #9ca3af; /* 2 */\\n}\\ninput::placeholder,\\ntextarea::placeholder {\\n opacity: 1; /* 1 */\\n color: #9ca3af; /* 2 */\\n}\\n/*\\nSet the default cursor for buttons.\\n*/\\nbutton,\\n[role=\\\"button\\\"] {\\n cursor: pointer;\\n}\\n/*\\nMake sure disabled buttons don't get the pointer cursor.\\n*/\\n:disabled {\\n cursor: default;\\n}\\n/*\\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\\n This can trigger a poorly considered lint error in some tools but is included by design.\\n*/\\nimg,\\nsvg,\\nvideo,\\ncanvas,\\naudio,\\niframe,\\nembed,\\nobject {\\n display: block; /* 1 */\\n vertical-align: middle; /* 2 */\\n}\\n/*\\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\\n*/\\nimg,\\nvideo {\\n max-width: 100%;\\n height: auto;\\n}\\n/* Make elements with the HTML hidden attribute stay hidden by default */\\n[hidden]:where(:not([hidden=\\\"until-found\\\"])) {\\n display: none;\\n}\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n.container {\\n width: 100%;\\n}\\n@media (min-width: 640px) {\\n .container {\\n max-width: 640px;\\n }\\n}\\n@media (min-width: 768px) {\\n .container {\\n max-width: 768px;\\n }\\n}\\n@media (min-width: 1024px) {\\n .container {\\n max-width: 1024px;\\n }\\n}\\n@media (min-width: 1280px) {\\n .container {\\n max-width: 1280px;\\n }\\n}\\n@media (min-width: 1536px) {\\n .container {\\n max-width: 1536px;\\n }\\n}\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n.pointer-events-none {\\n pointer-events: none;\\n}\\n.visible {\\n visibility: visible;\\n}\\n.invisible {\\n visibility: hidden;\\n}\\n.static {\\n position: static;\\n}\\n.fixed {\\n position: fixed;\\n}\\n.absolute {\\n position: absolute;\\n}\\n.relative {\\n position: relative;\\n}\\n.inset-0 {\\n inset: 0px;\\n}\\n.left-0 {\\n left: 0px;\\n}\\n.top-0 {\\n top: 0px;\\n}\\n.isolate {\\n isolation: isolate;\\n}\\n.z-10 {\\n z-index: 10;\\n}\\n.z-20 {\\n z-index: 20;\\n}\\n.z-\\\\[20\\\\] {\\n z-index: 20;\\n}\\n.z-\\\\[5\\\\] {\\n z-index: 5;\\n}\\n.col-span-2 {\\n grid-column: span 2 / span 2;\\n}\\n.mx-2 {\\n margin-left: 0.5rem;\\n margin-right: 0.5rem;\\n}\\n.mb-\\\\[1px\\\\] {\\n margin-bottom: 1px;\\n}\\n.block {\\n display: block;\\n}\\n.inline-block {\\n display: inline-block;\\n}\\n.inline {\\n display: inline;\\n}\\n.flex {\\n display: flex;\\n}\\n.grid {\\n display: grid;\\n}\\n.contents {\\n display: contents;\\n}\\n.hidden {\\n display: none;\\n}\\n.size-full {\\n width: 100%;\\n height: 100%;\\n}\\n.h-\\\\[1\\\\.1rem\\\\] {\\n height: 1.1rem;\\n}\\n.h-\\\\[200px\\\\] {\\n height: 200px;\\n}\\n.h-\\\\[270px\\\\] {\\n height: 270px;\\n}\\n.h-\\\\[300px\\\\] {\\n height: 300px;\\n}\\n.h-\\\\[360px\\\\] {\\n height: 360px;\\n}\\n.h-\\\\[500px\\\\] {\\n height: 500px;\\n}\\n.h-\\\\[5px\\\\] {\\n height: 5px;\\n}\\n.h-full {\\n height: 100%;\\n}\\n.w-1 {\\n width: 0.25rem;\\n}\\n.w-\\\\[1000px\\\\] {\\n width: 1000px;\\n}\\n.w-\\\\[2px\\\\] {\\n width: 2px;\\n}\\n.w-\\\\[480px\\\\] {\\n width: 480px;\\n}\\n.w-\\\\[600px\\\\] {\\n width: 600px;\\n}\\n.w-\\\\[640px\\\\] {\\n width: 640px;\\n}\\n.w-full {\\n width: 100%;\\n}\\n.transform {\\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\\n}\\n.cursor-crosshair {\\n cursor: crosshair;\\n}\\n.touch-none {\\n touch-action: none;\\n}\\n.touch-pan-x {\\n --tw-pan-x: pan-x;\\n touch-action: var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom);\\n}\\n.resize {\\n resize: both;\\n}\\n.place-content-center {\\n place-content: center;\\n}\\n.items-center {\\n align-items: center;\\n}\\n.overflow-auto {\\n overflow: auto;\\n}\\n.overflow-hidden {\\n overflow: hidden;\\n}\\n.overflow-visible {\\n overflow: visible;\\n}\\n.whitespace-nowrap {\\n white-space: nowrap;\\n}\\n.text-nowrap {\\n text-wrap: nowrap;\\n}\\n.rounded {\\n border-radius: 0.25rem;\\n}\\n.border {\\n border-width: 1px;\\n}\\n.border-r-2 {\\n border-right-width: 2px;\\n}\\n.bg-black {\\n --tw-bg-opacity: 1;\\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\\n}\\n.bg-lime-400 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(163 230 53 / var(--tw-bg-opacity, 1));\\n}\\n.bg-slate-500 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(100 116 139 / var(--tw-bg-opacity, 1));\\n}\\n.bg-yellow-400 {\\n --tw-bg-opacity: 1;\\n background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));\\n}\\n.bg-opacity-20 {\\n --tw-bg-opacity: 0.2;\\n}\\n.object-contain {\\n -o-object-fit: contain;\\n object-fit: contain;\\n}\\n.p-4 {\\n padding: 1rem;\\n}\\n.p-\\\\[1px\\\\] {\\n padding: 1px;\\n}\\n.px-0\\\\.5 {\\n padding-left: 0.125rem;\\n padding-right: 0.125rem;\\n}\\n.pb-0 {\\n padding-bottom: 0px;\\n}\\n.pl-1 {\\n padding-left: 0.25rem;\\n}\\n.pl-2 {\\n padding-left: 0.5rem;\\n}\\n.pr-0 {\\n padding-right: 0px;\\n}\\n.pr-1 {\\n padding-right: 0.25rem;\\n}\\n.pt-\\\\[8px\\\\] {\\n padding-top: 8px;\\n}\\n.text-center {\\n text-align: center;\\n}\\n.font-mono {\\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace;\\n}\\n.text-\\\\[8px\\\\] {\\n font-size: 8px;\\n}\\n.text-sm {\\n font-size: 0.875rem;\\n line-height: 1.25rem;\\n}\\n.text-xs {\\n font-size: 0.75rem;\\n line-height: 1rem;\\n}\\n.font-bold {\\n font-weight: 700;\\n}\\n.ordinal {\\n --tw-ordinal: ordinal;\\n font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);\\n}\\n.text-black {\\n --tw-text-opacity: 1;\\n color: rgb(0 0 0 / var(--tw-text-opacity, 1));\\n}\\n.text-green-200 {\\n --tw-text-opacity: 1;\\n color: rgb(187 247 208 / var(--tw-text-opacity, 1));\\n}\\n.text-green-900 {\\n --tw-text-opacity: 1;\\n color: rgb(20 83 45 / var(--tw-text-opacity, 1));\\n}\\n.line-through {\\n text-decoration-line: line-through;\\n}\\n.opacity-50 {\\n opacity: 0.5;\\n}\\n.shadow {\\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\\n}\\n.outline {\\n outline-style: solid;\\n}\\n.blur {\\n --tw-blur: blur(8px);\\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\\n}\\n.filter {\\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\\n}\\n.backdrop-filter {\\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\\n}\\n.transition {\\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;\\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\\n transition-duration: 150ms;\\n}\\n.ease-in {\\n transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\\n}\\n.ease-in-out {\\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\\n}\\n.ease-out {\\n transition-timing-function: cubic-bezier(0, 0, 0.2, 1);\\n}\\n\""],"mappings":";AAAA,sBAAe"}
|
package/dist/style.css
CHANGED
|
@@ -738,10 +738,6 @@ video {
|
|
|
738
738
|
--tw-blur: blur(8px);
|
|
739
739
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
740
740
|
}
|
|
741
|
-
.invert {
|
|
742
|
-
--tw-invert: invert(100%);
|
|
743
|
-
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
744
|
-
}
|
|
745
741
|
.filter {
|
|
746
742
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
747
743
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.2-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"license": "UNLICENSED",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@bramus/style-observer": "^1.3.0",
|
|
16
|
-
"@editframe/assets": "0.30.
|
|
16
|
+
"@editframe/assets": "0.30.2-beta.0",
|
|
17
17
|
"@lit/context": "^1.1.6",
|
|
18
18
|
"@lit/task": "^1.0.3",
|
|
19
19
|
"@opentelemetry/api": "^1.9.0",
|