pi2dsh 0.3.0 → 0.3.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/README.md +16 -1
- package/README.zh.md +16 -1
- package/dist/compat/pi-ai.d.mts +10 -1
- package/dist/compat/pi-ai.d.mts.map +1 -1
- package/dist/compat/pi-ai.mjs +2 -2918
- package/dist/credentials-oauth.d.mts +27 -0
- package/dist/credentials-oauth.d.mts.map +1 -0
- package/dist/credentials-oauth.mjs +91 -0
- package/dist/credentials-oauth.mjs.map +1 -0
- package/dist/host.mjs +3 -1
- package/dist/host.mjs.map +1 -1
- package/dist/oauth-bridge-BpPrppjR.mjs +359 -0
- package/dist/oauth-bridge-BpPrppjR.mjs.map +1 -0
- package/dist/pi-ai-CWFlgigJ.mjs +2947 -0
- package/dist/pi-ai-CWFlgigJ.mjs.map +1 -0
- package/dist/{runtime-oLd2EInK.mjs → runtime-6DefpI6h.mjs} +11 -355
- package/dist/runtime-6DefpI6h.mjs.map +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +11 -1
- package/dist/compat/pi-ai.mjs.map +0 -1
- package/dist/runtime-oLd2EInK.mjs.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
|
|
3
3
|
import { E as __setSubagentSessionFactory, S as Theme, f as ExtensionRunner } from "./pi-coding-agent-Z1hTs61i.mjs";
|
|
4
|
+
import { a as storedOAuthCredential, i as resolveOAuthApiKey, n as loginPiProvider, r as providerSupportsOAuth, t as FileCredentialStore } from "./oauth-bridge-BpPrppjR.mjs";
|
|
5
|
+
import { r as builtinProviders } from "./pi-ai-CWFlgigJ.mjs";
|
|
4
6
|
import { createRequire } from "node:module";
|
|
5
|
-
import { access,
|
|
6
|
-
import {
|
|
7
|
+
import { access, readFile } from "node:fs/promises";
|
|
8
|
+
import { join } from "node:path";
|
|
7
9
|
import { fileURLToPath } from "node:url";
|
|
8
10
|
import { EventEmitter } from "node:events";
|
|
9
11
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -492,358 +494,6 @@ async function createBridgedAgentSession(host, options) {
|
|
|
492
494
|
return { session: new PiBridgedAgentSession(host, handle, tools) };
|
|
493
495
|
}
|
|
494
496
|
//#endregion
|
|
495
|
-
//#region src/compat/vendor/pi-ai-abort.ts
|
|
496
|
-
function abortReason(signal) {
|
|
497
|
-
if (signal.reason !== void 0) return signal.reason;
|
|
498
|
-
const error = /* @__PURE__ */ new Error("The operation was aborted");
|
|
499
|
-
error.name = "AbortError";
|
|
500
|
-
return error;
|
|
501
|
-
}
|
|
502
|
-
/** Create an operation-local signal for public APIs whose signal is optional. */
|
|
503
|
-
function operationSignal(signal) {
|
|
504
|
-
return signal ?? new AbortController().signal;
|
|
505
|
-
}
|
|
506
|
-
/**
|
|
507
|
-
* Stop waiting for an operation when its signal aborts while continuing to
|
|
508
|
-
* observe the abandoned promise so a later rejection is always handled.
|
|
509
|
-
*/
|
|
510
|
-
function raceWithAbortSignal(operation, signal) {
|
|
511
|
-
if (signal.aborted) {
|
|
512
|
-
operation.catch(() => {});
|
|
513
|
-
return Promise.reject(abortReason(signal));
|
|
514
|
-
}
|
|
515
|
-
return new Promise((resolve, reject) => {
|
|
516
|
-
let settled = false;
|
|
517
|
-
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
518
|
-
const onAbort = () => {
|
|
519
|
-
if (settled) return;
|
|
520
|
-
settled = true;
|
|
521
|
-
cleanup();
|
|
522
|
-
reject(abortReason(signal));
|
|
523
|
-
};
|
|
524
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
525
|
-
operation.then((value) => {
|
|
526
|
-
if (settled) return;
|
|
527
|
-
settled = true;
|
|
528
|
-
cleanup();
|
|
529
|
-
resolve(value);
|
|
530
|
-
}, (error) => {
|
|
531
|
-
if (settled) return;
|
|
532
|
-
settled = true;
|
|
533
|
-
cleanup();
|
|
534
|
-
reject(error);
|
|
535
|
-
});
|
|
536
|
-
if (signal.aborted) onAbort();
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
//#endregion
|
|
540
|
-
//#region src/compat/vendor/pi-ai-credential-store.ts
|
|
541
|
-
/**
|
|
542
|
-
* Default in-memory credential store. Apps inject persistent stores.
|
|
543
|
-
* Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
|
|
544
|
-
* Writes are serialized per provider through a promise chain.
|
|
545
|
-
*/
|
|
546
|
-
var InMemoryCredentialStore = class {
|
|
547
|
-
credentials = /* @__PURE__ */ new Map();
|
|
548
|
-
chains = /* @__PURE__ */ new Map();
|
|
549
|
-
/** Serialize tasks per provider id without releasing the chain before active work settles. */
|
|
550
|
-
enqueue(providerId, task, options) {
|
|
551
|
-
const signal = operationSignal(options?.signal);
|
|
552
|
-
const previous = this.chains.get(providerId) ?? Promise.resolve();
|
|
553
|
-
const queued = (async () => {
|
|
554
|
-
await previous.catch(() => {});
|
|
555
|
-
signal.throwIfAborted();
|
|
556
|
-
return task();
|
|
557
|
-
})();
|
|
558
|
-
const tail = queued.catch(() => {});
|
|
559
|
-
this.chains.set(providerId, tail);
|
|
560
|
-
tail.then(() => {
|
|
561
|
-
if (this.chains.get(providerId) === tail) this.chains.delete(providerId);
|
|
562
|
-
});
|
|
563
|
-
return raceWithAbortSignal(queued, signal);
|
|
564
|
-
}
|
|
565
|
-
async read(providerId, options) {
|
|
566
|
-
options?.signal?.throwIfAborted();
|
|
567
|
-
return this.credentials.get(providerId);
|
|
568
|
-
}
|
|
569
|
-
async list(options) {
|
|
570
|
-
options?.signal?.throwIfAborted();
|
|
571
|
-
return [...this.credentials].map(([providerId, credential]) => ({
|
|
572
|
-
providerId,
|
|
573
|
-
type: credential.type
|
|
574
|
-
}));
|
|
575
|
-
}
|
|
576
|
-
modify(providerId, fn, options) {
|
|
577
|
-
return this.enqueue(providerId, async () => {
|
|
578
|
-
const current = this.credentials.get(providerId);
|
|
579
|
-
const next = await fn(current);
|
|
580
|
-
options?.signal?.throwIfAborted();
|
|
581
|
-
if (next !== void 0) this.credentials.set(providerId, next);
|
|
582
|
-
return next ?? current;
|
|
583
|
-
}, options);
|
|
584
|
-
}
|
|
585
|
-
delete(providerId, options) {
|
|
586
|
-
return this.enqueue(providerId, async () => {
|
|
587
|
-
this.credentials.delete(providerId);
|
|
588
|
-
}, options);
|
|
589
|
-
}
|
|
590
|
-
};
|
|
591
|
-
//#endregion
|
|
592
|
-
//#region src/compat/vendor/pi-ai-diagnostics.ts
|
|
593
|
-
function formatThrownValue(value) {
|
|
594
|
-
if (value instanceof Error) return value.message || value.name;
|
|
595
|
-
if (typeof value === "string") return value;
|
|
596
|
-
return String(value);
|
|
597
|
-
}
|
|
598
|
-
//#endregion
|
|
599
|
-
//#region src/compat/vendor/pi-ai-auth-resolve.ts
|
|
600
|
-
var ModelsError = class extends Error {
|
|
601
|
-
code;
|
|
602
|
-
constructor(code, message, options) {
|
|
603
|
-
super(withCauseDetail(message, options?.cause), options);
|
|
604
|
-
this.name = "ModelsError";
|
|
605
|
-
this.code = code;
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
/** Callers surface `error.message` only, so keep the underlying reason in it. */
|
|
609
|
-
function withCauseDetail(message, cause) {
|
|
610
|
-
if (cause === void 0 || cause === null) return message;
|
|
611
|
-
const detail = formatThrownValue(cause).trim();
|
|
612
|
-
if (!detail || message.includes(detail)) return message;
|
|
613
|
-
return `${message}: ${detail}`;
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Auth resolution shared by the `Models` and `ImagesModels` collections.
|
|
617
|
-
* A stored credential owns the provider: ambient/env is consulted only when
|
|
618
|
-
* nothing is stored. No silent env fallback after a failed refresh or for a
|
|
619
|
-
* credential type without a matching handler.
|
|
620
|
-
*/
|
|
621
|
-
function resolveProviderAuth(provider, credentials, authContext, overrides) {
|
|
622
|
-
const signal = operationSignal(overrides?.signal);
|
|
623
|
-
return raceWithAbortSignal(resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal), signal);
|
|
624
|
-
}
|
|
625
|
-
async function resolveProviderAuthWithSignal(provider, credentials, authContext, overrides, signal) {
|
|
626
|
-
signal.throwIfAborted();
|
|
627
|
-
const requestAuthContext = overrides?.env ? overlayEnvAuthContext(authContext, overrides.env) : authContext;
|
|
628
|
-
if (overrides?.apiKey !== void 0 && provider.auth.apiKey) return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, {
|
|
629
|
-
type: "api_key",
|
|
630
|
-
key: overrides.apiKey,
|
|
631
|
-
env: overrides.env
|
|
632
|
-
}, signal);
|
|
633
|
-
const stored = await readCredential(credentials, provider.id, signal);
|
|
634
|
-
if (stored) {
|
|
635
|
-
if (stored.type === "oauth" && provider.auth.oauth) return resolveStoredOAuth(credentials, provider.id, provider.auth.oauth, stored, signal, overrides?.minOAuthValidityMs);
|
|
636
|
-
if (stored.type === "api_key" && provider.auth.apiKey) {
|
|
637
|
-
const credential = overrides?.env ? {
|
|
638
|
-
...stored,
|
|
639
|
-
env: {
|
|
640
|
-
...stored.env,
|
|
641
|
-
...overrides.env
|
|
642
|
-
}
|
|
643
|
-
} : stored;
|
|
644
|
-
return resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, credential, signal);
|
|
645
|
-
}
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
return provider.auth.apiKey ? resolveApiKey(requestAuthContext, provider.auth.apiKey, provider.id, void 0, signal) : void 0;
|
|
649
|
-
}
|
|
650
|
-
function overlayEnvAuthContext(base, env) {
|
|
651
|
-
return {
|
|
652
|
-
env: async (name) => env[name] || await base.env(name),
|
|
653
|
-
fileExists: (path) => base.fileExists(path)
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
const DEFAULT_OAUTH_MINIMUM_VALIDITY_MS = 3e5;
|
|
657
|
-
const DEFAULT_OAUTH_REFRESH_TIMEOUT_MS = 15e3;
|
|
658
|
-
/**
|
|
659
|
-
* OAuth resolution with double-checked locking: tokens with less than five
|
|
660
|
-
* minutes remaining lock, re-check expiry under the lock, refresh once
|
|
661
|
-
* globally, and persist the rotated credential before release.
|
|
662
|
-
*/
|
|
663
|
-
async function resolveStoredOAuth(credentials, providerId, oauth, stored, signal, minOAuthValidityMs) {
|
|
664
|
-
const minimumValidityMs = Math.max(DEFAULT_OAUTH_MINIMUM_VALIDITY_MS, minOAuthValidityMs ?? 0);
|
|
665
|
-
const expiresSoon = (credential) => Date.now() + minimumValidityMs >= credential.expires;
|
|
666
|
-
let credential = stored;
|
|
667
|
-
if (expiresSoon(credential)) {
|
|
668
|
-
let post;
|
|
669
|
-
try {
|
|
670
|
-
post = await credentials.modify(providerId, async (current) => {
|
|
671
|
-
if (current?.type !== "oauth") return void 0;
|
|
672
|
-
if (!expiresSoon(current)) return void 0;
|
|
673
|
-
try {
|
|
674
|
-
const refreshSignal = AbortSignal.any([signal, AbortSignal.timeout(DEFAULT_OAUTH_REFRESH_TIMEOUT_MS)]);
|
|
675
|
-
return await oauth.refresh(current, refreshSignal);
|
|
676
|
-
} catch (error) {
|
|
677
|
-
throw new ModelsError("oauth", `OAuth refresh failed for ${providerId}`, { cause: error });
|
|
678
|
-
}
|
|
679
|
-
}, { signal });
|
|
680
|
-
} catch (error) {
|
|
681
|
-
if (error instanceof ModelsError) throw error;
|
|
682
|
-
throw new ModelsError("auth", `Credential store modify failed for ${providerId}`, { cause: error });
|
|
683
|
-
}
|
|
684
|
-
if (post?.type !== "oauth") return void 0;
|
|
685
|
-
credential = post;
|
|
686
|
-
if (minOAuthValidityMs !== void 0 && expiresSoon(credential)) throw new ModelsError("oauth", `OAuth refresh returned a token that expires too soon for ${providerId}`);
|
|
687
|
-
}
|
|
688
|
-
try {
|
|
689
|
-
return {
|
|
690
|
-
auth: await oauth.toAuth(credential),
|
|
691
|
-
source: "OAuth"
|
|
692
|
-
};
|
|
693
|
-
} catch (error) {
|
|
694
|
-
throw new ModelsError("oauth", `OAuth auth derivation failed for ${providerId}`, { cause: error });
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
async function resolveApiKey(authContext, apiKey, providerId, credential, signal) {
|
|
698
|
-
try {
|
|
699
|
-
return await apiKey.resolve({
|
|
700
|
-
ctx: authContext,
|
|
701
|
-
credential,
|
|
702
|
-
signal
|
|
703
|
-
});
|
|
704
|
-
} catch (error) {
|
|
705
|
-
throw new ModelsError("auth", `API key auth failed for provider ${providerId}`, { cause: error });
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
async function readCredential(credentials, providerId, signal) {
|
|
709
|
-
try {
|
|
710
|
-
return await credentials.read(providerId, { signal });
|
|
711
|
-
} catch (error) {
|
|
712
|
-
throw new ModelsError("auth", `Credential store read failed for ${providerId}`, { cause: error });
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
//#endregion
|
|
716
|
-
//#region src/compat/vendor/pi-oauth-adapt.ts
|
|
717
|
-
function adaptOAuth(config) {
|
|
718
|
-
return {
|
|
719
|
-
name: config.name,
|
|
720
|
-
isSubscription: config.isSubscription,
|
|
721
|
-
login: async (callbacks) => {
|
|
722
|
-
return {
|
|
723
|
-
...await config.login({
|
|
724
|
-
onAuth: (info) => callbacks.notify({
|
|
725
|
-
type: "auth_url",
|
|
726
|
-
...info
|
|
727
|
-
}),
|
|
728
|
-
onDeviceCode: (info) => callbacks.notify({
|
|
729
|
-
type: "device_code",
|
|
730
|
-
...info
|
|
731
|
-
}),
|
|
732
|
-
onPrompt: (prompt) => callbacks.prompt({
|
|
733
|
-
type: "text",
|
|
734
|
-
...prompt
|
|
735
|
-
}),
|
|
736
|
-
onProgress: (message) => callbacks.notify({
|
|
737
|
-
type: "progress",
|
|
738
|
-
message
|
|
739
|
-
}),
|
|
740
|
-
onManualCodeInput: () => callbacks.prompt({
|
|
741
|
-
type: "manual_code",
|
|
742
|
-
message: "Paste the authorization code"
|
|
743
|
-
}),
|
|
744
|
-
onSelect: (prompt) => callbacks.prompt({
|
|
745
|
-
type: "select",
|
|
746
|
-
...prompt
|
|
747
|
-
}),
|
|
748
|
-
signal: callbacks.signal
|
|
749
|
-
}),
|
|
750
|
-
type: "oauth"
|
|
751
|
-
};
|
|
752
|
-
},
|
|
753
|
-
refresh: async (credential, signal) => ({
|
|
754
|
-
...await config.refreshToken(credential, signal),
|
|
755
|
-
type: "oauth"
|
|
756
|
-
}),
|
|
757
|
-
toAuth: async (credential) => ({ apiKey: config.getApiKey(credential) })
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
//#endregion
|
|
761
|
-
//#region src/oauth-bridge.ts
|
|
762
|
-
var FileCredentialStore = class extends InMemoryCredentialStore {
|
|
763
|
-
#path;
|
|
764
|
-
constructor(path) {
|
|
765
|
-
super();
|
|
766
|
-
this.#path = path;
|
|
767
|
-
try {
|
|
768
|
-
const data = JSON.parse(readFileSync(path, "utf8"));
|
|
769
|
-
for (const [providerId, credential] of Object.entries(data)) this.credentials.set(providerId, credential);
|
|
770
|
-
} catch {}
|
|
771
|
-
}
|
|
772
|
-
get path() {
|
|
773
|
-
return this.#path;
|
|
774
|
-
}
|
|
775
|
-
async #persist() {
|
|
776
|
-
const credentials = this.credentials;
|
|
777
|
-
const data = Object.fromEntries(credentials);
|
|
778
|
-
await mkdir(dirname(this.#path), { recursive: true });
|
|
779
|
-
const temp = `${this.#path}.tmp-${process.pid}-${Math.floor(Math.random() * 1e9).toString(36)}`;
|
|
780
|
-
await writeFile(temp, `${JSON.stringify(data, null, 2)}\n`, { mode: 384 });
|
|
781
|
-
await rename(temp, this.#path);
|
|
782
|
-
}
|
|
783
|
-
modify(providerId, fn, options) {
|
|
784
|
-
return super.modify(providerId, async (current) => {
|
|
785
|
-
const next = await fn(current);
|
|
786
|
-
if (next !== void 0) {
|
|
787
|
-
this.credentials.set(providerId, next);
|
|
788
|
-
await this.#persist();
|
|
789
|
-
}
|
|
790
|
-
return next;
|
|
791
|
-
}, options);
|
|
792
|
-
}
|
|
793
|
-
delete(providerId, options) {
|
|
794
|
-
return super.delete(providerId, options).then(() => this.#persist());
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
function oauthInteraction(ui, signal) {
|
|
798
|
-
return {
|
|
799
|
-
signal: signal ?? new AbortController().signal,
|
|
800
|
-
async prompt(prompt) {
|
|
801
|
-
if (prompt.type === "select") {
|
|
802
|
-
const options = prompt.options ?? [];
|
|
803
|
-
const picked = await ui.select(prompt.message, options.map((option) => option.label));
|
|
804
|
-
return options.find((option) => option.label === picked)?.id ?? picked;
|
|
805
|
-
}
|
|
806
|
-
return ui.input(prompt.message, prompt.placeholder);
|
|
807
|
-
},
|
|
808
|
-
notify(event) {
|
|
809
|
-
if (event.type === "auth_url") ui.notify(`Open this URL to authorize: ${event.url}${event.instructions !== void 0 ? `\n${event.instructions}` : ""}`);
|
|
810
|
-
else if (event.type === "device_code") ui.notify(`Visit ${event.verificationUri} and enter code ${event.userCode}`);
|
|
811
|
-
else if (event.message !== void 0) ui.notify(event.message);
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
function oauthConfigOf(providerConfig) {
|
|
816
|
-
const oauth = providerConfig?.oauth;
|
|
817
|
-
return typeof oauth === "object" && oauth !== null && typeof oauth.login === "function" ? oauth : void 0;
|
|
818
|
-
}
|
|
819
|
-
function oauthAdapterOf(oauthConfig) {
|
|
820
|
-
if (typeof oauthConfig.toAuth === "function") return oauthConfig;
|
|
821
|
-
return adaptOAuth(oauthConfig);
|
|
822
|
-
}
|
|
823
|
-
function providerSupportsOAuth(providerConfig) {
|
|
824
|
-
return oauthConfigOf(providerConfig) !== void 0;
|
|
825
|
-
}
|
|
826
|
-
async function loginPiProvider(options) {
|
|
827
|
-
const oauthConfig = oauthConfigOf(options.providerConfig);
|
|
828
|
-
if (oauthConfig === void 0) throw new Error(`${options.providerName ?? options.providerId} does not support oauth login`);
|
|
829
|
-
const credential = await oauthAdapterOf(oauthConfig).login(oauthInteraction(options.ui, options.signal));
|
|
830
|
-
await options.store.modify(options.providerId, async () => credential);
|
|
831
|
-
return credential;
|
|
832
|
-
}
|
|
833
|
-
async function resolveOAuthApiKey(options) {
|
|
834
|
-
const oauthConfig = oauthConfigOf(options.providerConfig);
|
|
835
|
-
if (oauthConfig === void 0) return void 0;
|
|
836
|
-
return (await resolveProviderAuth({
|
|
837
|
-
id: options.providerId,
|
|
838
|
-
name: options.providerName ?? options.providerId,
|
|
839
|
-
auth: { oauth: oauthAdapterOf(oauthConfig) }
|
|
840
|
-
}, options.store, { env: async () => void 0 }, options.signal !== void 0 ? { signal: options.signal } : void 0))?.auth?.apiKey;
|
|
841
|
-
}
|
|
842
|
-
async function storedOAuthCredential(store, providerId) {
|
|
843
|
-
const stored = await store.read(providerId, void 0);
|
|
844
|
-
return stored?.type === "oauth" ? stored : void 0;
|
|
845
|
-
}
|
|
846
|
-
//#endregion
|
|
847
497
|
//#region src/runtime.ts
|
|
848
498
|
function logger(ctx) {
|
|
849
499
|
const candidate = ctx.logger;
|
|
@@ -2123,6 +1773,12 @@ async function applyPiPackage(ctx, options) {
|
|
|
2123
1773
|
};
|
|
2124
1774
|
subscribeLifecycle(ctx, state);
|
|
2125
1775
|
subscribeInterceptors(ctx, state);
|
|
1776
|
+
for (const provider of builtinProviders()) state.providers.set(provider.id, {
|
|
1777
|
+
name: provider.name,
|
|
1778
|
+
baseUrl: provider.baseUrl,
|
|
1779
|
+
oauth: provider.auth.oauth
|
|
1780
|
+
});
|
|
1781
|
+
ensureLoginCommand(ctx, state);
|
|
2126
1782
|
if (options.manifest.skillDirs.length > 0) {
|
|
2127
1783
|
if (ctx.get("skills") === void 0) logger(ctx).warn("[pi2dsh] migrated skills were not mounted because this DSH composition has no ctx.skills");
|
|
2128
1784
|
else {
|
|
@@ -2161,4 +1817,4 @@ const runtimeInternals = {
|
|
|
2161
1817
|
//#endregion
|
|
2162
1818
|
export { normalizeToolSchema as n, runtimeInternals as r, applyPiPackage as t };
|
|
2163
1819
|
|
|
2164
|
-
//# sourceMappingURL=runtime-
|
|
1820
|
+
//# sourceMappingURL=runtime-6DefpI6h.mjs.map
|