@dejadex/web 0.0.0-stage → 0.1.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.
Files changed (113) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +222 -2
  3. package/dist/errors.d.ts +8 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/errors.js +9 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/geometry/homography.d.ts +75 -0
  8. package/dist/geometry/homography.d.ts.map +1 -0
  9. package/dist/geometry/homography.js +146 -0
  10. package/dist/geometry/homography.js.map +1 -0
  11. package/dist/identify/assets.d.ts +39 -0
  12. package/dist/identify/assets.d.ts.map +1 -0
  13. package/dist/identify/assets.js +167 -0
  14. package/dist/identify/assets.js.map +1 -0
  15. package/dist/identify/decode.d.ts +6 -0
  16. package/dist/identify/decode.d.ts.map +1 -0
  17. package/dist/identify/decode.js +53 -0
  18. package/dist/identify/decode.js.map +1 -0
  19. package/dist/identify/engine.d.ts +32 -0
  20. package/dist/identify/engine.d.ts.map +1 -0
  21. package/dist/identify/engine.js +127 -0
  22. package/dist/identify/engine.js.map +1 -0
  23. package/dist/identify/identifier.d.ts +91 -0
  24. package/dist/identify/identifier.d.ts.map +1 -0
  25. package/dist/identify/identifier.js +332 -0
  26. package/dist/identify/identifier.js.map +1 -0
  27. package/dist/identify/manifest.d.ts +60 -0
  28. package/dist/identify/manifest.d.ts.map +1 -0
  29. package/dist/identify/manifest.js +211 -0
  30. package/dist/identify/manifest.js.map +1 -0
  31. package/dist/identify/preprocess.d.ts +52 -0
  32. package/dist/identify/preprocess.d.ts.map +1 -0
  33. package/dist/identify/preprocess.js +195 -0
  34. package/dist/identify/preprocess.js.map +1 -0
  35. package/dist/identify/router.d.ts +60 -0
  36. package/dist/identify/router.d.ts.map +1 -0
  37. package/dist/identify/router.js +83 -0
  38. package/dist/identify/router.js.map +1 -0
  39. package/dist/identify/runtime.d.ts +69 -0
  40. package/dist/identify/runtime.d.ts.map +1 -0
  41. package/dist/identify/runtime.js +140 -0
  42. package/dist/identify/runtime.js.map +1 -0
  43. package/dist/identify/search.d.ts +35 -0
  44. package/dist/identify/search.d.ts.map +1 -0
  45. package/dist/identify/search.js +99 -0
  46. package/dist/identify/search.js.map +1 -0
  47. package/dist/identify/server.d.ts +60 -0
  48. package/dist/identify/server.d.ts.map +1 -0
  49. package/dist/identify/server.js +149 -0
  50. package/dist/identify/server.js.map +1 -0
  51. package/dist/identify/shard.d.ts +31 -0
  52. package/dist/identify/shard.d.ts.map +1 -0
  53. package/dist/identify/shard.js +146 -0
  54. package/dist/identify/shard.js.map +1 -0
  55. package/dist/identify/types.d.ts +107 -0
  56. package/dist/identify/types.d.ts.map +1 -0
  57. package/dist/identify/types.js +7 -0
  58. package/dist/identify/types.js.map +1 -0
  59. package/dist/identify/worker.d.ts +2 -0
  60. package/dist/identify/worker.d.ts.map +1 -0
  61. package/dist/identify/worker.js +13 -0
  62. package/dist/identify/worker.js.map +1 -0
  63. package/dist/identify/workerProtocol.d.ts +54 -0
  64. package/dist/identify/workerProtocol.d.ts.map +1 -0
  65. package/dist/identify/workerProtocol.js +113 -0
  66. package/dist/identify/workerProtocol.js.map +1 -0
  67. package/dist/index.d.ts +20 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +16 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lease/verify.d.ts +69 -0
  72. package/dist/lease/verify.d.ts.map +1 -0
  73. package/dist/lease/verify.js +235 -0
  74. package/dist/lease/verify.js.map +1 -0
  75. package/dist/scanner.d.ts +10 -0
  76. package/dist/scanner.d.ts.map +1 -0
  77. package/dist/scanner.js +58 -0
  78. package/dist/scanner.js.map +1 -0
  79. package/dist/types.d.ts +180 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +2 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/usage/meter.d.ts +83 -0
  84. package/dist/usage/meter.d.ts.map +1 -0
  85. package/dist/usage/meter.js +111 -0
  86. package/dist/usage/meter.js.map +1 -0
  87. package/dist/usage/store.d.ts +40 -0
  88. package/dist/usage/store.d.ts.map +1 -0
  89. package/dist/usage/store.js +248 -0
  90. package/dist/usage/store.js.map +1 -0
  91. package/package.json +64 -4
  92. package/src/errors.ts +24 -0
  93. package/src/geometry/homography.ts +178 -0
  94. package/src/identify/assets.ts +189 -0
  95. package/src/identify/decode.ts +54 -0
  96. package/src/identify/engine.ts +167 -0
  97. package/src/identify/identifier.ts +431 -0
  98. package/src/identify/manifest.ts +240 -0
  99. package/src/identify/preprocess.ts +227 -0
  100. package/src/identify/router.ts +115 -0
  101. package/src/identify/runtime.ts +197 -0
  102. package/src/identify/search.ts +115 -0
  103. package/src/identify/server.ts +167 -0
  104. package/src/identify/shard.ts +154 -0
  105. package/src/identify/types.ts +122 -0
  106. package/src/identify/worker.ts +13 -0
  107. package/src/identify/workerProtocol.ts +136 -0
  108. package/src/index.ts +71 -0
  109. package/src/lease/verify.ts +252 -0
  110. package/src/scanner.ts +56 -0
  111. package/src/types.ts +196 -0
  112. package/src/usage/meter.ts +165 -0
  113. package/src/usage/store.ts +282 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * `createIdentifier`: crops in, catalogue ids out, on the device or through
3
+ * `POST /v1/identify`, under a verified lease, with usage counted on the
4
+ * device. See `types.ts` beside this file for the answer's shape and README.md
5
+ * for host wiring.
6
+ *
7
+ * Per call:
8
+ * 1. The lease must be set, unexpired, and have allowance left.
9
+ * 2. `router.ts` picks the device or the server.
10
+ * 3. A server attempt is bounded by the fallback deadline; on any failure
11
+ * (or a late answer) the same crops are identified on the device.
12
+ * 4. The answer is metered (`usage/meter.ts`) before it is returned.
13
+ *
14
+ * `identify` never throws: every failure is an outcome.
15
+ */
16
+ import { ScannerError } from '../errors.js';
17
+ import { verifyLease } from '../lease/verify.js';
18
+ import { UsageMeter } from '../usage/meter.js';
19
+ import { defaultUsageStore, randomId } from '../usage/store.js';
20
+ import { defaultEngineDeps, loadDeviceEngine } from './engine.js';
21
+ import { DEFAULT_SERVER_TIMEOUT_MS, DEFAULT_SLOW_DEVICE_BUDGET_MS, ServerHealth, chooseRoute, serverDeadline, } from './router.js';
22
+ import { postIdentify } from './server.js';
23
+ import { DEFAULT_TOP, MAX_CROPS_PER_REQUEST, MAX_TOP, } from './types.js';
24
+ import { connectWorkerEngine } from './workerProtocol.js';
25
+ const DOMAIN_CODE = /^[a-z][a-z0-9]*_[a-z]{2}$/;
26
+ const SESSION = /^[\x20-\x7e]{1,128}$/;
27
+ const errorText = (err) => (err instanceof Error ? err.message || err.name : String(err));
28
+ const codeText = (err) => (err instanceof ScannerError ? `${err.code}: ${err.message}` : errorText(err));
29
+ function validate(options) {
30
+ const fail = (m) => {
31
+ throw new ScannerError('INVALID_OPTIONS', m);
32
+ };
33
+ if (typeof options !== 'object' || options === null)
34
+ fail('options are required');
35
+ if (typeof options.domain !== 'string' || !DOMAIN_CODE.test(options.domain))
36
+ fail(`not a domain code: ${String(options.domain)}`);
37
+ if (!Array.isArray(options.leasePublicKeys) || options.leasePublicKeys.length === 0)
38
+ fail('leasePublicKeys must list at least one key');
39
+ const modes = ['auto', 'local', 'server'];
40
+ if (options.identification !== undefined && !modes.includes(options.identification))
41
+ fail(`unknown identification mode: ${String(options.identification)}`);
42
+ if (options.serverUrl !== undefined && options.serverUrl !== null) {
43
+ try {
44
+ const u = new URL(options.serverUrl);
45
+ if (u.protocol !== 'https:' && u.protocol !== 'http:')
46
+ fail('serverUrl must be http(s)');
47
+ }
48
+ catch {
49
+ fail(`serverUrl is not a URL: ${options.serverUrl}`);
50
+ }
51
+ }
52
+ for (const [name, v] of [['slowDeviceBudgetMs', options.slowDeviceBudgetMs], ['serverTimeoutMs', options.serverTimeoutMs]]) {
53
+ if (v !== undefined && (!Number.isFinite(v) || v <= 0))
54
+ fail(`${name} must be a positive number`);
55
+ }
56
+ }
57
+ function defaultOrigin() {
58
+ const loc = globalThis.location;
59
+ return typeof loc?.origin === 'string' && loc.origin !== 'null' ? loc.origin : null;
60
+ }
61
+ function defaultEngineLoader(choice) {
62
+ const useWorker = choice === undefined ? typeof Worker !== 'undefined' : choice !== 'inline';
63
+ if (!useWorker)
64
+ return async (config) => loadDeviceEngine(config, await defaultEngineDeps());
65
+ const make = typeof choice === 'function' ? choice : () => new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
66
+ return async (config) => {
67
+ const worker = make();
68
+ try {
69
+ return await connectWorkerEngine(worker, config);
70
+ }
71
+ catch (err) {
72
+ worker.terminate();
73
+ throw err;
74
+ }
75
+ };
76
+ }
77
+ export function createIdentifier(options) {
78
+ validate(options);
79
+ const mode = options.identification ?? 'auto';
80
+ const endpoint = options.serverUrl ? `${options.serverUrl.trim().replace(/\/+$/, '')}/v1/identify` : null;
81
+ const budget = options.slowDeviceBudgetMs ?? DEFAULT_SLOW_DEVICE_BUDGET_MS;
82
+ const serverTimeoutMs = options.serverTimeoutMs ?? DEFAULT_SERVER_TIMEOUT_MS;
83
+ const now = options.now ?? (() => Date.now());
84
+ const online = options.online ?? (() => globalThis.navigator?.onLine !== false);
85
+ const origin = options.origin === undefined ? defaultOrigin() : options.origin;
86
+ const doFetch = options.fetch ?? ((url, init) => fetch(url, init));
87
+ const loadEngine = options.loadEngine ?? defaultEngineLoader(options.engine);
88
+ const health = new ServerHealth();
89
+ // A store the identifier opened is closed by `destroy()`; the host's is not.
90
+ const ownStore = options.usageStore === undefined;
91
+ const storeReady = options.usageStore ? Promise.resolve(options.usageStore) : defaultUsageStore();
92
+ const meterReady = storeReady.then((store) => new UsageMeter({ store, now }));
93
+ let lease = null;
94
+ /** The constructor's lease while it is being verified; `identify` waits for it. */
95
+ let initialLease = null;
96
+ let manifestUrl = null;
97
+ let session = randomId();
98
+ let destroyed = false;
99
+ // The device engine for the current lease, and its load.
100
+ let engine = null;
101
+ let engineKey = null;
102
+ let loading = null;
103
+ let deviceError = null;
104
+ const keyOf = (claims, url) => `${url}\n${claims.modelVersion}\n${claims.indexVersion}`;
105
+ function startLoad() {
106
+ if (destroyed)
107
+ return Promise.reject(new ScannerError('INVALID_OPTIONS', 'the identifier was destroyed'));
108
+ if (!lease || !manifestUrl)
109
+ return Promise.reject(new ScannerError('LEASE_INVALID', 'no lease is set'));
110
+ const key = keyOf(lease.claims, manifestUrl);
111
+ if (engine && engineKey === key)
112
+ return Promise.resolve(engine);
113
+ if (loading)
114
+ return loading;
115
+ const config = {
116
+ manifestUrl,
117
+ expect: { modelVersion: lease.claims.modelVersion, indexVersion: lease.claims.indexVersion, shard: options.domain },
118
+ runtime: options.runtime ?? {},
119
+ };
120
+ deviceError = null;
121
+ const attempt = loadEngine(config).then(async (loaded) => {
122
+ const previous = engine;
123
+ engine = loaded;
124
+ engineKey = key;
125
+ loading = null;
126
+ if (previous && previous !== loaded)
127
+ await previous.release().catch(() => undefined);
128
+ if (destroyed)
129
+ await loaded.release().catch(() => undefined);
130
+ return loaded;
131
+ }, (err) => {
132
+ loading = null;
133
+ deviceError = codeText(err);
134
+ throw err;
135
+ });
136
+ loading = attempt;
137
+ return attempt;
138
+ }
139
+ const preload = () => {
140
+ if (options.preload === false)
141
+ return;
142
+ startLoad().catch((err) => options.onError?.(err instanceof Error ? err : new Error(String(err))));
143
+ };
144
+ function deviceState() {
145
+ const e = engine;
146
+ if (e === null || lease === null || manifestUrl === null || engineKey !== keyOf(lease.claims, manifestUrl)) {
147
+ return { ready: false, backend: null, perCropMs: Number.NaN };
148
+ }
149
+ return { ready: true, backend: e.info.backend, perCropMs: e.info.perCropMs };
150
+ }
151
+ async function setLease(grant) {
152
+ if (destroyed)
153
+ throw new ScannerError('INVALID_OPTIONS', 'the identifier was destroyed');
154
+ if (typeof grant?.token !== 'string' || typeof grant.manifestUrl !== 'string') {
155
+ throw new ScannerError('INVALID_OPTIONS', 'a lease grant is { token, manifestUrl }');
156
+ }
157
+ const verified = await verifyLease(grant.token, {
158
+ publicKeys: options.leasePublicKeys,
159
+ origin,
160
+ domains: [options.domain],
161
+ now: Math.floor(now() / 1000),
162
+ ...(options.verify ? { verify: options.verify } : {}),
163
+ });
164
+ let url;
165
+ try {
166
+ url = new URL(grant.manifestUrl, defaultOrigin() ?? undefined).href;
167
+ }
168
+ catch {
169
+ throw new ScannerError('INVALID_OPTIONS', `manifestUrl is not a URL: ${grant.manifestUrl}`);
170
+ }
171
+ lease = verified;
172
+ manifestUrl = url;
173
+ // Every lease reports at least once (the renewal gate), used or not.
174
+ await (await meterReady).touch(verified.claims.jti, session);
175
+ preload();
176
+ return verified;
177
+ }
178
+ const aborted = () => ({ ok: false, reason: 'unavailable', detail: 'aborted' });
179
+ /** Resolves with the device's answer, or `null` when the caller aborted first. */
180
+ async function onDevice(crops, top, signal) {
181
+ const work = startLoad().then((e) => e.identify(crops, top));
182
+ if (!signal)
183
+ return work;
184
+ if (signal.aborted)
185
+ return null;
186
+ return new Promise((resolve, reject) => {
187
+ const onAbort = () => resolve(null);
188
+ signal.addEventListener('abort', onAbort, { once: true });
189
+ work.then((r) => {
190
+ signal.removeEventListener('abort', onAbort);
191
+ resolve(r);
192
+ }, (e) => {
193
+ signal.removeEventListener('abort', onAbort);
194
+ reject(e);
195
+ });
196
+ });
197
+ }
198
+ async function identify(crops, call = {}) {
199
+ try {
200
+ if (destroyed)
201
+ return { ok: false, reason: 'unavailable', detail: 'INVALID_OPTIONS: the identifier was destroyed' };
202
+ if (!Array.isArray(crops) || crops.length > MAX_CROPS_PER_REQUEST) {
203
+ return { ok: false, reason: 'rejected', detail: `INVALID_OPTIONS: at most ${MAX_CROPS_PER_REQUEST} crops per call` };
204
+ }
205
+ const top = call.top ?? DEFAULT_TOP;
206
+ if (!Number.isInteger(top) || top < 1 || top > MAX_TOP)
207
+ return { ok: false, reason: 'rejected', detail: `INVALID_OPTIONS: top must be 1..${MAX_TOP}` };
208
+ const sessionId = call.session ?? session;
209
+ if (!SESSION.test(sessionId))
210
+ return { ok: false, reason: 'rejected', detail: 'INVALID_OPTIONS: session must be 1..128 printable characters' };
211
+ if (call.signal?.aborted)
212
+ return aborted();
213
+ if (initialLease)
214
+ await initialLease;
215
+ const current = lease;
216
+ if (!current)
217
+ return { ok: false, reason: 'rejected', detail: 'LEASE_INVALID: no lease is set' };
218
+ if (Math.floor(now() / 1000) >= current.claims.exp)
219
+ return { ok: false, reason: 'rejected', detail: 'LEASE_EXPIRED: renew the lease' };
220
+ const meter = await meterReady;
221
+ if (meter.exhausted(current.claims))
222
+ return { ok: false, reason: 'rejected', detail: 'ALLOWANCE_EXHAUSTED: renew the lease' };
223
+ if (crops.length === 0)
224
+ return { ok: true, modelVersion: current.claims.modelVersion, results: [], source: 'device' };
225
+ const device = deviceState();
226
+ const serverBlocked = endpoint === null ? 'no serverUrl' : health.blocked(current.claims.jti, now(), online());
227
+ const route = chooseRoute({ mode, device, serverBlocked, slowDeviceBudgetMs: budget });
228
+ let results = null;
229
+ let source = 'device';
230
+ let serverFailure = null;
231
+ if (route === 'server' && endpoint !== null) {
232
+ const answer = await postIdentify({
233
+ endpoint,
234
+ crops,
235
+ token: current.token,
236
+ top,
237
+ session: sessionId,
238
+ ...(call.purpose ? { purpose: call.purpose } : {}),
239
+ timeoutMs: serverDeadline(device, crops.length, serverTimeoutMs),
240
+ ...(call.signal ? { signal: call.signal } : {}),
241
+ fetch: doFetch,
242
+ });
243
+ const checked = answer.ok && answer.modelVersion !== current.claims.modelVersion
244
+ ? { ok: false, kind: 'malformed', detail: `answer is model ${answer.modelVersion}, the lease is ${current.claims.modelVersion}` }
245
+ : answer;
246
+ health.record(checked, current.claims.jti, now());
247
+ if (checked.ok) {
248
+ results = checked.results;
249
+ source = 'server';
250
+ }
251
+ else if (checked.kind === 'aborted') {
252
+ return aborted();
253
+ }
254
+ else {
255
+ serverFailure = checked;
256
+ }
257
+ }
258
+ if (results === null) {
259
+ try {
260
+ results = await onDevice(crops, top, call.signal);
261
+ }
262
+ catch (err) {
263
+ const why = codeText(err);
264
+ if (serverFailure?.ok === false && serverFailure.kind === 'timeout')
265
+ return { ok: false, reason: 'timeout', detail: `${serverFailure.detail}; device: ${why}` };
266
+ const reason = err instanceof ScannerError && err.code === 'INVALID_OPTIONS' ? 'rejected' : 'unavailable';
267
+ return { ok: false, reason, detail: serverFailure?.ok === false ? `${serverFailure.detail}; device: ${why}` : why };
268
+ }
269
+ if (results === null)
270
+ return aborted();
271
+ }
272
+ await meter.record({ lease: current.claims, session: sessionId, purpose: call.purpose, results });
273
+ return { ok: true, modelVersion: current.claims.modelVersion, results, source };
274
+ }
275
+ catch (err) {
276
+ return { ok: false, reason: 'unavailable', detail: codeText(err) };
277
+ }
278
+ }
279
+ const identifier = {
280
+ identify,
281
+ setLease,
282
+ get session() {
283
+ return session;
284
+ },
285
+ newSession() {
286
+ session = randomId();
287
+ return session;
288
+ },
289
+ async prepare() {
290
+ return (await startLoad()).info;
291
+ },
292
+ status() {
293
+ const claims = lease?.claims ?? null;
294
+ const ready = deviceState().ready;
295
+ return {
296
+ lease: claims,
297
+ device: ready ? 'ready' : loading ? 'loading' : deviceError ? 'failed' : 'idle',
298
+ deviceInfo: ready && engine ? engine.info : null,
299
+ deviceError,
300
+ serverPaused: endpoint === null ? 'no serverUrl' : health.blocked(claims?.jti ?? null, now(), online()),
301
+ };
302
+ },
303
+ async drainUsage(deliver) {
304
+ return (await meterReady).drain(deliver);
305
+ },
306
+ async pendingUsage() {
307
+ return (await meterReady).pending();
308
+ },
309
+ async leaseRequest(previousLeaseId) {
310
+ return (await meterReady).leaseRequest(previousLeaseId === undefined ? (lease?.claims.jti ?? null) : previousLeaseId);
311
+ },
312
+ async destroy() {
313
+ destroyed = true;
314
+ const e = engine;
315
+ engine = null;
316
+ engineKey = null;
317
+ await e?.release().catch(() => undefined);
318
+ if (ownStore)
319
+ (await storeReady).close?.();
320
+ },
321
+ };
322
+ if (options.lease) {
323
+ initialLease = setLease(options.lease).then(() => {
324
+ initialLease = null;
325
+ }, (err) => {
326
+ initialLease = null;
327
+ options.onError?.(err instanceof Error ? err : new Error(String(err)));
328
+ });
329
+ }
330
+ return identifier;
331
+ }
332
+ //# sourceMappingURL=identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../src/identify/identifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { Orientation } from './preprocess.js';
2
+ export interface ManifestFile {
3
+ /** Absolute, resolved against the manifest's URL; carries its signature when under the signed prefix. */
4
+ readonly url: string;
5
+ readonly sha256: string;
6
+ readonly size: number;
7
+ }
8
+ export type ModelPrecision = 'fp16' | 'fp32';
9
+ export interface ManifestModel extends ManifestFile {
10
+ readonly precision: ModelPrecision;
11
+ readonly licence: string;
12
+ }
13
+ export interface Manifest {
14
+ readonly modelVersion: string;
15
+ readonly indexVersion: string;
16
+ readonly shard: string;
17
+ readonly rows: number;
18
+ readonly dims: number;
19
+ readonly notACardBelow: number;
20
+ readonly confidentMargin: number;
21
+ readonly preprocessing: {
22
+ readonly width: number;
23
+ readonly height: number;
24
+ readonly mean: readonly [number, number, number];
25
+ readonly std: readonly [number, number, number];
26
+ readonly orientations: readonly Orientation[];
27
+ };
28
+ readonly embedding: {
29
+ readonly input: string;
30
+ readonly output: string;
31
+ readonly token: number;
32
+ };
33
+ readonly index: ManifestFile;
34
+ readonly ids: ManifestFile;
35
+ readonly models: readonly ManifestModel[];
36
+ }
37
+ /** Licences a shipped model may carry (closed commercial distribution). */
38
+ export declare const LICENCE_ALLOWLIST: readonly string[];
39
+ export interface SignedPrefix {
40
+ /** The decoded `URLPrefix`: scheme, host and path. */
41
+ readonly prefix: string;
42
+ /** `URLPrefix=…&Expires=…&KeyName=…&Signature=…`, the values exactly as received. */
43
+ readonly query: string;
44
+ }
45
+ /**
46
+ * The prefix signature a manifest URL carries, or null when it carries none
47
+ * (or a malformed one). The raw query is read, never `URLSearchParams`, so
48
+ * the values, `=` padding included, travel byte for byte.
49
+ */
50
+ export declare function signedPrefixOf(manifestUrl: string): SignedPrefix | null;
51
+ /**
52
+ * `url` with the signing query added when it lies under the signed prefix and
53
+ * on the prefix's origin; anything else is returned unchanged, so another
54
+ * host or another pair's directory never receives this signature. A URL that
55
+ * already carries signing parameters (an absolute signed URL) keeps its own.
56
+ */
57
+ export declare function carrySignature(url: string, signed: SignedPrefix | null): string;
58
+ /** Validates a parsed manifest document. `manifestUrl` is what relative paths resolve against. */
59
+ export declare function parseManifest(doc: unknown, manifestUrl: string): Manifest;
60
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/identify/manifest.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,yGAAyG;IACzG,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAA;AAE5C,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,aAAa,EAAE;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAChD,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAC/C,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAA;KAC9C,CAAA;IACD,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/F,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA0D,CAAA;AAqBzG,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAyBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAwBvE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,CAO/E;AAgBD,kGAAkG;AAClG,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,QAAQ,CAmEzE"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * The model-and-index manifest of one shard, as `ml/src/dejadex_ml/shard_export.py`
3
+ * writes it (`manifest_<domain>.json`). It names every file the device
4
+ * downloads with its SHA-256 and size, and carries the values the SDK decides
5
+ * with, so none of them is hard-coded here:
6
+ *
7
+ * { format: 1, modelVersion, indexVersion, shard, rows, dims, dtype: "fp16",
8
+ * notACardBelow, confidentMargin, checksum: "sha256:<index>",
9
+ * preprocessing: { width, height, resize: "pil-bilinear", mean, std, orientations },
10
+ * embedding: { input, output, token },
11
+ * files: { index: File, ids: File, models: [ File & { precision, licence } ] } }
12
+ *
13
+ * File = { path, sha256, size }; `path` resolves against the manifest's URL,
14
+ * so a manifest may list relative paths or absolute (signed) URLs.
15
+ *
16
+ * The lease's manifest URL carries a Cloud CDN prefix signature over its
17
+ * pair's directory (`URLPrefix`, `Expires`, `KeyName`, `Signature`). Resolving
18
+ * a relative path drops the query, so the signature is carried onto each file
19
+ * URL that falls under the signed prefix, on the same origin, and onto no
20
+ * other: a file elsewhere never sees this lease's signature.
21
+ */
22
+ import { ScannerError } from '../errors.js';
23
+ /** Licences a shipped model may carry (closed commercial distribution). */
24
+ export const LICENCE_ALLOWLIST = ['Apache-2.0', 'MIT', 'BSD-2-Clause', 'BSD-3-Clause'];
25
+ const SHA256 = /^[0-9a-f]{64}$/;
26
+ const bad = (why) => new ScannerError('MODEL_INTEGRITY', `manifest: ${why}`);
27
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
28
+ const nonEmpty = (v) => typeof v === 'string' && v.length > 0;
29
+ const posInt = (v) => Number.isSafeInteger(v) && v > 0;
30
+ const cosine = (v) => typeof v === 'number' && Number.isFinite(v) && v >= -1 && v <= 1;
31
+ function triple(v, name) {
32
+ if (!Array.isArray(v) || v.length !== 3 || !v.every((x) => typeof x === 'number' && Number.isFinite(x))) {
33
+ throw bad(`${name} must be three numbers`);
34
+ }
35
+ return [v[0], v[1], v[2]];
36
+ }
37
+ /** The four signing parameters, in Cloud CDN's order. */
38
+ const SIGNING_PARAMS = ['URLPrefix', 'Expires', 'KeyName', 'Signature'];
39
+ /** base64url (padded or not) to text; null when it is not base64url of UTF-8. */
40
+ function base64urlText(value) {
41
+ if (!/^[A-Za-z0-9_-]+={0,2}$/.test(value))
42
+ return null;
43
+ try {
44
+ const b64 = value.replace(/=+$/, '').replace(/-/g, '+').replace(/_/g, '/');
45
+ const bin = atob(b64 + '='.repeat((4 - (b64.length % 4)) % 4));
46
+ return new TextDecoder('utf-8', { fatal: true }).decode(Uint8Array.from(bin, (c) => c.charCodeAt(0)));
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /** The raw values of the signing parameters in a query, undecoded. */
53
+ function signingValues(search) {
54
+ const found = new Map();
55
+ for (const part of search.replace(/^\?/, '').split('&')) {
56
+ const eq = part.indexOf('=');
57
+ const name = eq < 0 ? part : part.slice(0, eq);
58
+ if (SIGNING_PARAMS.includes(name))
59
+ found.set(name, [...(found.get(name) ?? []), eq < 0 ? '' : part.slice(eq + 1)]);
60
+ }
61
+ return found;
62
+ }
63
+ /**
64
+ * The prefix signature a manifest URL carries, or null when it carries none
65
+ * (or a malformed one). The raw query is read, never `URLSearchParams`, so
66
+ * the values, `=` padding included, travel byte for byte.
67
+ */
68
+ export function signedPrefixOf(manifestUrl) {
69
+ let url;
70
+ try {
71
+ url = new URL(manifestUrl);
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ const found = signingValues(url.search);
77
+ const values = [];
78
+ for (const p of SIGNING_PARAMS) {
79
+ const v = found.get(p);
80
+ if (v === undefined || v.length !== 1 || v[0] === '')
81
+ return null;
82
+ values.push(v[0]);
83
+ }
84
+ const prefix = base64urlText(values[0]);
85
+ if (prefix === null)
86
+ return null;
87
+ let prefixUrl;
88
+ try {
89
+ prefixUrl = new URL(prefix);
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ if (prefixUrl.protocol !== 'https:' && prefixUrl.protocol !== 'http:')
95
+ return null;
96
+ return { prefix, query: SIGNING_PARAMS.map((p, i) => `${p}=${values[i]}`).join('&') };
97
+ }
98
+ /**
99
+ * `url` with the signing query added when it lies under the signed prefix and
100
+ * on the prefix's origin; anything else is returned unchanged, so another
101
+ * host or another pair's directory never receives this signature. A URL that
102
+ * already carries signing parameters (an absolute signed URL) keeps its own.
103
+ */
104
+ export function carrySignature(url, signed) {
105
+ if (signed === null)
106
+ return url;
107
+ const u = new URL(url);
108
+ if (u.origin !== new URL(signed.prefix).origin)
109
+ return url;
110
+ if (!`${u.origin}${u.pathname}`.startsWith(signed.prefix))
111
+ return url;
112
+ if (signingValues(u.search).size > 0)
113
+ return url;
114
+ return `${u.origin}${u.pathname}${u.search === '' ? '?' : `${u.search}&`}${signed.query}${u.hash}`;
115
+ }
116
+ function file(v, name, base, signed) {
117
+ if (!isRecord(v))
118
+ throw bad(`files.${name} is missing`);
119
+ if (!nonEmpty(v.path))
120
+ throw bad(`files.${name}.path is missing`);
121
+ if (typeof v.sha256 !== 'string' || !SHA256.test(v.sha256))
122
+ throw bad(`files.${name}.sha256 is not a SHA-256 hex digest`);
123
+ if (!posInt(v.size))
124
+ throw bad(`files.${name}.size is not a positive integer`);
125
+ let url;
126
+ try {
127
+ url = new URL(v.path, base).href;
128
+ }
129
+ catch {
130
+ throw bad(`files.${name}.path does not resolve against ${base}`);
131
+ }
132
+ return { url: carrySignature(url, signed), sha256: v.sha256, size: v.size };
133
+ }
134
+ /** Validates a parsed manifest document. `manifestUrl` is what relative paths resolve against. */
135
+ export function parseManifest(doc, manifestUrl) {
136
+ if (!isRecord(doc))
137
+ throw bad('not a JSON object');
138
+ if (doc.format !== 1)
139
+ throw bad(`format ${String(doc.format)} is not supported`);
140
+ const { modelVersion, indexVersion, shard, rows, dims, dtype, notACardBelow, confidentMargin, checksum } = doc;
141
+ if (!nonEmpty(modelVersion) || !nonEmpty(indexVersion) || !nonEmpty(shard))
142
+ throw bad('modelVersion, indexVersion and shard are required');
143
+ if (!posInt(rows) || !posInt(dims))
144
+ throw bad('rows and dims must be positive integers');
145
+ if (dtype !== 'fp16')
146
+ throw bad(`dtype ${String(dtype)} is not supported`);
147
+ if (!cosine(notACardBelow) || !cosine(confidentMargin))
148
+ throw bad('notACardBelow and confidentMargin must be cosines');
149
+ const p = doc.preprocessing;
150
+ if (!isRecord(p))
151
+ throw bad('preprocessing is missing');
152
+ if (p.resize !== 'pil-bilinear')
153
+ throw bad(`resize ${String(p.resize)} is not supported`);
154
+ if (!posInt(p.width) || !posInt(p.height))
155
+ throw bad('preprocessing width and height must be positive integers');
156
+ const orientations = p.orientations;
157
+ if (!Array.isArray(orientations) ||
158
+ orientations.length === 0 ||
159
+ !orientations.every((o) => o === 0 || o === 180) ||
160
+ new Set(orientations).size !== orientations.length) {
161
+ throw bad('orientations must list 0 and/or 180');
162
+ }
163
+ const e = doc.embedding;
164
+ if (!isRecord(e) || !nonEmpty(e.input) || !nonEmpty(e.output) || !Number.isSafeInteger(e.token) || e.token < 0) {
165
+ throw bad('embedding must name input, output and token');
166
+ }
167
+ const files = doc.files;
168
+ if (!isRecord(files))
169
+ throw bad('files is missing');
170
+ const signed = signedPrefixOf(manifestUrl);
171
+ const index = file(files.index, 'index', manifestUrl, signed);
172
+ if (checksum !== `sha256:${index.sha256}`)
173
+ throw bad('checksum does not match files.index.sha256');
174
+ const ids = file(files.ids, 'ids', manifestUrl, signed);
175
+ if (!Array.isArray(files.models) || files.models.length === 0)
176
+ throw bad('files.models lists no model');
177
+ const models = files.models.map((m, i) => {
178
+ if (!isRecord(m))
179
+ throw bad(`files.models[${i}] is not an object`);
180
+ if (m.precision !== 'fp16' && m.precision !== 'fp32') {
181
+ throw bad(`files.models[${i}].precision ${String(m.precision)} is not shipped (fp16 or fp32)`);
182
+ }
183
+ if (typeof m.licence !== 'string' || !LICENCE_ALLOWLIST.includes(m.licence)) {
184
+ throw bad(`files.models[${i}].licence ${String(m.licence)} is outside the allowlist`);
185
+ }
186
+ return { ...file(m, `models[${i}]`, manifestUrl, signed), precision: m.precision, licence: m.licence };
187
+ });
188
+ if (new Set(models.map((m) => m.precision)).size !== models.length)
189
+ throw bad('one model file per precision');
190
+ return {
191
+ modelVersion,
192
+ indexVersion,
193
+ shard,
194
+ rows,
195
+ dims,
196
+ notACardBelow,
197
+ confidentMargin,
198
+ preprocessing: {
199
+ width: p.width,
200
+ height: p.height,
201
+ mean: triple(p.mean, 'preprocessing.mean'),
202
+ std: triple(p.std, 'preprocessing.std'),
203
+ orientations: orientations,
204
+ },
205
+ embedding: { input: e.input, output: e.output, token: e.token },
206
+ index,
207
+ ids,
208
+ models,
209
+ };
210
+ }
211
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/identify/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAsC3C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAsB,CAAC,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,CAAC,CAAA;AAEzG,MAAM,MAAM,GAAG,gBAAgB,CAAA;AAE/B,MAAM,GAAG,GAAG,CAAC,GAAW,EAAgB,EAAE,CAAC,IAAI,YAAY,CAAC,iBAAiB,EAAE,aAAa,GAAG,EAAE,CAAC,CAAA;AAElG,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AACvH,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;AACnF,MAAM,MAAM,GAAG,CAAC,CAAU,EAAe,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAK,CAAY,GAAG,CAAC,CAAA;AACxF,MAAM,MAAM,GAAG,CAAC,CAAU,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAE5G,SAAS,MAAM,CAAC,CAAU,EAAE,IAAY;IACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,MAAM,GAAG,CAAC,GAAG,IAAI,wBAAwB,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAU,CAAA;AACpC,CAAC;AAED,yDAAyD;AACzD,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAU,CAAA;AAShF,iFAAiF;AACjF,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC9D,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC5B,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9C,IAAK,cAAoC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3I,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,IAAI,GAAQ,CAAA;IACZ,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACvC,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACtB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;YAAE,OAAO,IAAI,CAAA;QACjE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAW,CAAC,CAAA;IAC7B,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAW,CAAC,CAAA;IACjD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,SAAc,CAAA;IAClB,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAA;IAClF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAW,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AACjG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,MAA2B;IACrE,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,GAAG,CAAA;IAC/B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACtB,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM;QAAE,OAAO,GAAG,CAAA;IAC1D,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,GAAG,CAAA;IACrE,IAAI,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,CAAA;IAChD,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AACpG,CAAC;AAED,SAAS,IAAI,CAAC,CAAU,EAAE,IAAY,EAAE,IAAY,EAAE,MAA2B;IAC/E,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,MAAM,GAAG,CAAC,SAAS,IAAI,aAAa,CAAC,CAAA;IACvD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,MAAM,GAAG,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAA;IACjE,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,MAAM,GAAG,CAAC,SAAS,IAAI,qCAAqC,CAAC,CAAA;IACzH,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,MAAM,GAAG,CAAC,SAAS,IAAI,iCAAiC,CAAC,CAAA;IAC9E,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,CAAC,SAAS,IAAI,kCAAkC,IAAI,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;AAC7E,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,WAAmB;IAC7D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,GAAG,CAAC,mBAAmB,CAAC,CAAA;IAClD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,UAAU,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAChF,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;IAC9G,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,mDAAmD,CAAC,CAAA;IAC1I,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,MAAM,GAAG,CAAC,yCAAyC,CAAC,CAAA;IACxF,IAAI,KAAK,KAAK,MAAM;QAAE,MAAM,GAAG,CAAC,SAAS,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IAC1E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QAAE,MAAM,GAAG,CAAC,mDAAmD,CAAC,CAAA;IAEtH,MAAM,CAAC,GAAG,GAAG,CAAC,aAAa,CAAA;IAC3B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,MAAM,GAAG,CAAC,0BAA0B,CAAC,CAAA;IACvD,IAAI,CAAC,CAAC,MAAM,KAAK,cAAc;QAAE,MAAM,GAAG,CAAC,UAAU,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IACzF,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,MAAM,GAAG,CAAC,0DAA0D,CAAC,CAAA;IAChH,MAAM,YAAY,GAAG,CAAC,CAAC,YAAY,CAAA;IACnC,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC5B,YAAY,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;QAChD,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,MAAM,EAClD,CAAC;QACD,MAAM,GAAG,CAAC,qCAAqC,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAA;IACvB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,IAAK,CAAC,CAAC,KAAgB,GAAG,CAAC,EAAE,CAAC;QAC3H,MAAM,GAAG,CAAC,6CAA6C,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAA;IACvB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAA;IACnD,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;IAC7D,IAAI,QAAQ,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE;QAAE,MAAM,GAAG,CAAC,4CAA4C,CAAC,CAAA;IAClG,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,6BAA6B,CAAC,CAAA;IACvG,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAiB,EAAE;QACtD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,MAAM,GAAG,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;QAClE,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YACrD,MAAM,GAAG,CAAC,gBAAgB,CAAC,eAAe,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAA;QAChG,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5E,MAAM,GAAG,CAAC,gBAAgB,CAAC,aAAa,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;QACvF,CAAC;QACD,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;IACxG,CAAC,CAAC,CAAA;IACF,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM;QAAE,MAAM,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAE7G,OAAO;QACL,YAAY;QACZ,YAAY;QACZ,KAAK;QACL,IAAI;QACJ,IAAI;QACJ,aAAa;QACb,eAAe;QACf,aAAa,EAAE;YACb,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,oBAAoB,CAAC;YAC1C,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,mBAAmB,CAAC;YACvC,YAAY,EAAE,YAA6B;SAC5C;QACD,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAe,EAAE;QACzE,KAAK;QACL,GAAG;QACH,MAAM;KACP,CAAA;AACH,CAAC"}