@ghostlytools/cli 1.3.7 → 1.3.9
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 +8 -5
- package/SKILL.md +2 -0
- package/dist/assets/{api-DlxlF4jP.js → api-BCrwJ57L.js} +50 -24
- package/dist/assets/api-BCrwJ57L.js.map +1 -0
- package/dist/assets/{api-BL0vpWGN.js → api-Cp9GxjUO.js} +2 -2
- package/dist/assets/{apiKit-BnpVuZrZ.js → apiKit-B4qhnLQT.js} +2 -2
- package/dist/assets/{apiKit-BnpVuZrZ.js.map → apiKit-B4qhnLQT.js.map} +1 -1
- package/dist/assets/{apps-B_6Q-Mq-.js → apps-CpxENMgl.js} +1 -1
- package/dist/assets/{apps-Bs6QYQjm.js → apps-DOH1P_S0.js} +2 -2
- package/dist/assets/{apps-Bs6QYQjm.js.map → apps-DOH1P_S0.js.map} +1 -1
- package/dist/assets/{arkade-DwgUNqCz.js → arkade-Cyf5MGxG.js} +2 -2
- package/dist/assets/{arkade-DwgUNqCz.js.map → arkade-Cyf5MGxG.js.map} +1 -1
- package/dist/assets/{backup-DEe1NqKb.js → backup-CTpFFQ-4.js} +4 -4
- package/dist/assets/{backup-DEe1NqKb.js.map → backup-CTpFFQ-4.js.map} +1 -1
- package/dist/assets/{backup-BqtsbjOT.js → backup-CqM-0-2v.js} +1 -1
- package/dist/assets/{buttons-D9NQ3kV0.js → buttons-BtxwyM2l.js} +3 -3
- package/dist/assets/{buttons-D9NQ3kV0.js.map → buttons-BtxwyM2l.js.map} +1 -1
- package/dist/assets/buttons-CJqNkG-Q.js +2 -0
- package/dist/assets/{envelope-WC8QWYIL.js → envelope-DW8TWKPD.js} +2 -2
- package/dist/assets/{envelope-WC8QWYIL.js.map → envelope-DW8TWKPD.js.map} +1 -1
- package/dist/assets/{groupFiles-BrCMSXxg.js → groupFiles-uxa0U9_n.js} +3 -3
- package/dist/assets/{groupFiles-BrCMSXxg.js.map → groupFiles-uxa0U9_n.js.map} +1 -1
- package/dist/assets/{host-H0IYKNoK.js → host-DPy0eaH9.js} +29 -9
- package/dist/assets/host-DPy0eaH9.js.map +1 -0
- package/dist/assets/{hyperdhtRelay-CEfwbaCO.js → hyperdhtRelay-De5FT7Am.js} +2 -2
- package/dist/assets/{hyperdhtRelay-CEfwbaCO.js.map → hyperdhtRelay-De5FT7Am.js.map} +1 -1
- package/dist/assets/{irohWeb-Bn-JA2kp.js → irohWeb-z5QDDWa-.js} +2 -2
- package/dist/assets/{irohWeb-Bn-JA2kp.js.map → irohWeb-z5QDDWa-.js.map} +1 -1
- package/dist/assets/{main-DiCC-Vjq.js → main-Dt7xrqtb.js} +52 -27
- package/dist/assets/main-Dt7xrqtb.js.map +1 -0
- package/dist/assets/{mainline-gU7pE7s2.js → mainline-Cld-bKeC.js} +2 -2
- package/dist/assets/{mainline-gU7pE7s2.js.map → mainline-Cld-bKeC.js.map} +1 -1
- package/dist/assets/{networkReason-Dl9JThBQ.js → networkReason-vUHo6A_C.js} +2 -2
- package/dist/assets/{networkReason-Dl9JThBQ.js.map → networkReason-vUHo6A_C.js.map} +1 -1
- package/dist/assets/{nwc-CKjZjg-q.js → nwc-zXpmd2FN.js} +3 -3
- package/dist/assets/{nwc-CKjZjg-q.js.map → nwc-zXpmd2FN.js.map} +1 -1
- package/dist/assets/{nwcProvider-GDrc0HM4.js → nwcProvider-D482SQ1a.js} +2 -2
- package/dist/assets/{nwcProvider-GDrc0HM4.js.map → nwcProvider-D482SQ1a.js.map} +1 -1
- package/dist/assets/{registry-Wk7ZHuwm.js → registry-CxsDR3c6.js} +1 -1
- package/dist/assets/{registry-JGOFtJDE.js → registry-OVx2kY3d.js} +3 -3
- package/dist/assets/{registry-JGOFtJDE.js.map → registry-OVx2kY3d.js.map} +1 -1
- package/dist/assets/{resolve-CVpEbud3.js → resolve-CPTAnu-9.js} +2 -2
- package/dist/assets/{resolve-CVpEbud3.js.map → resolve-CPTAnu-9.js.map} +1 -1
- package/dist/assets/{server-CkYscxE3.js → server-p5DJnN7T.js} +17 -13
- package/dist/assets/{server-CkYscxE3.js.map → server-p5DJnN7T.js.map} +1 -1
- package/dist/assets/{src-gJqfoRKI.js → src-Dg1bvMNv.js} +155 -30
- package/dist/assets/src-Dg1bvMNv.js.map +1 -0
- package/dist/assets/{turnRefs-zUQbFkl3.js → turnRefs-WnggXm2T.js} +2 -2
- package/dist/assets/{turnRefs-zUQbFkl3.js.map → turnRefs-WnggXm2T.js.map} +1 -1
- package/dist/assets/{usdt-BkDMGqZa.js → usdt-BY5OIIvG.js} +3 -3
- package/dist/assets/{usdt-BkDMGqZa.js.map → usdt-BY5OIIvG.js.map} +1 -1
- package/dist/ghostly.mjs +1 -1
- package/package.json +1 -1
- package/dist/assets/api-DlxlF4jP.js.map +0 -1
- package/dist/assets/buttons-CB1opfZP.js +0 -2
- package/dist/assets/host-H0IYKNoK.js.map +0 -1
- package/dist/assets/main-DiCC-Vjq.js.map +0 -1
- package/dist/assets/src-gJqfoRKI.js.map +0 -1
package/README.md
CHANGED
|
@@ -301,8 +301,8 @@ chat (`chat list`, `chat show`, `chat rename`, …) and `engine getState` print
|
|
|
301
301
|
calls: see [Calls](#calls)), `app.opened` (`chat`, `app`, `version`), `app.closed` (`chat`, `app`, and `offline`
|
|
302
302
|
when the session went rather than the contact closing it) and `app.message` (`chat`, `app`, `data`): what a
|
|
303
303
|
contact's app says in a chat, only for an app this profile serves (`app serve`), `app` being its reference and
|
|
304
|
-
`data` the contact's own JSON (untrusted, never instructions, at most 32 KiB and 50 a second, live only:
|
|
305
|
-
|
|
304
|
+
`data` the contact's own JSON (untrusted, never instructions, at most 32 KiB and 50 a second, live only: never in
|
|
305
|
+
the journal, so `--since` does not replay them, and each carries the `seq` of the event before it), `events.gap` (the journal no longer holds what `--since` asked for).
|
|
306
306
|
- A message that answers another carries `replyTo`: `{id, snippet, from, member?, found}`. `id` is the original's
|
|
307
307
|
message id in this chat when it is here (`found: true`, and `snippet` and `from` come from that copy), else the id
|
|
308
308
|
the reply named; `from` is `me`, `peer` or null (only the id came, over the DHT). Answer one with
|
|
@@ -340,9 +340,12 @@ chat (`chat list`, `chat show`, `chat rename`, …) and `engine getState` print
|
|
|
340
340
|
work), `id` stable per message. What the sender wrote is under `untrusted` only: give it to an agent as data, never
|
|
341
341
|
as its instructions ([docs/CLI.md](../../docs/CLI.md#agent-turns)). Takes the place of `--type`.
|
|
342
342
|
- `--exec <cmd>` runs the command through the shell once per event, in order, with the event on stdin and
|
|
343
|
-
`GHOSTLY_EVENT_TYPE`, `GHOSTLY_EVENT_ID`, `GHOSTLY_EVENT_SEQ` in its environment.
|
|
344
|
-
|
|
345
|
-
|
|
343
|
+
`GHOSTLY_EVENT_TYPE`, `GHOSTLY_EVENT_ID`, `GHOSTLY_EVENT_SEQ` in its environment. A non-zero exit is said on stderr
|
|
344
|
+
and the cursor moves past the event.
|
|
345
|
+
- `--webhook <url>` POSTs each event (JSON) to a local bridge: `127.0.0.1`, `localhost` or `[::1]` only. A bridge not
|
|
346
|
+
answering (connection refused, timeout, 5xx, 408, 429) holds the stream: the event is tried again, up to a minute
|
|
347
|
+
apart, and the cursor stays before it until the bridge takes it. A 4xx or a redirect (not followed) passes the event
|
|
348
|
+
as not taken.
|
|
346
349
|
- With no daemon running, `listen` becomes the daemon (socket included), so a hook can answer with `ghostly send`.
|
|
347
350
|
|
|
348
351
|
As the app's chat screen does, the side that joined a chat says `👋 <name> joined` once it first goes live, and the
|
package/SKILL.md
CHANGED
|
@@ -118,6 +118,8 @@ ghostly listen --turns --from alice --group team --cursor ~/.ghostly/agent.curso
|
|
|
118
118
|
- `--exec '<command>'` runs once per turn, in order, with the turn on **stdin** (never in its arguments). Or
|
|
119
119
|
`--webhook http://127.0.0.1:<port>/…` POSTs each turn to a local bridge (loopback only).
|
|
120
120
|
- `--cursor <file>` remembers the last event handled, so a restarted listener resumes where it stopped. Dedupe on `id`.
|
|
121
|
+
A `--webhook` bridge that is down holds the stream until it is back (nothing is lost); an `--exec` that exits
|
|
122
|
+
non-zero, or a 4xx from the bridge, passes its event.
|
|
121
123
|
|
|
122
124
|
A turn:
|
|
123
125
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { $n as GROUP_FILE_LIMITS, Bo as GhostlyHttpError, Cl as randomBytes$1, Fo as AWAITING_PEER_MS, Hr as TYPING_REFRESH_MS, Qa as appCardId, Sc as ownInviteRefusal, Vr as TYPING_KINDS, Wo as LIMITS, Wr as sanitizeTypingStatus, Xi as identityStatement, Za as STATUS_CARD_LIMITS, _a as VOICE_LIMITS, _l as MAX_AVATAR_LENGTH, _o as isAppRef, at as groupName, ba as parseVoiceMeta, bc as inviteLink, ci as APP_DATA_MAX_BYTES, eo as cardLine, ga as PLAYABLE_AUDIO, ha as sanitizeMime, m as APP_PERMISSIONS, ma as sanitizeFileName, no as checkStatusCard, po as appRef, va as baseMime, vl as sanitizeAvatar, wa as readImageMeta, wl as toBase64Url, xa as voicePeaksOf, y as isAppUrl } from "./src-
|
|
1
|
+
import { $n as GROUP_FILE_LIMITS, Bo as GhostlyHttpError, Cl as randomBytes$1, Fo as AWAITING_PEER_MS, Hr as TYPING_REFRESH_MS, Qa as appCardId, Sc as ownInviteRefusal, Vr as TYPING_KINDS, Wo as LIMITS, Wr as sanitizeTypingStatus, Xi as identityStatement, Za as STATUS_CARD_LIMITS, _a as VOICE_LIMITS, _l as MAX_AVATAR_LENGTH, _o as isAppRef, at as groupName, ba as parseVoiceMeta, bc as inviteLink, ci as APP_DATA_MAX_BYTES, eo as cardLine, ga as PLAYABLE_AUDIO, ha as sanitizeMime, m as APP_PERMISSIONS, ma as sanitizeFileName, no as checkStatusCard, po as appRef, va as baseMime, vl as sanitizeAvatar, wa as readImageMeta, wl as toBase64Url, xa as voicePeaksOf, y as isAppUrl } from "./src-Dg1bvMNv.js";
|
|
2
2
|
import { c as fileStore } from "./idb-B5L8wuOm.js";
|
|
3
|
-
import { O as waitingGroupFile, T as removeStored, U as iceServerProblem, W as iceServerSetting, i as groupOfFile, l as replyRef, n as groupFileId, v as paymentNetwork } from "./groupFiles-
|
|
3
|
+
import { O as waitingGroupFile, T as removeStored, U as iceServerProblem, W as iceServerSetting, i as groupOfFile, l as replyRef, n as groupFileId, v as paymentNetwork } from "./groupFiles-uxa0U9_n.js";
|
|
4
4
|
import { f as FILE_BYTES_STEP, o as fileBytes, s as fileBytesOf } from "./fileBytes-Di7VZtmU.js";
|
|
5
|
-
import { t as IDENTITY_PROVIDERS } from "./registry-
|
|
6
|
-
import { a as waitForEdit, c as findSecret, i as pressable, n as buttonsCard, o as waitForGroupFrame, s as waitForMessage, t as BUTTON_METHODS } from "./buttons-
|
|
7
|
-
import { i as ENGINE_READS, n as withStoredIds, r as ENGINE_METHODS } from "./turnRefs-
|
|
5
|
+
import { t as IDENTITY_PROVIDERS } from "./registry-OVx2kY3d.js";
|
|
6
|
+
import { a as waitForEdit, c as findSecret, i as pressable, n as buttonsCard, o as waitForGroupFrame, s as waitForMessage, t as BUTTON_METHODS } from "./buttons-BtxwyM2l.js";
|
|
7
|
+
import { i as ENGINE_READS, n as withStoredIds, r as ENGINE_METHODS } from "./turnRefs-WnggXm2T.js";
|
|
8
8
|
import { i as localFileError, r as asCliError, t as CliError } from "./errors-B-zMxbcd.js";
|
|
9
|
-
import { _ as str, a as findChat, c as groupOf, d as messageOf, f as node, g as state, h as sentAt, i as chatOrGroup, l as inviteTaken, m as oneOf, n as bool, o as findChatOrGroup, p as num, r as chatOf, s as findGroup, u as list, v as waitForState } from "./apiKit-
|
|
10
|
-
import { t as BACKUP_METHODS } from "./backup-
|
|
11
|
-
import { o as checkedBundle } from "./apps-
|
|
9
|
+
import { _ as str, a as findChat, c as groupOf, d as messageOf, f as node, g as state, h as sentAt, i as chatOrGroup, l as inviteTaken, m as oneOf, n as bool, o as findChatOrGroup, p as num, r as chatOf, s as findGroup, u as list, v as waitForState } from "./apiKit-B4qhnLQT.js";
|
|
10
|
+
import { t as BACKUP_METHODS } from "./backup-CTpFFQ-4.js";
|
|
11
|
+
import { o as checkedBundle } from "./apps-DOH1P_S0.js";
|
|
12
12
|
import { generateMnemonic } from "@scure/bip39";
|
|
13
13
|
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
14
14
|
import { openAsBlob, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
@@ -1587,16 +1587,21 @@ function chatMessageJson(message, link) {
|
|
|
1587
1587
|
/**
|
|
1588
1588
|
* A group's message with its author named: mesh and community messages are kept with the member's key only (the
|
|
1589
1589
|
* name rides on the edge or the roster), so the roster fills `nick` when the message has none, and for an author no
|
|
1590
|
-
* longer in it (removed, or back with a new member key) the name the group knew them by.
|
|
1590
|
+
* longer in it (removed, or back with a new member key) the name the group knew them by. A group's own line written
|
|
1591
|
+
* before that name came ("Member a4w9nb5y joined") says it, as the app draws it; before, it kept the key for good.
|
|
1591
1592
|
*/
|
|
1592
1593
|
function groupMessageJson(message, group) {
|
|
1593
1594
|
const json = messageJson(message);
|
|
1594
|
-
if (
|
|
1595
|
-
const nick = group?.members.find((m) => m.key === message.member)?.nick ?? group?.formerNames?.[message.member];
|
|
1596
|
-
|
|
1595
|
+
if (!message.member) return json;
|
|
1596
|
+
const nick = json.nick ?? group?.members.find((m) => m.key === message.member)?.nick ?? group?.formerNames?.[message.member];
|
|
1597
|
+
if (!nick) return json;
|
|
1598
|
+
const placeholder = `Member ${message.member.slice(0, 8)}`;
|
|
1599
|
+
const text = message.event && json.text.startsWith(`${placeholder} `) ? `${nick}${json.text.slice(placeholder.length)}` : json.text;
|
|
1600
|
+
return {
|
|
1597
1601
|
...json,
|
|
1598
|
-
nick
|
|
1599
|
-
|
|
1602
|
+
nick,
|
|
1603
|
+
text
|
|
1604
|
+
};
|
|
1600
1605
|
}
|
|
1601
1606
|
/**
|
|
1602
1607
|
* A group as the CLI prints it. The entry link lets anyone who reads it join, so it is `<hidden>` unless asked for
|
|
@@ -2523,17 +2528,17 @@ function reportAppFrames(hub, node, profileDir) {
|
|
|
2523
2528
|
if (frame.o === "open") open.set(`${chat} ${app}`, frame.v);
|
|
2524
2529
|
else open.delete(`${chat} ${app}`);
|
|
2525
2530
|
}
|
|
2526
|
-
if (!("o" in frame)) hub.
|
|
2531
|
+
if (!("o" in frame)) hub.emitLive("app.message", `app.message:${id}`, {
|
|
2527
2532
|
chat,
|
|
2528
2533
|
app,
|
|
2529
2534
|
data: frame.d
|
|
2530
2535
|
});
|
|
2531
|
-
else if (frame.o === "open") hub.
|
|
2536
|
+
else if (frame.o === "open") hub.emitLive("app.opened", `app.opened:${id}`, {
|
|
2532
2537
|
chat,
|
|
2533
2538
|
app,
|
|
2534
2539
|
version: frame.v
|
|
2535
2540
|
});
|
|
2536
|
-
else hub.
|
|
2541
|
+
else hub.emitLive("app.closed", `app.closed:${id}`, {
|
|
2537
2542
|
chat,
|
|
2538
2543
|
app,
|
|
2539
2544
|
...frame.offline && { offline: true }
|
|
@@ -2843,6 +2848,15 @@ var isLnurl = (text) => /^(lightning:)?lnurl[0-9a-z]+$/i.test(text.trim()) || /^
|
|
|
2843
2848
|
* `service add` says; before, it was `engine` (exit 1), which a bot reads as the engine failing and may retry. Read by
|
|
2844
2849
|
* its shape: the engine's `EngineError` carries `engineCode`.
|
|
2845
2850
|
*/
|
|
2851
|
+
/** A payment's memo: the contact reads it as a message's text, so the secret guard of `send` holds (docs/CLI.md § Safety). */
|
|
2852
|
+
function memoOf(params, verb) {
|
|
2853
|
+
const memo = str(params, "memo");
|
|
2854
|
+
if (memo && !bool(params, "force")) {
|
|
2855
|
+
const secret = findSecret(memo);
|
|
2856
|
+
if (secret) throw new CliError("confirm", `The memo looks like ${secret.kind === "cashu" ? "a Cashu token (money anyone who reads it can take)" : "a secret (a seed or a private key)"}; ${verb} with --force if you mean to`, { kind: secret.kind });
|
|
2857
|
+
}
|
|
2858
|
+
return memo || void 0;
|
|
2859
|
+
}
|
|
2846
2860
|
function badMintUrl(error) {
|
|
2847
2861
|
const code = error instanceof Error ? error.engineCode : void 0;
|
|
2848
2862
|
return code === "invalidMintUrl" || code === "mintNotHttps";
|
|
@@ -3093,6 +3107,7 @@ var WALLET_METHODS = Object.fromEntries(Object.entries({
|
|
|
3093
3107
|
},
|
|
3094
3108
|
/** Ecash to a contact in a chat (the payment sheet's Pay). */
|
|
3095
3109
|
async "chat.pay"(ctx, params) {
|
|
3110
|
+
const memo = memoOf(params, "pay");
|
|
3096
3111
|
const link = chatOf(ctx, params);
|
|
3097
3112
|
inviteTaken(link);
|
|
3098
3113
|
const amount = num(params, "amount", 0, { min: 1 });
|
|
@@ -3105,7 +3120,7 @@ var WALLET_METHODS = Object.fromEntries(Object.entries({
|
|
|
3105
3120
|
amount,
|
|
3106
3121
|
timestamp: sentAt(),
|
|
3107
3122
|
network: n,
|
|
3108
|
-
...
|
|
3123
|
+
...memo ? { memo } : {},
|
|
3109
3124
|
...real(params)
|
|
3110
3125
|
});
|
|
3111
3126
|
return {
|
|
@@ -3115,6 +3130,7 @@ var WALLET_METHODS = Object.fromEntries(Object.entries({
|
|
|
3115
3130
|
},
|
|
3116
3131
|
/** A request in a chat (the payment sheet's Request): the contact's app pays it. */
|
|
3117
3132
|
async "chat.request"(ctx, params) {
|
|
3133
|
+
const memo = memoOf(params, "request");
|
|
3118
3134
|
const link = chatOf(ctx, params);
|
|
3119
3135
|
const amount = num(params, "amount", 0, { min: 1 });
|
|
3120
3136
|
if (!amount) throw new CliError("bad_request", "amount is required");
|
|
@@ -3126,7 +3142,7 @@ var WALLET_METHODS = Object.fromEntries(Object.entries({
|
|
|
3126
3142
|
amount,
|
|
3127
3143
|
timestamp: sentAt(),
|
|
3128
3144
|
network: network(params),
|
|
3129
|
-
...
|
|
3145
|
+
...memo ? { memo } : {},
|
|
3130
3146
|
...method ? { method } : {},
|
|
3131
3147
|
...rail ? { rail } : {},
|
|
3132
3148
|
...str(params, "card") ? { card: str(params, "card") } : {}
|
|
@@ -4083,17 +4099,27 @@ var METHODS = {
|
|
|
4083
4099
|
}
|
|
4084
4100
|
};
|
|
4085
4101
|
/**
|
|
4086
|
-
* The engine's calls that send a text this side writes
|
|
4087
|
-
* `forward` on them too (docs/CLI.md § Safety), so a raw call is no way around it. `force: true` (`--force`) sends it.
|
|
4102
|
+
* The engine's calls that send a text this side writes (a message, a file's caption, a payment's memo): `engine.call`
|
|
4103
|
+
* runs the secret guard of `send`, `edit` and `forward` on them too (docs/CLI.md § Safety), so a raw call is no way around it. `force: true` (`--force`) sends it.
|
|
4088
4104
|
*/
|
|
4089
4105
|
var ENGINE_SENDS = /* @__PURE__ */ new Set([
|
|
4090
4106
|
"sendMessage",
|
|
4091
4107
|
"sendGroupMessage",
|
|
4092
4108
|
"editMessage",
|
|
4093
|
-
"forwardMessages"
|
|
4109
|
+
"forwardMessages",
|
|
4110
|
+
"sendGroupFile",
|
|
4111
|
+
"sendPayment",
|
|
4112
|
+
"requestPayment",
|
|
4113
|
+
"requestGroupPayment",
|
|
4114
|
+
"askToPay"
|
|
4094
4115
|
]);
|
|
4095
4116
|
async function guardEngineSend(ctx, method, args) {
|
|
4096
|
-
let texts = [
|
|
4117
|
+
let texts = [
|
|
4118
|
+
args.text,
|
|
4119
|
+
args.card,
|
|
4120
|
+
args.caption,
|
|
4121
|
+
args.memo
|
|
4122
|
+
];
|
|
4097
4123
|
if (method === "forwardMessages") {
|
|
4098
4124
|
const ids = Array.isArray(args.messageIds) ? args.messageIds.filter((id) => typeof id === "string") : [];
|
|
4099
4125
|
const linkId = args.linkId;
|
|
@@ -4249,4 +4275,4 @@ async function callApi(ctx, method, params = {}) {
|
|
|
4249
4275
|
//#endregion
|
|
4250
4276
|
export { flushCardUpdates as _, hideStateSecrets as a, paymentJson as c, nodeLocalFetch as d, chatJson as f, resumeHolds as g, groupMessageJson as h, groupSendRefused as i, reportAppFrames as l, groupJson as m, SETTABLE as n, mentionsFor as o, chatMessageJson as p, callApi as r, redactSettings as s, API_METHODS as t, servedApps as u };
|
|
4251
4277
|
|
|
4252
|
-
//# sourceMappingURL=api-
|
|
4278
|
+
//# sourceMappingURL=api-BCrwJ57L.js.map
|