@flapsdk/vault-runtime 0.1.0 → 0.1.2
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 +2 -2
- package/host.d.mts +4 -4
- package/host.js +123 -25
- package/host.js.map +1 -1
- package/{hostRuntimeConfig-BOEJo2nq.d.mts → hostRuntimeConfig-8d2c6qsO.d.mts} +1 -1
- package/package.json +1 -1
- package/runtime-contract.json +1 -1
- package/sdk.d.mts +6 -5
- package/sdk.js +120 -24
- package/sdk.js.map +1 -1
- package/server.d.mts +15 -4
- package/server.js +136 -9
- package/server.js.map +1 -1
- package/{txError-1lPZHdqI.d.mts → txError-BmDt5Z4B.d.mts} +25 -3
- package/{types-CX7pLmiT.d.mts → types-DzTX2u7q.d.mts} +20 -2
- package/ui.js.map +1 -1
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ This package is the shared runtime surface that local preview, Artifact Workbenc
|
|
|
6
6
|
|
|
7
7
|
## Exports
|
|
8
8
|
|
|
9
|
-
- `./sdk`: component-facing SDK hooks, helpers, types, and
|
|
9
|
+
- `./sdk`: component-facing SDK hooks, helpers, types, provider, and local oracle reader helper
|
|
10
10
|
- `./ui`: shared UI primitives
|
|
11
11
|
- `./host`: host/runtime preflight helpers
|
|
12
|
-
- `./server`: server-side presentation
|
|
12
|
+
- `./server`: server-side presentation plus runtime oracle-registry helpers
|
|
13
13
|
|
|
14
14
|
See `runtime-contract.json` for the machine-readable subpath contract.
|
package/host.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { a as Address,
|
|
2
|
-
export { A as ActionAvailabilityStage, C as ContractReadRequest, b as ContractWriteRequest, E as EndpointPolicy, F as FeeMode, d as FlapFeeVaultInfo, e as FlapI18n, f as FlapNotify, g as FlapTaxInfo, h as FlapTokenInfo, i as FlapVaultPortalInfo, j as FlapVaultSdk, k as FlapWallet, l as HostRuntimeDataSource, m as HostRuntimeDegradeReason, o as HostRuntimePolicy, p as HostRuntimePresentationFetcher, q as HostRuntimePresentationRequest, s as HostRuntimeSources, t as HostRuntimeStatus, u as HostRuntimeWarning, v as HostTokenPresentation, M as ManifestBindingEntry, P as PaymentToken, S as SimulateResult, T as TokenMarketPhase,
|
|
3
|
-
export { C as CreateTaxInfoHostContextInput, R as ResolveRenderSurfaceInput, a as RuntimeMatchInput, T as TaxVaultHostSnapshot, b as TxErrorKind, V as VaultBindingPolicy, Z as ZERO_ADDRESS, c as createTaxInfoHostContext, f as formatCountdown,
|
|
1
|
+
import { a as Address, B as TokenRuntimeSnapshot, z as TokenMetadataSnapshot, n as HostRuntimeInput, H as HostRuntimeAddresses, r as HostRuntimeResult, c as CreateVaultRuntimeContextInput, K as VaultRuntimeContext } from './types-DzTX2u7q.mjs';
|
|
2
|
+
export { A as ActionAvailabilityStage, C as ContractReadRequest, b as ContractWriteRequest, E as EndpointPolicy, F as FeeMode, d as FlapFeeVaultInfo, e as FlapI18n, f as FlapNotify, g as FlapTaxInfo, h as FlapTokenInfo, i as FlapVaultPortalInfo, j as FlapVaultSdk, k as FlapWallet, l as HostRuntimeDataSource, m as HostRuntimeDegradeReason, o as HostRuntimePolicy, p as HostRuntimePresentationFetcher, q as HostRuntimePresentationRequest, s as HostRuntimeSources, t as HostRuntimeStatus, u as HostRuntimeWarning, v as HostTokenPresentation, M as ManifestBindingEntry, w as ManifestExternalContract, O as OracleProvision, x as OracleReadRequest, y as OracleReader, P as PaymentToken, R as RuntimeOracleRegistry, S as SimulateResult, T as TokenMarketPhase, D as TxReceipt, V as VaultComponentProps, G as VaultHostContext, I as VaultManifest, J as VaultRenderSurface, L as VaultRuntimeContextOverrides, N as VaultRuntimeExtraConfig } from './types-DzTX2u7q.mjs';
|
|
3
|
+
export { C as CreateTaxInfoHostContextInput, O as OracleReadError, R as ResolveRenderSurfaceInput, a as RuntimeMatchInput, T as TaxVaultHostSnapshot, b as TxErrorKind, V as VaultBindingPolicy, Z as ZERO_ADDRESS, c as buildLocalOracleUrl, d as createLocalOracleReader, e as createTaxInfoHostContext, f as fetchOracleJson, g as fetchProvisionedOracle, h as formatCountdown, i as formatPercentBps, j as formatTokenAmount, k as getTupleField, l as getTxErrorKind, m as handleTxError, n as isActionAvailableForPhase, o as isCustomVaultTaxToken, p as isManifestRuntimeMatch, q as isSameAddress, r as isValidAddress, s as isVaultBindingMatch, t as normalizeAddress, u as parseFeeVaultInfo, v as parsePortalTokenInfo, w as parseTaxTokenInfo, x as parseTokenAmount, y as parseVaultPortalInfo, z as readTaxVaultHostContext, A as resolveFeeMode, B as resolveManifestBinding, D as resolveTaxInfoRenderSurface, E as resolveTokenMarketPhase, F as resolveVaultBinding, G as shortenAddress, H as standardErc20Abi } from './txError-BmDt5Z4B.mjs';
|
|
4
4
|
import { PublicClient } from 'viem';
|
|
5
5
|
export { erc20Abi } from 'viem';
|
|
6
|
-
export { T as TaxVaultHostChainConfig, g as getTaxVaultHostChainConfig } from './hostRuntimeConfig-
|
|
6
|
+
export { T as TaxVaultHostChainConfig, g as getTaxVaultHostChainConfig } from './hostRuntimeConfig-8d2c6qsO.mjs';
|
|
7
7
|
|
|
8
8
|
declare function readErc20TokenMetadata(publicClient: PublicClient, tokenAddress?: Address | null): Promise<TokenMetadataSnapshot | null>;
|
|
9
9
|
declare function loadTokenRuntimeSnapshot(publicClient: PublicClient, chainId: number, tokenAddress?: Address | null): Promise<TokenRuntimeSnapshot | null>;
|
package/host.js
CHANGED
|
@@ -28,9 +28,11 @@ function formatCountdown(targetTimeMs) {
|
|
|
28
28
|
if (!targetTimeMs) return "-";
|
|
29
29
|
const diff = Math.max(0, targetTimeMs - Date.now());
|
|
30
30
|
const totalSeconds = Math.floor(diff / 1e3);
|
|
31
|
-
const
|
|
31
|
+
const days = Math.floor(totalSeconds / 86400);
|
|
32
|
+
const hours = Math.floor(totalSeconds % 86400 / 3600);
|
|
32
33
|
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
33
34
|
const seconds = totalSeconds % 60;
|
|
35
|
+
if (days > 0) return `${days}d ${hours}h ${minutes}m`;
|
|
34
36
|
if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
|
|
35
37
|
return `${minutes}m ${seconds}s`;
|
|
36
38
|
}
|
|
@@ -181,26 +183,52 @@ function resolveManifestBinding(manifest, input) {
|
|
|
181
183
|
if (candidates.length === 1) return candidates[0];
|
|
182
184
|
return null;
|
|
183
185
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
const matchesChain = (binding) => !input.chainId || binding.chainId === input.chainId;
|
|
187
|
+
const matchesToken = (binding) => !input.tokenAddress || !binding.tokenAddresses?.length || binding.tokenAddresses.some((address) => isSameAddress(address, input.tokenAddress));
|
|
188
|
+
const isVaultScopedBinding = (binding) => !binding.factoryAddress && Boolean(binding.vaultAddresses?.length);
|
|
189
|
+
if (input.factoryAddress) {
|
|
190
|
+
const factoryMatch = resolveUnique(
|
|
191
|
+
bindings.filter((binding) => matchesChain(binding) && Boolean(binding.factoryAddress) && isSameAddress(binding.factoryAddress, input.factoryAddress) && matchesToken(binding))
|
|
192
|
+
);
|
|
193
|
+
if (factoryMatch || !input.vaultAddress) return factoryMatch;
|
|
194
|
+
}
|
|
195
|
+
if (input.vaultAddress) {
|
|
196
|
+
const vaultMatch = resolveUnique(
|
|
197
|
+
bindings.filter(
|
|
198
|
+
(binding) => matchesChain(binding) && isVaultScopedBinding(binding) && Boolean(binding.vaultAddresses?.some((address) => isSameAddress(address, input.vaultAddress))) && matchesToken(binding)
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
if (vaultMatch) return vaultMatch;
|
|
202
|
+
}
|
|
203
|
+
if (input.factoryAddress || input.vaultAddress) {
|
|
204
|
+
return null;
|
|
186
205
|
}
|
|
187
206
|
if (input.chainId) {
|
|
188
|
-
return resolveUnique(bindings.filter((binding) => binding.chainId === input.chainId));
|
|
207
|
+
return resolveUnique(bindings.filter((binding) => binding.chainId === input.chainId && matchesToken(binding)));
|
|
189
208
|
}
|
|
190
|
-
if (input.
|
|
191
|
-
return resolveUnique(bindings.filter((binding) => isSameAddress(
|
|
209
|
+
if (input.tokenAddress) {
|
|
210
|
+
return resolveUnique(bindings.filter((binding) => binding.tokenAddresses?.some((address) => isSameAddress(address, input.tokenAddress))));
|
|
192
211
|
}
|
|
193
212
|
return null;
|
|
194
213
|
}
|
|
195
214
|
function isManifestRuntimeMatch(manifest, input) {
|
|
196
|
-
if (!input.chainId || !input.factoryAddress) return false;
|
|
215
|
+
if (!input.chainId || !input.factoryAddress && !input.vaultAddress) return false;
|
|
197
216
|
const matchingBinding = resolveManifestBinding(manifest, input);
|
|
198
217
|
if (!matchingBinding) return false;
|
|
199
|
-
|
|
218
|
+
if (matchingBinding.chainId !== input.chainId) return false;
|
|
219
|
+
if (matchingBinding.factoryAddress) return isSameAddress(matchingBinding.factoryAddress, input.factoryAddress);
|
|
220
|
+
const vaultAddress = matchingBinding.vaultAddresses?.[0];
|
|
221
|
+
if (!vaultAddress || !isSameAddress(vaultAddress, input.vaultAddress)) return false;
|
|
222
|
+
if (input.tokenAddress && matchingBinding.tokenAddresses?.length) {
|
|
223
|
+
return matchingBinding.tokenAddresses.some((address) => isSameAddress(address, input.tokenAddress));
|
|
224
|
+
}
|
|
225
|
+
return true;
|
|
200
226
|
}
|
|
201
227
|
function isVaultBindingMatch(binding, input) {
|
|
202
228
|
if (!input.chainId || binding.chainId !== input.chainId) return false;
|
|
203
|
-
if (
|
|
229
|
+
if (binding.factoryAddress) return Boolean(input.factoryAddress && isSameAddress(binding.factoryAddress, input.factoryAddress));
|
|
230
|
+
const vaultAddress = binding.vaultAddresses?.[0];
|
|
231
|
+
if (!vaultAddress || !input.vaultAddress || !isSameAddress(vaultAddress, input.vaultAddress)) return false;
|
|
204
232
|
return true;
|
|
205
233
|
}
|
|
206
234
|
function resolveVaultBinding(bindings, input) {
|
|
@@ -482,8 +510,15 @@ async function readErc20TokenMetadata(publicClient, tokenAddress) {
|
|
|
482
510
|
}
|
|
483
511
|
async function loadTokenRuntimeSnapshot(publicClient, chainId, tokenAddress) {
|
|
484
512
|
if (!tokenAddress || !isValidAddress(tokenAddress) || tokenAddress === ZERO_ADDRESS) return null;
|
|
485
|
-
const metadata = await readErc20TokenMetadata(publicClient, tokenAddress);
|
|
486
513
|
const chainConfig = getTaxVaultHostChainConfig(chainId);
|
|
514
|
+
const metadataPromise = readErc20TokenMetadata(publicClient, tokenAddress);
|
|
515
|
+
const portalPromise = chainConfig ? publicClient.readContract({
|
|
516
|
+
address: chainConfig.portal,
|
|
517
|
+
abi: portalAbi,
|
|
518
|
+
functionName: "getTokenV7",
|
|
519
|
+
args: [tokenAddress]
|
|
520
|
+
}).then((data) => ({ ok: true, data })).catch(() => ({ ok: false })) : Promise.resolve(null);
|
|
521
|
+
const [metadata, portalResult] = await Promise.all([metadataPromise, portalPromise]);
|
|
487
522
|
const baseSnapshot = {
|
|
488
523
|
tokenSymbol: metadata?.tokenSymbol,
|
|
489
524
|
tokenName: metadata?.tokenName,
|
|
@@ -497,15 +532,7 @@ async function loadTokenRuntimeSnapshot(publicClient, chainId, tokenAddress) {
|
|
|
497
532
|
hostReadFromChain: false
|
|
498
533
|
};
|
|
499
534
|
}
|
|
500
|
-
|
|
501
|
-
try {
|
|
502
|
-
tokenData = await publicClient.readContract({
|
|
503
|
-
address: chainConfig.portal,
|
|
504
|
-
abi: portalAbi,
|
|
505
|
-
functionName: "getTokenV7",
|
|
506
|
-
args: [tokenAddress]
|
|
507
|
-
});
|
|
508
|
-
} catch {
|
|
535
|
+
if (!portalResult || !portalResult.ok) {
|
|
509
536
|
return {
|
|
510
537
|
...baseSnapshot,
|
|
511
538
|
hasTaxVaults: Boolean(chainConfig.vaultPortal),
|
|
@@ -514,6 +541,7 @@ async function loadTokenRuntimeSnapshot(publicClient, chainId, tokenAddress) {
|
|
|
514
541
|
giftVaultFactory: chainConfig.giftVaultFactory
|
|
515
542
|
};
|
|
516
543
|
}
|
|
544
|
+
const tokenData = portalResult.data;
|
|
517
545
|
const tokenInfo = parsePortalTokenInfo(tokenData);
|
|
518
546
|
const hasTaxVaults = Boolean(chainConfig.vaultPortal);
|
|
519
547
|
if (!tokenInfo) {
|
|
@@ -607,8 +635,8 @@ function resolveAddresses(input, snapshot) {
|
|
|
607
635
|
tokenAddress: input.tokenAddress,
|
|
608
636
|
factoryAddressHint: input.factoryAddressHint,
|
|
609
637
|
vaultAddressHint: input.vaultAddressHint,
|
|
610
|
-
factoryAddress: pickAddress(
|
|
611
|
-
vaultAddress: pickAddress(
|
|
638
|
+
factoryAddress: pickAddress(snapshot?.vaultInfo?.vaultFactory, snapshot?.taxInfo?.vaultInfo?.factory ?? void 0, input.factoryAddressHint),
|
|
639
|
+
vaultAddress: pickAddress(snapshot?.vaultInfo?.vault, snapshot?.taxInfo?.vaultInfo?.addr ?? void 0, input.vaultAddressHint)
|
|
612
640
|
};
|
|
613
641
|
}
|
|
614
642
|
function hasPresentationMetadata(result) {
|
|
@@ -700,11 +728,12 @@ async function runHostRuntime(input) {
|
|
|
700
728
|
let presentationFailure;
|
|
701
729
|
if (input.presentationFetcher) {
|
|
702
730
|
try {
|
|
731
|
+
const resolvedAddrs = resolveAddresses(input, snapshot);
|
|
703
732
|
presentation = await input.presentationFetcher({
|
|
704
733
|
chainId: input.chainId,
|
|
705
734
|
tokenAddress: input.tokenAddress,
|
|
706
|
-
factoryAddress:
|
|
707
|
-
vaultAddress:
|
|
735
|
+
factoryAddress: resolvedAddrs.factoryAddress,
|
|
736
|
+
vaultAddress: resolvedAddrs.vaultAddress,
|
|
708
737
|
snapshot
|
|
709
738
|
});
|
|
710
739
|
if (!presentation) {
|
|
@@ -752,6 +781,73 @@ async function runHostRuntime(input) {
|
|
|
752
781
|
return result;
|
|
753
782
|
}
|
|
754
783
|
|
|
784
|
+
// src/sdk/oracle.ts
|
|
785
|
+
var DEFAULT_LOCAL_ORACLE_ENDPOINT_BASE = "/api/runtime/oracle";
|
|
786
|
+
var OracleReadError = class extends Error {
|
|
787
|
+
constructor(message, status) {
|
|
788
|
+
super(message);
|
|
789
|
+
this.name = "OracleReadError";
|
|
790
|
+
this.status = status;
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
function appendSearchParams(url, params) {
|
|
794
|
+
for (const [key, value] of Object.entries(params ?? {})) {
|
|
795
|
+
url.searchParams.set(key, value);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function toOracleProvision(provision) {
|
|
799
|
+
return typeof provision === "string" ? { endpoint: provision } : provision;
|
|
800
|
+
}
|
|
801
|
+
function buildLocalOracleUrl(oracleId, params, endpointBase = DEFAULT_LOCAL_ORACLE_ENDPOINT_BASE) {
|
|
802
|
+
const normalizedBase = endpointBase.replace(/\/+$/, "");
|
|
803
|
+
const url = new URL(`${normalizedBase}/${encodeURIComponent(oracleId)}`, "http://localhost");
|
|
804
|
+
appendSearchParams(url, params);
|
|
805
|
+
return `${url.pathname}${url.search}`;
|
|
806
|
+
}
|
|
807
|
+
async function fetchOracleJson({
|
|
808
|
+
endpoint,
|
|
809
|
+
params,
|
|
810
|
+
fetchImpl,
|
|
811
|
+
headers
|
|
812
|
+
}) {
|
|
813
|
+
const fallbackOrigin = typeof window !== "undefined" ? window.location.origin : "http://localhost";
|
|
814
|
+
const url = new URL(endpoint, fallbackOrigin);
|
|
815
|
+
appendSearchParams(url, params);
|
|
816
|
+
const response = await (fetchImpl ?? fetch)(url.toString(), {
|
|
817
|
+
cache: "no-store",
|
|
818
|
+
headers,
|
|
819
|
+
method: "GET"
|
|
820
|
+
});
|
|
821
|
+
if (!response.ok) {
|
|
822
|
+
throw new OracleReadError(`Oracle request returned ${response.status}.`, response.status);
|
|
823
|
+
}
|
|
824
|
+
return await response.json();
|
|
825
|
+
}
|
|
826
|
+
async function fetchProvisionedOracle({
|
|
827
|
+
provision,
|
|
828
|
+
params,
|
|
829
|
+
fetchImpl
|
|
830
|
+
}) {
|
|
831
|
+
const normalizedProvision = toOracleProvision(provision);
|
|
832
|
+
const filteredParams = normalizedProvision.allowedParams && normalizedProvision.allowedParams.length ? Object.fromEntries(Object.entries(params ?? {}).filter(([key]) => normalizedProvision.allowedParams?.includes(key))) : params;
|
|
833
|
+
return fetchOracleJson({
|
|
834
|
+
endpoint: normalizedProvision.endpoint,
|
|
835
|
+
params: filteredParams,
|
|
836
|
+
fetchImpl,
|
|
837
|
+
headers: normalizedProvision.headers
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
function createLocalOracleReader(options = {}) {
|
|
841
|
+
const endpointBase = options.endpointBase ?? DEFAULT_LOCAL_ORACLE_ENDPOINT_BASE;
|
|
842
|
+
const fetchImpl = options.fetchImpl;
|
|
843
|
+
return async function readLocalOracle({ oracleId, params }) {
|
|
844
|
+
return fetchOracleJson({
|
|
845
|
+
endpoint: buildLocalOracleUrl(oracleId, params, endpointBase),
|
|
846
|
+
fetchImpl
|
|
847
|
+
});
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
|
|
755
851
|
// src/sdk/runtimeContext.ts
|
|
756
852
|
var zeroAddress = "0x0000000000000000000000000000000000000000";
|
|
757
853
|
function explorerForChain(chainId) {
|
|
@@ -782,7 +878,9 @@ function createVaultRuntimeContext(input) {
|
|
|
782
878
|
const runtimeOverrides = input.runtimeOverrides;
|
|
783
879
|
const resolvedBinding = resolveManifestBinding(input.manifest, {
|
|
784
880
|
chainId: runtimeOverrides?.chainId ?? input.connectedChainId ?? input.hostRuntimeResult?.addresses.chainId,
|
|
785
|
-
factoryAddress: runtimeOverrides?.factoryAddress ?? input.hostRuntimeResult?.addresses.factoryAddress
|
|
881
|
+
factoryAddress: runtimeOverrides?.factoryAddress ?? input.hostRuntimeResult?.addresses.factoryAddress,
|
|
882
|
+
vaultAddress: runtimeOverrides?.vaultAddress ?? input.hostRuntimeResult?.addresses.vaultAddress,
|
|
883
|
+
tokenAddress: runtimeOverrides?.tokenAddress ?? input.hostRuntimeResult?.addresses.tokenAddress
|
|
786
884
|
});
|
|
787
885
|
const effectiveChainId = runtimeOverrides?.chainId ?? input.hostRuntimeResult?.addresses.chainId ?? input.connectedChainId ?? resolvedBinding?.chainId ?? input.manifest.match.bindings[0]?.chainId ?? 56;
|
|
788
886
|
return {
|
|
@@ -866,6 +964,6 @@ function handleTxError(error, messages) {
|
|
|
866
964
|
return messages?.[kind] ?? defaultMessages[kind];
|
|
867
965
|
}
|
|
868
966
|
|
|
869
|
-
export { ZERO_ADDRESS, chainLabelForChain, createTaxInfoHostContext, createVaultRuntimeContext, explorerForChain, formatCountdown, formatPercentBps, formatTokenAmount, getTaxVaultHostChainConfig, getTupleField, getTxErrorKind, handleTxError, isActionAvailableForPhase, isCustomVaultTaxToken, isManifestRuntimeMatch, isSameAddress, isValidAddress, isVaultBindingMatch, loadTokenRuntimeSnapshot, normalizeAddress, parseFeeVaultInfo, parsePortalTokenInfo, parseTaxTokenInfo, parseTokenAmount, parseVaultPortalInfo, readErc20TokenMetadata, readTaxVaultHostContext, resolveFeeMode, resolveHostRuntimeAddresses, resolveManifestBinding, resolveTaxInfoRenderSurface, resolveTokenMarketPhase, resolveVaultBinding, runHostRuntime, shortenAddress, standardErc20Abi };
|
|
967
|
+
export { OracleReadError, ZERO_ADDRESS, buildLocalOracleUrl, chainLabelForChain, createLocalOracleReader, createTaxInfoHostContext, createVaultRuntimeContext, explorerForChain, fetchOracleJson, fetchProvisionedOracle, formatCountdown, formatPercentBps, formatTokenAmount, getTaxVaultHostChainConfig, getTupleField, getTxErrorKind, handleTxError, isActionAvailableForPhase, isCustomVaultTaxToken, isManifestRuntimeMatch, isSameAddress, isValidAddress, isVaultBindingMatch, loadTokenRuntimeSnapshot, normalizeAddress, parseFeeVaultInfo, parsePortalTokenInfo, parseTaxTokenInfo, parseTokenAmount, parseVaultPortalInfo, readErc20TokenMetadata, readTaxVaultHostContext, resolveFeeMode, resolveHostRuntimeAddresses, resolveManifestBinding, resolveTaxInfoRenderSurface, resolveTokenMarketPhase, resolveVaultBinding, runHostRuntime, shortenAddress, standardErc20Abi };
|
|
870
968
|
//# sourceMappingURL=host.js.map
|
|
871
969
|
//# sourceMappingURL=host.js.map
|