@absolutejs/absolute 0.20.0-beta.82 → 0.20.0-beta.83
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +224 -2
- package/dist/build.js.map +3 -3
- package/dist/cli/index.js +1 -1
- package/dist/cli/{mobile-hkxh2ab5.js → mobile-9dx39bd3.js} +143 -2
- package/dist/index.js +224 -2
- package/dist/index.js.map +3 -3
- package/dist/mobile/index.js +265 -2
- package/dist/mobile/index.js.map +4 -4
- package/dist/src/mobile/updatePublisher.d.ts +19 -0
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-WzbAzY/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-WzbAzY/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-WzbAzY/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/build.js
CHANGED
|
@@ -28480,7 +28480,7 @@ import {
|
|
|
28480
28480
|
} from "crypto";
|
|
28481
28481
|
import { readFile as readFile9, stat as stat3 } from "fs/promises";
|
|
28482
28482
|
import path from "path";
|
|
28483
|
-
var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", MobileUpdateRegistryError, object3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field) => {
|
|
28483
|
+
var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, DAY_MS, DEFAULT_MIN_AGE_MS, DEFAULT_GRACE_PERIOD_MS, DEFAULT_RETAIN_RECENT = 5, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", MobileUpdateRegistryError, object3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field) => {
|
|
28484
28484
|
if (typeof value !== "string" || value.length === 0)
|
|
28485
28485
|
throw new MobileUpdateRegistryError(`Mobile update ${field} is invalid`);
|
|
28486
28486
|
return value;
|
|
@@ -28647,6 +28647,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
28647
28647
|
const releaseRoot = (manifest) => `${root(manifest.appId)}/releases/${manifest.releaseId}`;
|
|
28648
28648
|
const manifestKey = (manifest) => `${releaseRoot(manifest)}/update.json`;
|
|
28649
28649
|
const fileKey = (manifest, file5) => `${releaseRoot(manifest)}/files/${file5.path}`;
|
|
28650
|
+
const tombstoneKey = (appId, releaseId) => `${root(appId)}/gc/${releaseId}.json`;
|
|
28650
28651
|
const channelKey = (appId, channel) => {
|
|
28651
28652
|
if (!APP_ID.test(appId) || !NAME.test(channel))
|
|
28652
28653
|
throw new MobileUpdateRegistryError("Mobile update channel identity is invalid");
|
|
@@ -28675,6 +28676,12 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
28675
28676
|
throw new MobileUpdateRegistryError("Stored mobile update channel identity changed");
|
|
28676
28677
|
return value;
|
|
28677
28678
|
};
|
|
28679
|
+
const assertNotMarked = async (appId, releaseId) => {
|
|
28680
|
+
if (!APP_ID.test(appId) || !RELEASE.test(releaseId))
|
|
28681
|
+
throw new MobileUpdateRegistryError("Mobile update release identity is invalid");
|
|
28682
|
+
if (await options.store.head(tombstoneKey(appId, releaseId)))
|
|
28683
|
+
throw new MobileUpdateRegistryError("Mobile update release is marked for collection. Increase retention and apply garbage collection to restore it before promotion");
|
|
28684
|
+
};
|
|
28678
28685
|
const writeChannel = async (input, signal) => {
|
|
28679
28686
|
const value = {
|
|
28680
28687
|
...input,
|
|
@@ -28699,6 +28706,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
28699
28706
|
input.signal?.throwIfAborted();
|
|
28700
28707
|
if (input.rollout <= 0 || input.rollout > 1)
|
|
28701
28708
|
throw new MobileUpdateRegistryError("Mobile update rollout is invalid");
|
|
28709
|
+
await assertNotMarked(input.appId, input.releaseId);
|
|
28702
28710
|
const release = await readManifest2(input.appId, input.releaseId);
|
|
28703
28711
|
if (!release || release.manifest.channel !== input.channel)
|
|
28704
28712
|
throw new MobileUpdateRegistryError("Mobile update was not published to this channel");
|
|
@@ -28744,11 +28752,221 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
28744
28752
|
status: "selected"
|
|
28745
28753
|
};
|
|
28746
28754
|
};
|
|
28755
|
+
const retentionValues = (input) => {
|
|
28756
|
+
if (!APP_ID.test(input.appId))
|
|
28757
|
+
throw new MobileUpdateRegistryError("Mobile update appId is invalid");
|
|
28758
|
+
const retainRecent = input.retainRecent ?? DEFAULT_RETAIN_RECENT;
|
|
28759
|
+
const minAgeMs = input.minAgeMs ?? DEFAULT_MIN_AGE_MS;
|
|
28760
|
+
if (!Number.isSafeInteger(retainRecent) || retainRecent < 0)
|
|
28761
|
+
throw new MobileUpdateRegistryError("Mobile update retained release count is invalid");
|
|
28762
|
+
if (!Number.isSafeInteger(minAgeMs) || minAgeMs < 0)
|
|
28763
|
+
throw new MobileUpdateRegistryError("Mobile update minimum release age is invalid");
|
|
28764
|
+
return { minAgeMs, retainRecent };
|
|
28765
|
+
};
|
|
28766
|
+
const listObjects = async (appId, signal) => {
|
|
28767
|
+
const list = options.store.list;
|
|
28768
|
+
if (!list)
|
|
28769
|
+
throw new MobileUpdateRegistryError("Mobile update storage does not support lifecycle listing");
|
|
28770
|
+
const objects = [];
|
|
28771
|
+
const cursors = new Set;
|
|
28772
|
+
let cursor;
|
|
28773
|
+
do {
|
|
28774
|
+
signal?.throwIfAborted();
|
|
28775
|
+
const page = await list({
|
|
28776
|
+
...cursor ? { cursor } : {},
|
|
28777
|
+
prefix: `${root(appId)}/`
|
|
28778
|
+
});
|
|
28779
|
+
objects.push(...page.objects);
|
|
28780
|
+
if (!page.truncated)
|
|
28781
|
+
break;
|
|
28782
|
+
if (!page.cursor || cursors.has(page.cursor))
|
|
28783
|
+
throw new MobileUpdateRegistryError("Mobile update storage returned an invalid lifecycle cursor");
|
|
28784
|
+
cursors.add(page.cursor);
|
|
28785
|
+
cursor = page.cursor;
|
|
28786
|
+
} while (true);
|
|
28787
|
+
return objects;
|
|
28788
|
+
};
|
|
28789
|
+
const inventory = async (input) => {
|
|
28790
|
+
const { minAgeMs, retainRecent } = retentionValues(input);
|
|
28791
|
+
const objects = await listObjects(input.appId, input.signal);
|
|
28792
|
+
const appRoot = `${root(input.appId)}/`;
|
|
28793
|
+
const releasePrefix = `${appRoot}releases/`;
|
|
28794
|
+
const channelPrefix = `${appRoot}channels/`;
|
|
28795
|
+
const markerPrefix = `${appRoot}gc/`;
|
|
28796
|
+
const objectKeysByRelease = new Map;
|
|
28797
|
+
const objectBytesByRelease = new Map;
|
|
28798
|
+
for (const blobObject of objects) {
|
|
28799
|
+
if (!blobObject.key.startsWith(releasePrefix))
|
|
28800
|
+
continue;
|
|
28801
|
+
const suffix = blobObject.key.slice(releasePrefix.length);
|
|
28802
|
+
const releaseId = suffix.slice(0, suffix.indexOf("/"));
|
|
28803
|
+
if (!RELEASE.test(releaseId))
|
|
28804
|
+
continue;
|
|
28805
|
+
objectKeysByRelease.set(releaseId, [
|
|
28806
|
+
...objectKeysByRelease.get(releaseId) ?? [],
|
|
28807
|
+
blobObject.key
|
|
28808
|
+
]);
|
|
28809
|
+
objectBytesByRelease.set(releaseId, (objectBytesByRelease.get(releaseId) ?? 0) + blobObject.size);
|
|
28810
|
+
}
|
|
28811
|
+
const channels = [];
|
|
28812
|
+
for (const blobObject of objects) {
|
|
28813
|
+
if (!blobObject.key.startsWith(channelPrefix) || !blobObject.key.endsWith(".json"))
|
|
28814
|
+
continue;
|
|
28815
|
+
const bytes = await options.store.get(blobObject.key);
|
|
28816
|
+
if (!bytes)
|
|
28817
|
+
throw new MobileUpdateRegistryError("Mobile update channel disappeared during lifecycle inspection");
|
|
28818
|
+
const channel = parseChannel(decode(bytes));
|
|
28819
|
+
if (channel.appId !== input.appId)
|
|
28820
|
+
throw new MobileUpdateRegistryError("Stored mobile update channel identity changed");
|
|
28821
|
+
channels.push(channel);
|
|
28822
|
+
}
|
|
28823
|
+
const markedAt = new Map;
|
|
28824
|
+
for (const blobObject of objects) {
|
|
28825
|
+
if (!blobObject.key.startsWith(markerPrefix) || !blobObject.key.endsWith(".json"))
|
|
28826
|
+
continue;
|
|
28827
|
+
const releaseId = blobObject.key.slice(markerPrefix.length, -".json".length);
|
|
28828
|
+
if (!RELEASE.test(releaseId))
|
|
28829
|
+
continue;
|
|
28830
|
+
const bytes = await options.store.get(blobObject.key);
|
|
28831
|
+
if (!bytes)
|
|
28832
|
+
continue;
|
|
28833
|
+
const marker = decode(bytes);
|
|
28834
|
+
if (!object3(marker) || marker.format !== 1 || marker.appId !== input.appId || marker.releaseId !== releaseId || !iso(marker.markedAt))
|
|
28835
|
+
throw new MobileUpdateRegistryError("Mobile update collection marker is invalid");
|
|
28836
|
+
markedAt.set(releaseId, marker.markedAt);
|
|
28837
|
+
}
|
|
28838
|
+
const active = new Set(channels.flatMap((channel) => channel.releaseId ? [channel.releaseId] : []));
|
|
28839
|
+
const fallback = new Set(channels.flatMap((channel) => channel.fallbackReleaseId ? [channel.fallbackReleaseId] : []));
|
|
28840
|
+
const manifests = [];
|
|
28841
|
+
for (const releaseId of objectKeysByRelease.keys()) {
|
|
28842
|
+
const release = await readManifest2(input.appId, releaseId);
|
|
28843
|
+
if (release)
|
|
28844
|
+
manifests.push(release.manifest);
|
|
28845
|
+
}
|
|
28846
|
+
const recent = new Set;
|
|
28847
|
+
const manifestsByChannel = new Map;
|
|
28848
|
+
for (const manifest of manifests)
|
|
28849
|
+
manifestsByChannel.set(manifest.channel, [
|
|
28850
|
+
...manifestsByChannel.get(manifest.channel) ?? [],
|
|
28851
|
+
manifest
|
|
28852
|
+
]);
|
|
28853
|
+
for (const releases2 of manifestsByChannel.values())
|
|
28854
|
+
for (const manifest of releases2.toSorted((left, right) => right.createdAt.localeCompare(left.createdAt)).slice(0, retainRecent))
|
|
28855
|
+
recent.add(manifest.releaseId);
|
|
28856
|
+
const now = clock().getTime();
|
|
28857
|
+
const releases = manifests.map((manifest) => {
|
|
28858
|
+
const protectedBy = [];
|
|
28859
|
+
if (active.has(manifest.releaseId))
|
|
28860
|
+
protectedBy.push("active");
|
|
28861
|
+
if (fallback.has(manifest.releaseId))
|
|
28862
|
+
protectedBy.push("fallback");
|
|
28863
|
+
if (recent.has(manifest.releaseId))
|
|
28864
|
+
protectedBy.push("recent");
|
|
28865
|
+
if (now - Date.parse(manifest.createdAt) < minAgeMs)
|
|
28866
|
+
protectedBy.push("age");
|
|
28867
|
+
return {
|
|
28868
|
+
bytes: objectBytesByRelease.get(manifest.releaseId) ?? 0,
|
|
28869
|
+
channel: manifest.channel,
|
|
28870
|
+
createdAt: manifest.createdAt,
|
|
28871
|
+
...markedAt.has(manifest.releaseId) ? { markedAt: markedAt.get(manifest.releaseId) } : {},
|
|
28872
|
+
objectCount: objectKeysByRelease.get(manifest.releaseId)?.length ?? 0,
|
|
28873
|
+
protectedBy,
|
|
28874
|
+
releaseId: manifest.releaseId
|
|
28875
|
+
};
|
|
28876
|
+
}).toSorted((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
28877
|
+
const releaseBytes = releases.reduce((total, release) => total + release.bytes, 0);
|
|
28878
|
+
const totalBytes = objects.reduce((total, object22) => total + object22.size, 0);
|
|
28879
|
+
return {
|
|
28880
|
+
objectKeysByRelease,
|
|
28881
|
+
report: {
|
|
28882
|
+
appId: input.appId,
|
|
28883
|
+
channelCount: channels.length,
|
|
28884
|
+
reclaimableBytes: releases.filter((release) => release.protectedBy.length === 0).reduce((total, release) => total + release.bytes, 0),
|
|
28885
|
+
releaseBytes,
|
|
28886
|
+
releaseCount: releases.length,
|
|
28887
|
+
releases,
|
|
28888
|
+
totalBytes,
|
|
28889
|
+
totalObjectCount: objects.length,
|
|
28890
|
+
untrackedBytes: totalBytes - releaseBytes
|
|
28891
|
+
}
|
|
28892
|
+
};
|
|
28893
|
+
};
|
|
28894
|
+
const pruneUpdates = async (input) => {
|
|
28895
|
+
const initial = await inventory(input);
|
|
28896
|
+
const result = {
|
|
28897
|
+
...initial.report,
|
|
28898
|
+
dryRun: input.apply !== true,
|
|
28899
|
+
marked: [],
|
|
28900
|
+
reclaimedBytes: 0,
|
|
28901
|
+
restored: [],
|
|
28902
|
+
swept: []
|
|
28903
|
+
};
|
|
28904
|
+
if (input.apply !== true)
|
|
28905
|
+
return result;
|
|
28906
|
+
const remove = options.store.delete;
|
|
28907
|
+
if (!remove)
|
|
28908
|
+
throw new MobileUpdateRegistryError("Mobile update storage does not support lifecycle deletion");
|
|
28909
|
+
const gracePeriodMs = input.gracePeriodMs ?? DEFAULT_GRACE_PERIOD_MS;
|
|
28910
|
+
if (!Number.isSafeInteger(gracePeriodMs) || gracePeriodMs < 0)
|
|
28911
|
+
throw new MobileUpdateRegistryError("Mobile update collection grace period is invalid");
|
|
28912
|
+
const now = clock();
|
|
28913
|
+
for (const release of initial.report.releases) {
|
|
28914
|
+
input.signal?.throwIfAborted();
|
|
28915
|
+
const marker = tombstoneKey(input.appId, release.releaseId);
|
|
28916
|
+
if (release.protectedBy.length > 0) {
|
|
28917
|
+
if (release.markedAt) {
|
|
28918
|
+
await remove(marker);
|
|
28919
|
+
result.restored.push(release.releaseId);
|
|
28920
|
+
}
|
|
28921
|
+
continue;
|
|
28922
|
+
}
|
|
28923
|
+
if (!release.markedAt) {
|
|
28924
|
+
const bytes = json({
|
|
28925
|
+
appId: input.appId,
|
|
28926
|
+
format: 1,
|
|
28927
|
+
markedAt: now.toISOString(),
|
|
28928
|
+
releaseId: release.releaseId
|
|
28929
|
+
});
|
|
28930
|
+
await options.store.put(marker, bytes, {
|
|
28931
|
+
cacheControl: "no-cache",
|
|
28932
|
+
contentType: "application/json",
|
|
28933
|
+
maxBytes: bytes.byteLength,
|
|
28934
|
+
metadata: { releaseid: release.releaseId, sha256: digest(bytes) },
|
|
28935
|
+
signal: input.signal
|
|
28936
|
+
});
|
|
28937
|
+
result.marked.push(release.releaseId);
|
|
28938
|
+
}
|
|
28939
|
+
}
|
|
28940
|
+
const current = await inventory(input);
|
|
28941
|
+
for (const release of current.report.releases) {
|
|
28942
|
+
input.signal?.throwIfAborted();
|
|
28943
|
+
if (release.protectedBy.length > 0 || !release.markedAt || now.getTime() - Date.parse(release.markedAt) < gracePeriodMs || result.marked.includes(release.releaseId))
|
|
28944
|
+
continue;
|
|
28945
|
+
const checked = await inventory(input);
|
|
28946
|
+
const candidate = checked.report.releases.find((value) => value.releaseId === release.releaseId);
|
|
28947
|
+
if (!candidate || candidate.protectedBy.length > 0 || !candidate.markedAt)
|
|
28948
|
+
continue;
|
|
28949
|
+
const keys = checked.objectKeysByRelease.get(release.releaseId) ?? [];
|
|
28950
|
+
for (const key of keys.toSorted((left, right) => {
|
|
28951
|
+
const leftManifest = left.endsWith("/update.json");
|
|
28952
|
+
const rightManifest = right.endsWith("/update.json");
|
|
28953
|
+
return Number(leftManifest) - Number(rightManifest);
|
|
28954
|
+
}))
|
|
28955
|
+
await remove(key);
|
|
28956
|
+
await remove(tombstoneKey(input.appId, release.releaseId));
|
|
28957
|
+
result.reclaimedBytes += candidate.bytes;
|
|
28958
|
+
result.swept.push(release.releaseId);
|
|
28959
|
+
}
|
|
28960
|
+
return result;
|
|
28961
|
+
};
|
|
28747
28962
|
return {
|
|
28963
|
+
inspectUpdateStorage: async (input) => (await inventory(input)).report,
|
|
28964
|
+
pruneUpdates,
|
|
28748
28965
|
publishUpdate: async (input) => {
|
|
28749
28966
|
input.signal?.throwIfAborted();
|
|
28750
28967
|
const manifest = parseMobileUpdateManifest(input.manifest);
|
|
28751
28968
|
verifyManifestSignature(manifest, options.publicKeys);
|
|
28969
|
+
await assertNotMarked(manifest.appId, manifest.releaseId);
|
|
28752
28970
|
const localRoot = path.resolve(input.releaseDirectory);
|
|
28753
28971
|
const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile9(path.join(localRoot, "update.json"), "utf8")));
|
|
28754
28972
|
if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
|
|
@@ -28813,6 +29031,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
28813
29031
|
if (!existing)
|
|
28814
29032
|
throw new MobileUpdateRegistryError("Mobile update channel does not exist");
|
|
28815
29033
|
if (input.releaseId) {
|
|
29034
|
+
await assertNotMarked(input.appId, input.releaseId);
|
|
28816
29035
|
const release = await readManifest2(input.appId, input.releaseId);
|
|
28817
29036
|
if (!release || release.manifest.channel !== input.channel)
|
|
28818
29037
|
throw new MobileUpdateRegistryError("Mobile rollback release was not published");
|
|
@@ -29145,6 +29364,9 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
29145
29364
|
var init_mobileUpdate = __esm(() => {
|
|
29146
29365
|
MAX_FILE_BYTES = 32 * 1024 * 1024;
|
|
29147
29366
|
MAX_TOTAL_BYTES = 128 * 1024 * 1024;
|
|
29367
|
+
DAY_MS = 24 * 60 * 60 * 1000;
|
|
29368
|
+
DEFAULT_MIN_AGE_MS = 30 * DAY_MS;
|
|
29369
|
+
DEFAULT_GRACE_PERIOD_MS = 7 * DAY_MS;
|
|
29148
29370
|
HASH = /^[a-f0-9]{64}$/;
|
|
29149
29371
|
RELEASE = /^amu_[a-f0-9]{64}$/;
|
|
29150
29372
|
APP_ID = /^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)+$/;
|
|
@@ -36969,5 +37191,5 @@ export {
|
|
|
36969
37191
|
devBuild
|
|
36970
37192
|
};
|
|
36971
37193
|
|
|
36972
|
-
//# debugId=
|
|
37194
|
+
//# debugId=4B8A1B549AE0AC2164756E2164756E21
|
|
36973
37195
|
//# sourceMappingURL=build.js.map
|