murasaki 0.3.0 → 0.4.1
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/dev.js +5 -17
- package/dist/dev.js.map +1 -1
- package/dist/jsx/dom/index.d.ts +2 -0
- package/dist/jsx/dom/index.d.ts.map +1 -1
- package/dist/jsx/dom/index.js +1 -0
- package/dist/jsx/dom/index.js.map +1 -1
- package/dist/jsx/dom/native.d.ts +45 -0
- package/dist/jsx/dom/native.d.ts.map +1 -0
- package/dist/jsx/dom/native.js +88 -0
- package/dist/jsx/dom/native.js.map +1 -0
- package/dist/runtime/hmr.d.ts +1 -0
- package/dist/runtime/hmr.d.ts.map +1 -1
- package/dist/runtime/hmr.js +22 -1
- package/dist/runtime/hmr.js.map +1 -1
- package/dist/runtime/native.d.ts +19 -0
- package/dist/runtime/native.d.ts.map +1 -0
- package/dist/runtime/native.js +111 -0
- package/dist/runtime/native.js.map +1 -0
- package/dist/runtime/shortcuts.d.ts.map +1 -1
- package/dist/runtime/shortcuts.js +10 -23
- package/dist/runtime/shortcuts.js.map +1 -1
- package/dist/runtime/window.d.ts.map +1 -1
- package/dist/runtime/window.js +48 -22
- package/dist/runtime/window.js.map +1 -1
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
// src/dev.tsx
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// Reads the consumer's src/ directory:
|
|
5
|
-
// src/layout.tsx (optional, can export `metadata`)
|
|
6
|
-
// src/app.tsx (required)
|
|
7
|
-
// src/globals.css (optional, auto-injected)
|
|
8
|
-
//
|
|
9
|
-
// Renders <Layout><App /></Layout> with React, ships HTML to the WebView,
|
|
10
|
-
// and reloads in place on file change.
|
|
11
|
-
import { printBanner, printBye, printOpened, printReady, printShortcuts, printStarting, } from "./cli/log.js";
|
|
1
|
+
// src/dev.tsx — boot entry for `murasaki dev`.
|
|
2
|
+
import { printBanner, printBye, printReady, printStarting, } from "./cli/log.js";
|
|
12
3
|
import { setupHmr } from "./runtime/hmr.js";
|
|
13
|
-
import { setupShortcuts
|
|
4
|
+
import { setupShortcuts } from "./runtime/shortcuts.js";
|
|
14
5
|
import { closeWindow, exitApp, getConfig, openWindow, reloadWindow, runApp, } from "./runtime/window.js";
|
|
15
6
|
const startAt = Date.now();
|
|
16
|
-
// Boot: render once (applies metadata) → banner → ready
|
|
17
7
|
await openWindow();
|
|
18
8
|
printBanner(getConfig().title, getConfig());
|
|
19
|
-
printShortcuts();
|
|
20
9
|
printStarting();
|
|
21
10
|
printReady(Date.now() - startAt);
|
|
22
11
|
setupShortcuts({
|
|
23
12
|
onOpen: () => {
|
|
24
|
-
void openWindow()
|
|
13
|
+
void openWindow();
|
|
25
14
|
},
|
|
26
15
|
onRestart: () => {
|
|
27
16
|
closeWindow();
|
|
28
|
-
void openWindow()
|
|
17
|
+
void openWindow();
|
|
29
18
|
},
|
|
30
19
|
onQuit: () => {
|
|
31
20
|
printBye();
|
|
32
|
-
teardownStdin();
|
|
33
21
|
exitApp();
|
|
34
22
|
process.exit(0);
|
|
35
23
|
},
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.tsx"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EACL,WAAW,EACX,OAAO,EACP,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,GACP,MAAM,qBAAqB,CAAA;AAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;AAE1B,MAAM,UAAU,EAAE,CAAA;AAClB,WAAW,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;AAC3C,aAAa,EAAE,CAAA;AACf,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAA;AAEhC,cAAc,CAAC;IACb,MAAM,EAAE,GAAG,EAAE;QACX,KAAK,UAAU,EAAE,CAAA;IACnB,CAAC;IACD,SAAS,EAAE,GAAG,EAAE;QACd,WAAW,EAAE,CAAA;QACb,KAAK,UAAU,EAAE,CAAA;IACnB,CAAC;IACD,MAAM,EAAE,GAAG,EAAE;QACX,QAAQ,EAAE,CAAA;QACV,OAAO,EAAE,CAAA;QACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;CACF,CAAC,CAAA;AAEF,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;IAChB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAC,CAAA;AAEF,MAAM,EAAE,CAAA"}
|
package/dist/jsx/dom/index.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { createElement, createRoot, Fragment, jsx, jsxDEV, jsxs, useEffect, useRef, useState, } from './runtime.ts';
|
|
2
|
+
export { useNotification, useClipboard, useShell } from './native.ts';
|
|
3
|
+
export type { NotifyOptions } from './native.ts';
|
|
2
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jsx/dom/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,UAAU,EACV,QAAQ,EACR,GAAG,EACH,MAAM,EACN,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jsx/dom/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,UAAU,EACV,QAAQ,EACR,GAAG,EACH,MAAM,EACN,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACrE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/jsx/dom/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
// Public surface for `import { ... } from 'murasaki/jsx/dom'`.
|
|
2
2
|
export { createElement, createRoot, Fragment, jsx, jsxDEV, jsxs, useEffect, useRef, useState, } from "./runtime.js";
|
|
3
|
+
export { useNotification, useClipboard, useShell } from "./native.js";
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/jsx/dom/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D,OAAO,EACL,aAAa,EACb,UAAU,EACV,QAAQ,EACR,GAAG,EACH,MAAM,EACN,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/jsx/dom/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D,OAAO,EACL,aAAa,EACb,UAAU,EACV,QAAQ,EACR,GAAG,EACH,MAAM,EACN,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type NotifyOptions = {
|
|
2
|
+
title: string;
|
|
3
|
+
body?: string;
|
|
4
|
+
sound?: boolean;
|
|
5
|
+
};
|
|
6
|
+
type Bridge = {
|
|
7
|
+
notify(opts: NotifyOptions): Promise<void>;
|
|
8
|
+
clipboardWrite(text: string): Promise<void>;
|
|
9
|
+
clipboardRead(): Promise<string>;
|
|
10
|
+
openExternal(target: string): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
declare global {
|
|
13
|
+
interface Window {
|
|
14
|
+
murasaki?: Bridge;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns a function that shows an OS notification.
|
|
19
|
+
*
|
|
20
|
+
* const notify = useNotification()
|
|
21
|
+
* notify({ title: 'Hello', body: 'from murasaki' })
|
|
22
|
+
*/
|
|
23
|
+
export declare function useNotification(): (opts: NotifyOptions) => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Returns { read, write } for the system clipboard.
|
|
26
|
+
*
|
|
27
|
+
* const clipboard = useClipboard()
|
|
28
|
+
* clipboard.write('hello')
|
|
29
|
+
* const text = await clipboard.read()
|
|
30
|
+
*/
|
|
31
|
+
export declare function useClipboard(): {
|
|
32
|
+
read(): Promise<string>;
|
|
33
|
+
write(text: string): Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Returns { openExternal } — opens URLs / files in the system default app.
|
|
37
|
+
*
|
|
38
|
+
* const shell = useShell()
|
|
39
|
+
* shell.openExternal('https://murasaki.dev')
|
|
40
|
+
*/
|
|
41
|
+
export declare function useShell(): {
|
|
42
|
+
openExternal(target: string): Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/jsx/dom/native.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,MAAM,GAAG;IACZ,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAChC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5C,CAAA;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB;CACF;AAOD;;;;;GAKG;AACH,wBAAgB,eAAe,KACf,MAAM,aAAa,KAAG,OAAO,CAAC,IAAI,CAAC,CASlD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY;YAEV,OAAO,CAAC,MAAM,CAAC;gBAUX,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAU3C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ;yBAEO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAUpD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Client-side React-style hooks for native APIs.
|
|
2
|
+
//
|
|
3
|
+
// All of these proxy to the Node side via window.murasaki.*, which the
|
|
4
|
+
// dev runner exposes through @webviewjs/webview's webview.expose().
|
|
5
|
+
//
|
|
6
|
+
// Safe to import server-side — every hook detects the missing bridge
|
|
7
|
+
// and degrades to no-op (notify/openExternal/clipboardWrite) or empty
|
|
8
|
+
// value (clipboardRead → '').
|
|
9
|
+
function bridge() {
|
|
10
|
+
if (typeof window === 'undefined')
|
|
11
|
+
return null;
|
|
12
|
+
return window.murasaki ?? null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns a function that shows an OS notification.
|
|
16
|
+
*
|
|
17
|
+
* const notify = useNotification()
|
|
18
|
+
* notify({ title: 'Hello', body: 'from murasaki' })
|
|
19
|
+
*/
|
|
20
|
+
export function useNotification() {
|
|
21
|
+
return async (opts) => {
|
|
22
|
+
const b = bridge();
|
|
23
|
+
if (!b)
|
|
24
|
+
return;
|
|
25
|
+
try {
|
|
26
|
+
await b.notify(opts);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
console.warn('[murasaki] notify failed:', e);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns { read, write } for the system clipboard.
|
|
35
|
+
*
|
|
36
|
+
* const clipboard = useClipboard()
|
|
37
|
+
* clipboard.write('hello')
|
|
38
|
+
* const text = await clipboard.read()
|
|
39
|
+
*/
|
|
40
|
+
export function useClipboard() {
|
|
41
|
+
return {
|
|
42
|
+
async read() {
|
|
43
|
+
const b = bridge();
|
|
44
|
+
if (!b)
|
|
45
|
+
return '';
|
|
46
|
+
try {
|
|
47
|
+
return await b.clipboardRead();
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
console.warn('[murasaki] clipboard.read failed:', e);
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
async write(text) {
|
|
55
|
+
const b = bridge();
|
|
56
|
+
if (!b)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
await b.clipboardWrite(text);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
console.warn('[murasaki] clipboard.write failed:', e);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Returns { openExternal } — opens URLs / files in the system default app.
|
|
69
|
+
*
|
|
70
|
+
* const shell = useShell()
|
|
71
|
+
* shell.openExternal('https://murasaki.dev')
|
|
72
|
+
*/
|
|
73
|
+
export function useShell() {
|
|
74
|
+
return {
|
|
75
|
+
async openExternal(target) {
|
|
76
|
+
const b = bridge();
|
|
77
|
+
if (!b)
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
await b.openExternal(target);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
console.warn('[murasaki] openExternal failed:', e);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/jsx/dom/native.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,8BAA8B;AAqB9B,SAAS,MAAM;IACb,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IAC9C,OAAO,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAA;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,EAAE,IAAmB,EAAiB,EAAE;QAClD,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;QAClB,IAAI,CAAC,CAAC;YAAE,OAAM;QACd,IAAI,CAAC;YACH,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,KAAK,CAAC,IAAI;YACR,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;YAClB,IAAI,CAAC,CAAC;gBAAE,OAAO,EAAE,CAAA;YACjB,IAAI,CAAC;gBACH,OAAO,MAAM,CAAC,CAAC,aAAa,EAAE,CAAA;YAChC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,CAAA;gBACpD,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAY;YACtB,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;YAClB,IAAI,CAAC,CAAC;gBAAE,OAAM;YACd,IAAI,CAAC;gBACH,MAAM,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YAC9B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC,CAAA;YACvD,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO;QACL,KAAK,CAAC,YAAY,CAAC,MAAc;YAC/B,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;YAClB,IAAI,CAAC,CAAC;gBAAE,OAAM;YACd,IAAI,CAAC;gBACH,MAAM,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;YAC9B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAA;YACpD,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/runtime/hmr.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/runtime/hmr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/runtime/hmr.ts"],"names":[],"mappings":"AAeA,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAuBnE;AAED,wBAAgB,WAAW,IAAI,IAAI,CAOlC"}
|
package/dist/runtime/hmr.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
// File watcher for src/ — debounces multi-event saves and triggers reload.
|
|
2
|
+
//
|
|
3
|
+
// macOS note: Node's fs.watch wraps FSEvents, which keeps the libuv loop
|
|
4
|
+
// alive AND, observed in practice, somehow blocks the OS close button on
|
|
5
|
+
// the webview window from completing. We:
|
|
6
|
+
// 1. unref() the watcher so it doesn't prop the process up on its own
|
|
7
|
+
// 2. close() it explicitly on app/window close (via teardown)
|
|
8
|
+
// That keeps HMR responsive while letting the red close button work.
|
|
2
9
|
import { existsSync, watch } from 'node:fs';
|
|
3
10
|
import { printHint } from "../cli/log.js";
|
|
4
11
|
import { SRC_DIR } from "../env.js";
|
|
12
|
+
let activeWatcher = null;
|
|
5
13
|
export function setupHmr(onChange) {
|
|
6
14
|
if (!existsSync(SRC_DIR)) {
|
|
7
15
|
printHint('src/ directory not found — nothing to watch');
|
|
@@ -10,7 +18,7 @@ export function setupHmr(onChange) {
|
|
|
10
18
|
let debounce = null;
|
|
11
19
|
let lastFile = '';
|
|
12
20
|
try {
|
|
13
|
-
watch(SRC_DIR, { recursive: true }, (_event, filename) => {
|
|
21
|
+
const w = watch(SRC_DIR, { recursive: true }, (_event, filename) => {
|
|
14
22
|
if (!filename)
|
|
15
23
|
return;
|
|
16
24
|
if (debounce)
|
|
@@ -20,9 +28,22 @@ export function setupHmr(onChange) {
|
|
|
20
28
|
onChange(lastFile);
|
|
21
29
|
}, 80);
|
|
22
30
|
});
|
|
31
|
+
// Don't let the watcher alone keep the process alive — the Cocoa main
|
|
32
|
+
// loop in @webviewjs/webview is the real keep-alive.
|
|
33
|
+
w.unref?.();
|
|
34
|
+
activeWatcher = w;
|
|
23
35
|
}
|
|
24
36
|
catch (e) {
|
|
25
37
|
printHint(`HMR watcher failed: ${e.message}`);
|
|
26
38
|
}
|
|
27
39
|
}
|
|
40
|
+
export function teardownHmr() {
|
|
41
|
+
if (activeWatcher) {
|
|
42
|
+
try {
|
|
43
|
+
activeWatcher.close();
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
46
|
+
activeWatcher = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
28
49
|
//# sourceMappingURL=hmr.js.map
|
package/dist/runtime/hmr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../../src/runtime/hmr.ts"],"names":[],"mappings":"AAAA,2EAA2E;
|
|
1
|
+
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../../src/runtime/hmr.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,0CAA0C;AAC1C,wEAAwE;AACxE,gEAAgE;AAChE,qEAAqE;AAErE,OAAO,EAAkB,UAAU,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,IAAI,aAAa,GAAqB,IAAI,CAAA;AAE1C,MAAM,UAAU,QAAQ,CAAC,QAAoC;IAC3D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,SAAS,CAAC,6CAA6C,CAAC,CAAA;QACxD,OAAM;IACR,CAAC;IACD,IAAI,QAAQ,GAA0B,IAAI,CAAA;IAC1C,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YACjE,IAAI,CAAC,QAAQ;gBAAE,OAAM;YACrB,IAAI,QAAQ;gBAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;YACpC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;YAC9B,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzB,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACpB,CAAC,EAAE,EAAE,CAAC,CAAA;QACR,CAAC,CAAC,CAAA;QACF,sEAAsE;QACtE,qDAAqD;QACrD,CAAC,CAAC,KAAK,EAAE,EAAE,CAAA;QACX,aAAa,GAAG,CAAC,CAAA;IACnB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,SAAS,CAAC,uBAAuB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,IAAI,aAAa,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,aAAa,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,aAAa,GAAG,IAAI,CAAA;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type NotifyOptions = {
|
|
2
|
+
title: string;
|
|
3
|
+
body?: string;
|
|
4
|
+
sound?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare const nativeBridge: {
|
|
7
|
+
/** Show an OS notification. */
|
|
8
|
+
notify(opts: NotifyOptions): Promise<void>;
|
|
9
|
+
/** Copy text to the system clipboard. */
|
|
10
|
+
clipboardWrite(text: string): Promise<void>;
|
|
11
|
+
/** Read text from the system clipboard. */
|
|
12
|
+
clipboardRead(): Promise<string>;
|
|
13
|
+
/** Open a URL or file path in the system default handler (browser, etc). */
|
|
14
|
+
openExternal(target: string): Promise<void>;
|
|
15
|
+
/** Murasaki version (debug/probe). */
|
|
16
|
+
version: string;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/runtime/native.ts"],"names":[],"mappings":"AAWA,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAoCD,eAAO,MAAM,YAAY;IACvB,+BAA+B;iBACZ,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBhD,yCAAyC;yBACd,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjD,2CAA2C;qBACpB,OAAO,CAAC,MAAM,CAAC;IAYtC,4EAA4E;yBACjD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,sCAAsC;;CAEvC,CAAA"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Native bridge exposed to the WebView under `window.murasaki`.
|
|
2
|
+
//
|
|
3
|
+
// Each function here becomes callable from client code via
|
|
4
|
+
// await window.murasaki.<name>(args)
|
|
5
|
+
// (the underlying transport is @webviewjs/webview's `webview.expose`).
|
|
6
|
+
//
|
|
7
|
+
// macOS-first; Windows/Linux paths are best-effort. All values & arguments
|
|
8
|
+
// must be JSON-serializable.
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
function runSilent(cmd, args, stdin) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const proc = spawn(cmd, args, { stdio: ['pipe', 'ignore', 'ignore'] });
|
|
13
|
+
proc.on('error', reject);
|
|
14
|
+
proc.on('exit', (code) => {
|
|
15
|
+
if (code === 0)
|
|
16
|
+
resolve();
|
|
17
|
+
else
|
|
18
|
+
reject(new Error(`${cmd} exited with code ${code}`));
|
|
19
|
+
});
|
|
20
|
+
if (stdin !== undefined) {
|
|
21
|
+
proc.stdin.write(stdin);
|
|
22
|
+
proc.stdin.end();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function runCapture(cmd, args) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const proc = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
29
|
+
let out = '';
|
|
30
|
+
proc.stdout.on('data', (chunk) => {
|
|
31
|
+
out += chunk.toString();
|
|
32
|
+
});
|
|
33
|
+
proc.on('error', reject);
|
|
34
|
+
proc.on('exit', (code) => {
|
|
35
|
+
if (code === 0)
|
|
36
|
+
resolve(out);
|
|
37
|
+
else
|
|
38
|
+
reject(new Error(`${cmd} exited with code ${code}`));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function escapeAppleScript(s) {
|
|
43
|
+
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
44
|
+
}
|
|
45
|
+
export const nativeBridge = {
|
|
46
|
+
/** Show an OS notification. */
|
|
47
|
+
async notify(opts) {
|
|
48
|
+
if (process.platform === 'darwin') {
|
|
49
|
+
const title = escapeAppleScript(opts.title);
|
|
50
|
+
const body = escapeAppleScript(opts.body ?? '');
|
|
51
|
+
const sound = opts.sound ? ' sound name "default"' : '';
|
|
52
|
+
const script = `display notification "${body}" with title "${title}"${sound}`;
|
|
53
|
+
await runSilent('osascript', ['-e', script]);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (process.platform === 'win32') {
|
|
57
|
+
// Best-effort PowerShell toast
|
|
58
|
+
const escaped = opts.title.replace(/"/g, '\\"');
|
|
59
|
+
const body = (opts.body ?? '').replace(/"/g, '\\"');
|
|
60
|
+
const ps = `New-BurntToastNotification -Text "${escaped}","${body}"`;
|
|
61
|
+
await runSilent('powershell', ['-Command', ps]);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Linux
|
|
65
|
+
const args = [];
|
|
66
|
+
if (opts.body)
|
|
67
|
+
args.push(opts.title, opts.body);
|
|
68
|
+
else
|
|
69
|
+
args.push(opts.title);
|
|
70
|
+
await runSilent('notify-send', args);
|
|
71
|
+
},
|
|
72
|
+
/** Copy text to the system clipboard. */
|
|
73
|
+
async clipboardWrite(text) {
|
|
74
|
+
if (process.platform === 'darwin')
|
|
75
|
+
return runSilent('pbcopy', [], text);
|
|
76
|
+
if (process.platform === 'win32')
|
|
77
|
+
return runSilent('clip', [], text);
|
|
78
|
+
// Linux: try wl-copy (Wayland) then xclip (X11)
|
|
79
|
+
try {
|
|
80
|
+
return await runSilent('wl-copy', [], text);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return runSilent('xclip', ['-selection', 'clipboard'], text);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
/** Read text from the system clipboard. */
|
|
87
|
+
async clipboardRead() {
|
|
88
|
+
if (process.platform === 'darwin')
|
|
89
|
+
return runCapture('pbpaste', []);
|
|
90
|
+
if (process.platform === 'win32') {
|
|
91
|
+
return runCapture('powershell', ['-Command', 'Get-Clipboard']);
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
return await runCapture('wl-paste', ['--no-newline']);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return runCapture('xclip', ['-selection', 'clipboard', '-o']);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
/** Open a URL or file path in the system default handler (browser, etc). */
|
|
101
|
+
async openExternal(target) {
|
|
102
|
+
const cmd = process.platform === 'darwin' ? 'open'
|
|
103
|
+
: process.platform === 'win32' ? 'cmd'
|
|
104
|
+
: 'xdg-open';
|
|
105
|
+
const args = process.platform === 'win32' ? ['/c', 'start', '', target] : [target];
|
|
106
|
+
return runSilent(cmd, args);
|
|
107
|
+
},
|
|
108
|
+
/** Murasaki version (debug/probe). */
|
|
109
|
+
version: '0.3.0',
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../src/runtime/native.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcuts.d.ts","sourceRoot":"","sources":["../../src/runtime/shortcuts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shortcuts.d.ts","sourceRoot":"","sources":["../../src/runtime/shortcuts.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAI/D;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Quit handler. We previously had `o`/`r`/`q` keypress shortcuts via stdin
|
|
2
|
+
// raw mode, but attaching any listener to stdin caused the OS close button
|
|
3
|
+
// to hang (stdin polling conflicted with the Cocoa main loop).
|
|
2
4
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// Ctrl+C quit
|
|
5
|
+
// Now: just listen for SIGINT/SIGTERM (Ctrl+C, kill signal). The OS close
|
|
6
|
+
// button + Ctrl+C cover quit. Future work: bring back o/r via the native
|
|
7
|
+
// menu API (webview's Menu/Tray surface), which doesn't touch stdin.
|
|
7
8
|
export function setupShortcuts(handlers) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
process.
|
|
11
|
-
process.stdin.resume();
|
|
12
|
-
process.stdin.setEncoding('utf8');
|
|
13
|
-
process.stdin.on('data', (key) => {
|
|
14
|
-
const k = key.toString();
|
|
15
|
-
if (k === 'o' || k === 'O')
|
|
16
|
-
handlers.onOpen();
|
|
17
|
-
else if (k === 'r' || k === 'R')
|
|
18
|
-
handlers.onRestart();
|
|
19
|
-
else if (k === 'q' || k === 'Q' || k === '\x03' /* Ctrl+C */)
|
|
20
|
-
handlers.onQuit();
|
|
21
|
-
});
|
|
9
|
+
const quit = () => handlers.onQuit();
|
|
10
|
+
process.on('SIGINT', quit);
|
|
11
|
+
process.on('SIGTERM', quit);
|
|
22
12
|
}
|
|
23
13
|
export function teardownStdin() {
|
|
24
|
-
|
|
25
|
-
process.stdin.setRawMode(false);
|
|
26
|
-
}
|
|
27
|
-
catch { }
|
|
14
|
+
// no-op (we never touched stdin)
|
|
28
15
|
}
|
|
29
16
|
//# sourceMappingURL=shortcuts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../../src/runtime/shortcuts.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"shortcuts.js","sourceRoot":"","sources":["../../src/runtime/shortcuts.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,+DAA+D;AAC/D,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,qEAAqE;AAQrE,MAAM,UAAU,cAAc,CAAC,QAA0B;IACvD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;IACpC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC1B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,iCAAiC;AACnC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/runtime/window.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/runtime/window.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAIhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAe/C,eAAO,MAAM,GAAG,aAAoB,CAAA;AAmDpC,wBAAgB,SAAS,IAAI,QAAQ,CAAC,YAAY,CAAC,CAElD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBhD;AAED,wBAAgB,WAAW,IAAI,IAAI,CAKlC;AAED,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASrE;AAED,wBAAgB,MAAM,IAAI,IAAI,CAE7B;AAED,wBAAgB,OAAO,IAAI,IAAI,CAI9B"}
|
package/dist/runtime/window.js
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
1
|
// Owns the Application + BrowserWindow lifecycle.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// keeps the loop alive even when no windows are open, so the user can press
|
|
5
|
-
// `o` in the terminal to re-open the window.
|
|
6
|
-
import { Application, ControlFlow } from '@webviewjs/webview';
|
|
7
|
-
import { printClosed, printError, printHint, printReloaded } from "../cli/log.js";
|
|
2
|
+
import { Application } from '@webviewjs/webview';
|
|
3
|
+
import { printBye, printClosed, printError, printHint, printReloaded } from "../cli/log.js";
|
|
8
4
|
import { DEFAULT_WIN_SIZE, DEFAULT_WIN_TITLE, projectRoot } from "../env.js";
|
|
5
|
+
import { teardownHmr } from "./hmr.js";
|
|
6
|
+
import { nativeBridge } from "./native.js";
|
|
9
7
|
import { renderApp } from "./render.js";
|
|
10
8
|
const config = {
|
|
11
9
|
title: DEFAULT_WIN_TITLE,
|
|
12
10
|
width: DEFAULT_WIN_SIZE.width,
|
|
13
11
|
height: DEFAULT_WIN_SIZE.height,
|
|
14
12
|
};
|
|
15
|
-
|
|
13
|
+
// Default event-loop mode (pump_events at ~60 FPS). ControlFlow.Wait used to
|
|
14
|
+
// be set here to allow `o` re-open after close, but it caused the close
|
|
15
|
+
// button to hang waiting for the next pump tick, which macOS interpreted
|
|
16
|
+
// as "not responding". Plain run-loop is responsive and just as cheap.
|
|
17
|
+
export const app = new Application();
|
|
16
18
|
let win = null;
|
|
17
19
|
let webview = null;
|
|
20
|
+
// winit/wry distinguishes two close events:
|
|
21
|
+
// - window-close-requested → one window's red button
|
|
22
|
+
// - application-close-requested → last window closed → app should exit
|
|
23
|
+
// We MUST handle the latter and call app.exit(), otherwise the OS sees
|
|
24
|
+
// the process as alive but unresponsive (no pending GUI work, no exit).
|
|
18
25
|
app.onEvent((event) => {
|
|
19
26
|
const kind = event && (event.kind || event.event);
|
|
20
27
|
if (kind === 'window-close-requested') {
|
|
21
|
-
// Dispose so the OS close completes — without this the close button hangs.
|
|
22
|
-
if (win) {
|
|
23
|
-
try {
|
|
24
|
-
win.dispose();
|
|
25
|
-
}
|
|
26
|
-
catch { }
|
|
27
|
-
}
|
|
28
|
-
win = null;
|
|
29
28
|
webview = null;
|
|
29
|
+
win = null;
|
|
30
30
|
printClosed();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (kind === 'application-close-requested') {
|
|
34
|
+
teardownHmr();
|
|
35
|
+
printBye();
|
|
36
|
+
try {
|
|
37
|
+
app.exit();
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
process.exit(0);
|
|
31
41
|
}
|
|
32
42
|
});
|
|
43
|
+
// Manual close path (the `r` shortcut for restart). We reopen immediately
|
|
44
|
+
// after, so explicit dispose is desirable.
|
|
45
|
+
function disposeSafely(target) {
|
|
46
|
+
if (!target)
|
|
47
|
+
return;
|
|
48
|
+
const sym = target[Symbol.dispose];
|
|
49
|
+
if (typeof sym === 'function') {
|
|
50
|
+
try {
|
|
51
|
+
sym.call(target);
|
|
52
|
+
}
|
|
53
|
+
catch { }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
33
56
|
function applyMetadata(metadata) {
|
|
34
57
|
if (!metadata)
|
|
35
58
|
return;
|
|
@@ -58,16 +81,19 @@ export async function openWindow() {
|
|
|
58
81
|
height: config.height,
|
|
59
82
|
});
|
|
60
83
|
webview = win.createWebview({ html });
|
|
61
|
-
|
|
62
|
-
export function closeWindow() {
|
|
63
|
-
if (!win)
|
|
64
|
-
return;
|
|
84
|
+
// Expose native bridge under window.murasaki for client hooks.
|
|
65
85
|
try {
|
|
66
|
-
|
|
86
|
+
webview.expose('murasaki', nativeBridge);
|
|
67
87
|
}
|
|
68
|
-
catch {
|
|
69
|
-
|
|
88
|
+
catch (e) {
|
|
89
|
+
printError(`Native bridge expose failed: ${e.message}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export function closeWindow() {
|
|
93
|
+
disposeSafely(webview);
|
|
94
|
+
disposeSafely(win);
|
|
70
95
|
webview = null;
|
|
96
|
+
win = null;
|
|
71
97
|
}
|
|
72
98
|
export async function reloadWindow(triggerFile) {
|
|
73
99
|
if (!webview)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/runtime/window.ts"],"names":[],"mappings":"AAAA,kDAAkD;
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/runtime/window.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG5E,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAc,CAAA;AAExC,MAAM,MAAM,GAAiB;IAC3B,KAAK,EAAE,iBAAiB;IACxB,KAAK,EAAE,gBAAgB,CAAC,KAAK;IAC7B,MAAM,EAAE,gBAAgB,CAAC,MAAM;CAChC,CAAA;AAED,6EAA6E;AAC7E,wEAAwE;AACxE,yEAAyE;AACzE,uEAAuE;AACvE,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAA;AAKpC,IAAI,GAAG,GAAyB,IAAI,CAAA;AACpC,IAAI,OAAO,GAAmB,IAAI,CAAA;AAElC,4CAA4C;AAC5C,4DAA4D;AAC5D,yEAAyE;AACzE,uEAAuE;AACvE,wEAAwE;AACxE,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;IACpB,MAAM,IAAI,GAAG,KAAK,IAAI,CAAE,KAAa,CAAC,IAAI,IAAK,KAAa,CAAC,KAAK,CAAC,CAAA;IACnE,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;QACtC,OAAO,GAAG,IAAI,CAAA;QACd,GAAG,GAAG,IAAI,CAAA;QACV,WAAW,EAAE,CAAA;QACb,OAAM;IACR,CAAC;IACD,IAAI,IAAI,KAAK,6BAA6B,EAAE,CAAC;QAC3C,WAAW,EAAE,CAAA;QACb,QAAQ,EAAE,CAAA;QACV,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,EAAE,CAAA;QACZ,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,0EAA0E;AAC1E,2CAA2C;AAC3C,SAAS,aAAa,CAAC,MAAe;IACpC,IAAI,CAAC,MAAM;QAAE,OAAM;IACnB,MAAM,GAAG,GAAI,MAA4C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACzE,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAmB;IACxC,IAAI,CAAC,QAAQ;QAAE,OAAM;IACrB,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAA;SAC3D,IAAI,QAAQ,CAAC,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAA;IACtD,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAA;IAChE,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAA;AACrE,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,GAAG,EAAE,CAAC;QACR,SAAS,CAAC,wBAAwB,CAAC,CAAA;QACnC,OAAM;IACR,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,SAAS,EAAE,CAAA;IAC5C,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvB,GAAG,GAAG,GAAG,CAAC,mBAAmB,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IACF,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IACrC,+DAA+D;IAC/D,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAC1C,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,UAAU,CAAC,gCAAgC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,aAAa,CAAC,OAAO,CAAC,CAAA;IACtB,aAAa,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,GAAG,IAAI,CAAA;IACd,GAAG,GAAG,IAAI,CAAA;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,IAAI,CAAC,OAAO;QAAE,OAAM;IACpB,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,EAAE,CAAA;QAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QACtB,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3D,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,UAAU,CAAC,kBAAkB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,GAAG,CAAC,GAAG,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,CAAC;QACH,GAAG,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
|