@wemush/wols 1.2.0 → 1.3.0
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/CHANGELOG.md +170 -0
- package/README.md +204 -31
- package/dist/cjs/compact-url.d.ts +150 -0
- package/dist/cjs/compact-url.d.ts.map +1 -0
- package/dist/cjs/crypto/decrypt.d.ts +110 -0
- package/dist/cjs/crypto/decrypt.d.ts.map +1 -0
- package/dist/cjs/crypto/decrypt.js +519 -99
- package/dist/cjs/crypto/decrypt.js.map +1 -1
- package/dist/cjs/crypto/encrypt.d.ts +132 -0
- package/dist/cjs/crypto/encrypt.d.ts.map +1 -0
- package/dist/cjs/crypto/encrypt.js +281 -200
- package/dist/cjs/crypto/encrypt.js.map +1 -1
- package/dist/cjs/crypto/index.d.ts +12 -0
- package/dist/cjs/crypto/index.d.ts.map +1 -0
- package/dist/cjs/crypto/index.js +15 -2
- package/dist/cjs/crypto/index.js.map +1 -1
- package/dist/cjs/crypto/shared.d.ts +116 -0
- package/dist/cjs/crypto/shared.d.ts.map +1 -0
- package/dist/cjs/crypto/shared.js +238 -0
- package/dist/cjs/crypto/shared.js.map +1 -0
- package/dist/cjs/errors.d.ts +133 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +39 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.d.ts +29 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +19 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/parser.d.ts +30 -0
- package/dist/cjs/parser.d.ts.map +1 -0
- package/dist/cjs/qr/generate.d.ts +62 -0
- package/dist/cjs/qr/generate.d.ts.map +1 -0
- package/dist/cjs/qr/index.d.ts +10 -0
- package/dist/cjs/qr/index.d.ts.map +1 -0
- package/dist/cjs/specimen.d.ts +96 -0
- package/dist/cjs/specimen.d.ts.map +1 -0
- package/dist/cjs/specimen.js +84 -11
- package/dist/cjs/specimen.js.map +1 -1
- package/dist/cjs/types.d.ts +735 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +65 -5
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/cuid.d.ts +46 -0
- package/dist/cjs/utils/cuid.d.ts.map +1 -0
- package/dist/cjs/utils/cuid.js +6 -4
- package/dist/cjs/utils/cuid.js.map +1 -1
- package/dist/cjs/utils/environment.d.ts +137 -0
- package/dist/cjs/utils/environment.d.ts.map +1 -0
- package/dist/cjs/utils/iso8601.d.ts +79 -0
- package/dist/cjs/utils/iso8601.d.ts.map +1 -0
- package/dist/cjs/utils/migration.d.ts +162 -0
- package/dist/cjs/utils/migration.d.ts.map +1 -0
- package/dist/cjs/validator.d.ts +25 -0
- package/dist/cjs/validator.d.ts.map +1 -0
- package/dist/cjs/validator.js +33 -22
- package/dist/cjs/validator.js.map +1 -1
- package/dist/esm/crypto/decrypt.js +515 -99
- package/dist/esm/crypto/decrypt.js.map +1 -1
- package/dist/esm/crypto/encrypt.js +277 -200
- package/dist/esm/crypto/encrypt.js.map +1 -1
- package/dist/esm/crypto/index.js +5 -3
- package/dist/esm/crypto/index.js.map +1 -1
- package/dist/esm/crypto/shared.js +222 -0
- package/dist/esm/crypto/shared.js.map +1 -0
- package/dist/esm/errors.js +37 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +6 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/specimen.js +84 -12
- package/dist/esm/specimen.js.map +1 -1
- package/dist/esm/types.js +63 -4
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/cuid.js +6 -4
- package/dist/esm/utils/cuid.js.map +1 -1
- package/dist/esm/validator.js +34 -23
- package/dist/esm/validator.js.map +1 -1
- package/dist/types/crypto/decrypt.d.ts +93 -22
- package/dist/types/crypto/decrypt.d.ts.map +1 -1
- package/dist/types/crypto/encrypt.d.ts +106 -61
- package/dist/types/crypto/encrypt.d.ts.map +1 -1
- package/dist/types/crypto/index.d.ts +5 -3
- package/dist/types/crypto/index.d.ts.map +1 -1
- package/dist/types/crypto/shared.d.ts +116 -0
- package/dist/types/crypto/shared.d.ts.map +1 -0
- package/dist/types/errors.d.ts +31 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/specimen.d.ts +29 -4
- package/dist/types/specimen.d.ts.map +1 -1
- package/dist/types/types.d.ts +265 -40
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/cuid.d.ts +5 -3
- package/dist/types/utils/cuid.d.ts.map +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/package.json +32 -14
package/dist/esm/crypto/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WOLS Crypto Module
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* AES-256-GCM encryption and decryption for specimens in the WOLS v1.3.0
|
|
5
|
+
* encrypted format (`wemush://v1/encrypted/{id}?e=&iv=&kdf=...`).
|
|
5
6
|
*
|
|
6
7
|
* @module crypto
|
|
7
8
|
*/
|
|
8
|
-
export { encryptSpecimen, isEncrypted } from './encrypt.js';
|
|
9
|
-
export { decryptSpecimen } from './decrypt.js';
|
|
9
|
+
export { encryptSpecimen, encryptFields, isEncrypted, isEncryptedSpecimen, isEncryptedField, toEncryptedUrl, } from './encrypt.js';
|
|
10
|
+
export { decryptSpecimen, decryptPlaintext, decryptField, decryptFields, parseEncryptedUrl, } from './decrypt.js';
|
|
11
|
+
export { base64UrlEncode, base64UrlDecode, derivePassphraseKey } from './shared.js';
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,iBAAiB,GAElB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared primitives for the WOLS encrypted format (v1.3.0).
|
|
3
|
+
*
|
|
4
|
+
* Uses only WebCrypto (`globalThis.crypto.subtle`), so it runs unchanged in
|
|
5
|
+
* Node.js 20+, browsers, Deno, Bun and workers.
|
|
6
|
+
*
|
|
7
|
+
* `base64UrlEncode`, `base64UrlDecode` and `derivePassphraseKey` are public
|
|
8
|
+
* (re-exported from the package root and `@wemush/wols/crypto`); everything
|
|
9
|
+
* else here is internal to the crypto module.
|
|
10
|
+
*
|
|
11
|
+
* @module crypto/shared
|
|
12
|
+
*/
|
|
13
|
+
import { WolsDecryptionError, WolsEncryptionError, WolsErrorCode } from '../errors.js';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// CONSTANTS
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/** Default PBKDF2 iteration count used when generating. */
|
|
18
|
+
export const DEFAULT_PBKDF2_ITERATIONS = 600_000;
|
|
19
|
+
/** Iteration count pre-1.3.0 payloads used when they recorded none. */
|
|
20
|
+
export const LEGACY_PBKDF2_ITERATIONS = 100_000;
|
|
21
|
+
/** Generators MUST use at least this many PBKDF2 iterations (WOLS v1.3.0). */
|
|
22
|
+
export const MIN_GENERATE_ITERATIONS = 100_000;
|
|
23
|
+
/** Decoders MUST reject fewer PBKDF2 iterations than this (WOLS v1.3.0). */
|
|
24
|
+
export const MIN_DECODE_ITERATIONS = 10_000;
|
|
25
|
+
/** Default largest PBKDF2 iteration count accepted from a label when decoding. */
|
|
26
|
+
export const DEFAULT_MAX_DECODE_ITERATIONS = 10_000_000;
|
|
27
|
+
/**
|
|
28
|
+
* WOLS 1.3.0 ceiling: decoders reject more than this many iterations (alone,
|
|
29
|
+
* or in total across a field-encrypted label), and generators never exceed it.
|
|
30
|
+
* A configured `maxIterations` may be lower, never higher.
|
|
31
|
+
*/
|
|
32
|
+
export const MAX_ITERATIONS = 10_000_000;
|
|
33
|
+
/** WebCrypto's PBKDF2 `iterations` is an unsigned long; nothing above this is derivable. */
|
|
34
|
+
export const MAX_PBKDF2_ITERATIONS = 0xffff_ffff;
|
|
35
|
+
/** Per-label PBKDF2 salt length generated (spec minimum: 16 bytes). */
|
|
36
|
+
export const SALT_LENGTH = 16;
|
|
37
|
+
/** AES-GCM appends a 16-byte authentication tag, so no valid ciphertext is shorter. */
|
|
38
|
+
export const GCM_TAG_LENGTH = 16;
|
|
39
|
+
/** AES-GCM IV length in bytes. */
|
|
40
|
+
export const IV_LENGTH = 12;
|
|
41
|
+
/** Raw AES-256 key length in bytes. */
|
|
42
|
+
export const RAW_KEY_LENGTH = 32;
|
|
43
|
+
/** Prefix of every encrypted-format URL. */
|
|
44
|
+
export const ENCRYPTED_URL_PREFIX = 'wemush://v1/encrypted/';
|
|
45
|
+
/**
|
|
46
|
+
* Library-wide salt used by pre-1.3.0 releases. Only for decoding legacy
|
|
47
|
+
* payloads behind `allowLegacy`; never used when generating.
|
|
48
|
+
*/
|
|
49
|
+
export const LEGACY_PBKDF2_SALT = new TextEncoder().encode('@wemush/wols/crypto/v1');
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// ERRORS
|
|
52
|
+
// =============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Create a decryption error carrying a stable `details.reason` category.
|
|
55
|
+
*/
|
|
56
|
+
export function decryptionError(reason, message, details = {}) {
|
|
57
|
+
return new WolsDecryptionError(reason, message, details);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether WebCrypto (`globalThis.crypto.subtle`) is available. It is global in
|
|
61
|
+
* browsers, workers, Deno, Bun and Node.js 19+ (Node 18 needs
|
|
62
|
+
* `--experimental-global-webcrypto`).
|
|
63
|
+
*/
|
|
64
|
+
export function hasWebCrypto() {
|
|
65
|
+
const c = globalThis.crypto;
|
|
66
|
+
return (typeof c?.subtle === 'object' && c.subtle !== null && typeof c.getRandomValues === 'function');
|
|
67
|
+
}
|
|
68
|
+
/** Message used when WebCrypto is missing. */
|
|
69
|
+
export const NO_WEBCRYPTO_MESSAGE = 'WebCrypto (globalThis.crypto.subtle) is not available in this runtime. ' +
|
|
70
|
+
'Use Node.js 20+, a modern browser, Deno or Bun.';
|
|
71
|
+
/** Throw a WolsEncryptionError when WebCrypto is missing (encryption paths). */
|
|
72
|
+
export function assertWebCrypto() {
|
|
73
|
+
if (!hasWebCrypto()) {
|
|
74
|
+
throw new WolsEncryptionError(WolsErrorCode.ENCRYPTION_ERROR, NO_WEBCRYPTO_MESSAGE);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// =============================================================================
|
|
78
|
+
// BASE64URL
|
|
79
|
+
// =============================================================================
|
|
80
|
+
/**
|
|
81
|
+
* Encode bytes as base64url (RFC 4648 §5) without padding.
|
|
82
|
+
*
|
|
83
|
+
* @since 1.3.0
|
|
84
|
+
*/
|
|
85
|
+
export function base64UrlEncode(bytes) {
|
|
86
|
+
const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
87
|
+
let binary = '';
|
|
88
|
+
for (const byte of view) {
|
|
89
|
+
binary += String.fromCharCode(byte);
|
|
90
|
+
}
|
|
91
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
92
|
+
}
|
|
93
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]*={0,2}$/;
|
|
94
|
+
/**
|
|
95
|
+
* Decode base64url (RFC 4648 §5). Padded input is accepted.
|
|
96
|
+
*
|
|
97
|
+
* @throws Error if the input is not valid base64url
|
|
98
|
+
* @since 1.3.0
|
|
99
|
+
*/
|
|
100
|
+
export function base64UrlDecode(value) {
|
|
101
|
+
if (!BASE64URL_PATTERN.test(value)) {
|
|
102
|
+
throw new Error('Invalid base64url string');
|
|
103
|
+
}
|
|
104
|
+
const unpadded = value.replace(/=+$/, '');
|
|
105
|
+
if (unpadded.length % 4 === 1) {
|
|
106
|
+
throw new Error('Invalid base64url length');
|
|
107
|
+
}
|
|
108
|
+
const base64 = unpadded.replace(/-/g, '+').replace(/_/g, '/');
|
|
109
|
+
const binary = atob(base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '='));
|
|
110
|
+
const bytes = new Uint8Array(binary.length);
|
|
111
|
+
for (let i = 0; i < binary.length; i++) {
|
|
112
|
+
bytes[i] = binary.charCodeAt(i);
|
|
113
|
+
}
|
|
114
|
+
return bytes;
|
|
115
|
+
}
|
|
116
|
+
// =============================================================================
|
|
117
|
+
// RANDOMNESS
|
|
118
|
+
// =============================================================================
|
|
119
|
+
/** Cryptographically random bytes from WebCrypto. */
|
|
120
|
+
export function randomBytes(length) {
|
|
121
|
+
const bytes = new Uint8Array(length);
|
|
122
|
+
crypto.getRandomValues(bytes);
|
|
123
|
+
return bytes;
|
|
124
|
+
}
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// KEYS
|
|
127
|
+
// =============================================================================
|
|
128
|
+
/** Copy a byte view into a fresh ArrayBuffer-backed Uint8Array (WebCrypto-safe). */
|
|
129
|
+
function toOwnedBytes(bytes) {
|
|
130
|
+
const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
131
|
+
const copy = new Uint8Array(view.length);
|
|
132
|
+
copy.set(view);
|
|
133
|
+
return copy;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Derive a 256-bit key from a passphrase with PBKDF2-HMAC-SHA256.
|
|
137
|
+
*
|
|
138
|
+
* Exposed for debugging and interoperability testing (it reproduces the
|
|
139
|
+
* conformance `derive` vectors). Returns the raw key bytes.
|
|
140
|
+
*
|
|
141
|
+
* @param passphrase - Passphrase; normalized to Unicode NFC, then UTF-8 encoded (WOLS 1.3.0)
|
|
142
|
+
* @param salt - Salt bytes (the label's decoded `salt` parameter)
|
|
143
|
+
* @param iterations - PBKDF2 iteration count (positive integer)
|
|
144
|
+
* @since 1.3.0
|
|
145
|
+
*/
|
|
146
|
+
export async function derivePassphraseKey(passphrase, salt, iterations) {
|
|
147
|
+
if (!Number.isInteger(iterations) || iterations < 1 || iterations > MAX_PBKDF2_ITERATIONS) {
|
|
148
|
+
throw new Error(`PBKDF2 iterations must be an integer from 1 to ${MAX_PBKDF2_ITERATIONS}, got ${iterations}`);
|
|
149
|
+
}
|
|
150
|
+
const material = await crypto.subtle.importKey('raw',
|
|
151
|
+
// WOLS 1.3.0: NFC so composed and decomposed input derive the same key.
|
|
152
|
+
new TextEncoder().encode(passphrase.normalize('NFC')), 'PBKDF2', false, ['deriveBits']);
|
|
153
|
+
const bits = await crypto.subtle.deriveBits({ name: 'PBKDF2', hash: 'SHA-256', salt: toOwnedBytes(salt), iterations }, material, 256);
|
|
154
|
+
return new Uint8Array(bits);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Field-level AES-GCM additional data (WOLS 1.3.0): UTF-8 of the label's full
|
|
158
|
+
* `id`, a line feed, and the top-level field name, e.g. "wemush:clx1a2b3c4\nstrain".
|
|
159
|
+
* Binds each encrypted value to its label and field.
|
|
160
|
+
*/
|
|
161
|
+
export function fieldAad(id, field) {
|
|
162
|
+
return new TextEncoder().encode(`${id}\n${field}`);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fields that identify or type a label. They are never encrypted, and a label
|
|
166
|
+
* in which any of them is an encrypted object is refused (WOLS 1.3.0).
|
|
167
|
+
*/
|
|
168
|
+
export const IDENTIFYING_FIELDS = [
|
|
169
|
+
'@context',
|
|
170
|
+
'@type',
|
|
171
|
+
'id',
|
|
172
|
+
'version',
|
|
173
|
+
'type',
|
|
174
|
+
'species',
|
|
175
|
+
];
|
|
176
|
+
/** Import 32 raw key bytes as an AES-GCM key. */
|
|
177
|
+
export async function importAesKey(bytes, usage) {
|
|
178
|
+
return crypto.subtle.importKey('raw', toOwnedBytes(bytes), { name: 'AES-GCM' }, false, [usage]);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check whether a value is a WebCrypto CryptoKey without relying on the
|
|
182
|
+
* global `CryptoKey` constructor (absent in some runtimes).
|
|
183
|
+
*/
|
|
184
|
+
export function isCryptoKey(value) {
|
|
185
|
+
return (typeof value === 'object' &&
|
|
186
|
+
value !== null &&
|
|
187
|
+
'algorithm' in value &&
|
|
188
|
+
'usages' in value &&
|
|
189
|
+
'type' in value &&
|
|
190
|
+
!(value instanceof Uint8Array) &&
|
|
191
|
+
!(value instanceof ArrayBuffer));
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resolve a raw key (bytes or CryptoKey) to an AES-256-GCM CryptoKey.
|
|
195
|
+
* Returns an error message string when the key is unusable.
|
|
196
|
+
*/
|
|
197
|
+
export async function resolveRawKey(key, usage) {
|
|
198
|
+
if (isCryptoKey(key)) {
|
|
199
|
+
const algorithm = key.algorithm;
|
|
200
|
+
if (algorithm.name !== 'AES-GCM' || algorithm.length !== 256) {
|
|
201
|
+
return `CryptoKey must be AES-GCM with length 256, got ${algorithm.name ?? 'unknown'}/${algorithm.length ?? '?'}`;
|
|
202
|
+
}
|
|
203
|
+
if (!key.usages.includes(usage)) {
|
|
204
|
+
return `CryptoKey does not allow '${usage}'`;
|
|
205
|
+
}
|
|
206
|
+
return key;
|
|
207
|
+
}
|
|
208
|
+
const length = key instanceof Uint8Array ? key.length : key.byteLength;
|
|
209
|
+
if (length !== RAW_KEY_LENGTH) {
|
|
210
|
+
return `Raw key must be exactly ${RAW_KEY_LENGTH} bytes, got ${length}`;
|
|
211
|
+
}
|
|
212
|
+
return importAesKey(key, usage);
|
|
213
|
+
}
|
|
214
|
+
/** Whether a key value is a passphrase (selects kdf=pbkdf2). */
|
|
215
|
+
export function isPassphrase(key) {
|
|
216
|
+
return typeof key === 'string';
|
|
217
|
+
}
|
|
218
|
+
/** Whether a key value is raw key material (selects kdf=raw). */
|
|
219
|
+
export function isRawKey(key) {
|
|
220
|
+
return key instanceof Uint8Array || key instanceof ArrayBuffer || isCryptoKey(key);
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/crypto/shared.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/errors.js
CHANGED
|
@@ -128,6 +128,43 @@ export class WolsEncryptionError extends WolsError {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Decryption failure with a stable, typed {@link DecryptionFailureReason}.
|
|
133
|
+
*
|
|
134
|
+
* It extends `WolsEncryptionError` on purpose: 1.2.x returned a
|
|
135
|
+
* `WolsEncryptionError` for decryption failures, so existing
|
|
136
|
+
* `instanceof WolsEncryptionError` checks keep matching. Encryption misuse is
|
|
137
|
+
* thrown as a plain `WolsEncryptionError`; decryption failures are returned as
|
|
138
|
+
* this subclass, so check `instanceof WolsDecryptionError` to tell them apart.
|
|
139
|
+
* Malformed encrypted URLs are reported here too (`invalid-url`), not as
|
|
140
|
+
* `WolsParseError`, so every decryption input problem has one error type.
|
|
141
|
+
*
|
|
142
|
+
* Returned (never thrown) by `decryptSpecimen`, `decryptPlaintext`,
|
|
143
|
+
* `decryptField` and `decryptFields`. `reason` is also copied into
|
|
144
|
+
* `details.reason` for code that reads the generic error shape.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const r = await decryptSpecimen(url, { key });
|
|
149
|
+
* if (!r.success && r.error.reason === 'legacy-format') {
|
|
150
|
+
* // a pre-1.3.0 label: retry with { allowLegacy: true } during migration
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @since 1.3.0
|
|
155
|
+
*/
|
|
156
|
+
export class WolsDecryptionError extends WolsEncryptionError {
|
|
157
|
+
/** Stable failure category */
|
|
158
|
+
reason;
|
|
159
|
+
constructor(reason, message, details) {
|
|
160
|
+
super(reason === 'invalid-key' ? WolsErrorCode.INVALID_KEY : WolsErrorCode.DECRYPTION_ERROR, message, { ...details, reason });
|
|
161
|
+
this.name = 'WolsDecryptionError';
|
|
162
|
+
this.reason = reason;
|
|
163
|
+
if (Error.captureStackTrace) {
|
|
164
|
+
Error.captureStackTrace(this, WolsDecryptionError);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
131
168
|
// =============================================================================
|
|
132
169
|
// ERROR FACTORY FUNCTIONS
|
|
133
170
|
// =============================================================================
|
package/dist/esm/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @wemush/wols - Official WOLS TypeScript Library
|
|
3
3
|
*
|
|
4
|
-
* WeMush Open Labeling Standard (WOLS) v1.
|
|
4
|
+
* WeMush Open Labeling Standard (WOLS) v1.3.0 implementation
|
|
5
5
|
* for biological specimen labeling and traceability.
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
* @module @wemush/wols
|
|
9
|
-
* @version 1.
|
|
9
|
+
* @version 1.3.0
|
|
10
10
|
*/
|
|
11
11
|
// =============================================================================
|
|
12
12
|
// Constants
|
|
@@ -19,7 +19,7 @@ export { asSpecimenId, isSpecimenType, isGrowthStage, isStrain, SPECIMEN_TYPES,
|
|
|
19
19
|
// =============================================================================
|
|
20
20
|
// Type Alias System (v1.2.0)
|
|
21
21
|
// =============================================================================
|
|
22
|
-
export { registerTypeAlias, resolveTypeAlias, getTypeAliases } from './types.js';
|
|
22
|
+
export { registerTypeAlias, resolveTypeAlias, getTypeAliases, resolveTypeAndStage, PRIMORDIA_TYPE_ALIAS, } from './types.js';
|
|
23
23
|
// =============================================================================
|
|
24
24
|
// Type Mapping System (v1.2.0)
|
|
25
25
|
// =============================================================================
|
|
@@ -31,11 +31,11 @@ export { normalizeGeneration, isValidGeneration } from './types.js';
|
|
|
31
31
|
// =============================================================================
|
|
32
32
|
// Errors
|
|
33
33
|
// =============================================================================
|
|
34
|
-
export { WolsErrorCode, WolsError, WolsParseError, WolsValidationError, WolsEncryptionError, } from './errors.js';
|
|
34
|
+
export { WolsErrorCode, WolsError, WolsParseError, WolsValidationError, WolsEncryptionError, WolsDecryptionError, } from './errors.js';
|
|
35
35
|
// =============================================================================
|
|
36
36
|
// Core Functions - Specimen
|
|
37
37
|
// =============================================================================
|
|
38
|
-
export { createSpecimen, serializeSpecimen } from './specimen.js';
|
|
38
|
+
export { createSpecimen, serializeSpecimen, PRIMORDIA_AS_TYPE_WARNING } from './specimen.js';
|
|
39
39
|
// =============================================================================
|
|
40
40
|
// Core Functions - Validation
|
|
41
41
|
// =============================================================================
|
|
@@ -51,7 +51,7 @@ export { toCompactUrl, parseCompactUrl, parseCompactUrlOrThrow, parseCompactUrlO
|
|
|
51
51
|
// =============================================================================
|
|
52
52
|
// Core Functions - Encryption
|
|
53
53
|
// =============================================================================
|
|
54
|
-
export { encryptSpecimen, isEncrypted, decryptSpecimen } from './crypto/index.js';
|
|
54
|
+
export { encryptSpecimen, encryptFields, isEncrypted, isEncryptedSpecimen, isEncryptedField, toEncryptedUrl, decryptSpecimen, decryptPlaintext, decryptField, decryptFields, parseEncryptedUrl, base64UrlEncode, base64UrlDecode, derivePassphraseKey, } from './crypto/index.js';
|
|
55
55
|
// =============================================================================
|
|
56
56
|
// Core Functions - QR Code Generation
|
|
57
57
|
// =============================================================================
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAChF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAChF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiDxD,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,6BAA6B;AAC7B,gFAAgF;AAChF,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,oCAAoC;AACpC,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpE,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE7F,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAChF,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,iBAAiB,EAEjB,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAE3B,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAChF,OAAO,EACL,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAChF,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,MAAM,EACN,KAAK,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAGhC,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAChF,OAAO,EACL,eAAe,EACf,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,aAAa,EACb,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/esm/specimen.js
CHANGED
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
* Specimen Creation and Serialization
|
|
3
3
|
*
|
|
4
4
|
* This module provides functions to create and serialize
|
|
5
|
-
* WOLS v1.
|
|
5
|
+
* WOLS v1.3.0 compliant specimen objects.
|
|
6
6
|
*
|
|
7
7
|
* @module specimen
|
|
8
8
|
*/
|
|
9
|
-
import { WOLS_CONTEXT, WOLS_VERSION, asSpecimenId,
|
|
9
|
+
import { WOLS_CONTEXT, WOLS_VERSION, asSpecimenId, isStrain, resolveTypeAndStage, } from './types.js';
|
|
10
10
|
import { createSpecimenId } from './utils/cuid.js';
|
|
11
|
+
import { isValidISO8601 } from './utils/iso8601.js';
|
|
12
|
+
/**
|
|
13
|
+
* Warning code emitted when `PRIMORDIA` is supplied as a specimen type.
|
|
14
|
+
*
|
|
15
|
+
* @since 1.3.0
|
|
16
|
+
*/
|
|
17
|
+
export const PRIMORDIA_AS_TYPE_WARNING = 'PRIMORDIA_AS_TYPE';
|
|
18
|
+
function primordiaWarning() {
|
|
19
|
+
return {
|
|
20
|
+
path: 'type',
|
|
21
|
+
code: PRIMORDIA_AS_TYPE_WARNING,
|
|
22
|
+
message: `'PRIMORDIA' is a growth stage, not a specimen type; resolved to type 'FRUITING'`,
|
|
23
|
+
suggestion: `Use type: 'FRUITING', stage: 'PRIMORDIA'`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
11
26
|
/**
|
|
12
27
|
* Expand a strain input to a full Strain object.
|
|
13
28
|
* String inputs are expanded to { name: string }.
|
|
@@ -30,11 +45,17 @@ function expandStrain(strain) {
|
|
|
30
45
|
/**
|
|
31
46
|
* Create a new specimen with auto-generated ID and JSON-LD fields.
|
|
32
47
|
*
|
|
33
|
-
* This function creates a fully-formed WOLS v1.
|
|
48
|
+
* This function creates a fully-formed WOLS v1.3.0 compliant Specimen
|
|
34
49
|
* with automatic ID generation, version assignment, and JSON-LD context.
|
|
35
50
|
*
|
|
51
|
+
* Type aliases resolve case-insensitively. `PRIMORDIA` supplied as a type
|
|
52
|
+
* resolves to `FRUITING`, sets `stage: 'PRIMORDIA'` when no stage was given
|
|
53
|
+
* (a supplied stage is never overridden), and emits a warning.
|
|
54
|
+
*
|
|
36
55
|
* @param input - Specimen creation parameters
|
|
56
|
+
* @param options - `onWarning` receives non-fatal warnings (default: console.warn)
|
|
37
57
|
* @returns Fully-formed Specimen with JSON-LD fields
|
|
58
|
+
* @throws Error if the type is unknown or `created` is not ISO 8601
|
|
38
59
|
*
|
|
39
60
|
* @example
|
|
40
61
|
* ```typescript
|
|
@@ -64,33 +85,74 @@ function expandStrain(strain) {
|
|
|
64
85
|
* species: 'Ganoderma lucidum',
|
|
65
86
|
* strain: 'Reishi Red', // Auto-expands to { name: 'Reishi Red' }
|
|
66
87
|
* });
|
|
88
|
+
*
|
|
89
|
+
* // PRIMORDIA as a type (v1.3.0) -> type FRUITING, stage PRIMORDIA, plus a warning
|
|
90
|
+
* const pinning = createSpecimen(
|
|
91
|
+
* { type: 'PRIMORDIA', species: 'Pleurotus ostreatus' },
|
|
92
|
+
* { onWarning: w => console.info(w.message) }
|
|
93
|
+
* );
|
|
94
|
+
*
|
|
95
|
+
* // Explicit creation timestamp (v1.3.0)
|
|
96
|
+
* const dated = createSpecimen({
|
|
97
|
+
* type: 'CULTURE',
|
|
98
|
+
* species: 'Pleurotus ostreatus',
|
|
99
|
+
* created: '2025-12-16T10:30:00Z',
|
|
100
|
+
* });
|
|
67
101
|
* ```
|
|
68
102
|
*/
|
|
69
|
-
export function createSpecimen(input) {
|
|
103
|
+
export function createSpecimen(input, options = {}) {
|
|
70
104
|
const id = asSpecimenId(createSpecimenId());
|
|
71
105
|
const strain = expandStrain(input.strain);
|
|
72
106
|
// Resolve type alias to canonical WOLS type (e.g., 'LIQUID_CULTURE' -> 'CULTURE')
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
107
|
+
const resolved = resolveTypeAndStage(input.type, input.stage);
|
|
108
|
+
if (resolved === null) {
|
|
75
109
|
throw new Error(`Invalid specimen type: '${input.type}'. ` +
|
|
76
110
|
`Must be one of: CULTURE, SPAWN, SUBSTRATE, FRUITING, HARVEST ` +
|
|
77
111
|
`(or a registered alias).`);
|
|
78
112
|
}
|
|
113
|
+
let created;
|
|
114
|
+
if (input.created !== undefined) {
|
|
115
|
+
if (input.created instanceof Date) {
|
|
116
|
+
if (Number.isNaN(input.created.getTime())) {
|
|
117
|
+
throw new Error('Invalid created timestamp: Date is invalid. Must be ISO 8601.');
|
|
118
|
+
}
|
|
119
|
+
created = input.created.toISOString();
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
created = input.created;
|
|
123
|
+
}
|
|
124
|
+
if (typeof created !== 'string' || !isValidISO8601(created)) {
|
|
125
|
+
throw new Error(`Invalid created timestamp: '${String(input.created)}'. Must be ISO 8601.`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (resolved.primordia) {
|
|
129
|
+
const warning = primordiaWarning();
|
|
130
|
+
if (options.onWarning) {
|
|
131
|
+
options.onWarning(warning);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
// eslint-disable-next-line no-console
|
|
135
|
+
console.warn(`[@wemush/wols] ${warning.message}. ${warning.suggestion ?? ''}`.trim());
|
|
136
|
+
}
|
|
137
|
+
}
|
|
79
138
|
// Build specimen with required fields
|
|
80
139
|
const specimen = {
|
|
81
140
|
'@context': WOLS_CONTEXT,
|
|
82
141
|
'@type': 'Specimen',
|
|
83
142
|
id,
|
|
84
143
|
version: WOLS_VERSION,
|
|
85
|
-
type:
|
|
144
|
+
type: resolved.type,
|
|
86
145
|
species: input.species,
|
|
87
146
|
};
|
|
88
147
|
// Add optional fields only if defined
|
|
89
148
|
if (strain !== undefined) {
|
|
90
149
|
specimen.strain = strain;
|
|
91
150
|
}
|
|
92
|
-
if (
|
|
93
|
-
specimen.stage =
|
|
151
|
+
if (resolved.stage !== undefined) {
|
|
152
|
+
specimen.stage = resolved.stage;
|
|
153
|
+
}
|
|
154
|
+
if (created !== undefined) {
|
|
155
|
+
specimen.created = created;
|
|
94
156
|
}
|
|
95
157
|
if (input.batch !== undefined) {
|
|
96
158
|
specimen.batch = input.batch;
|
|
@@ -130,21 +192,31 @@ export function createSpecimen(input) {
|
|
|
130
192
|
* ```
|
|
131
193
|
*/
|
|
132
194
|
export function serializeSpecimen(specimen) {
|
|
195
|
+
// WOLS v1.3.0: PRIMORDIA is never emitted as a type. A specimen object built
|
|
196
|
+
// by hand with type PRIMORDIA gets the same resolution as createSpecimen()
|
|
197
|
+
// (shared resolveTypeAndStage). Any other type is emitted as given.
|
|
198
|
+
let type = specimen.type;
|
|
199
|
+
let stage = specimen.stage;
|
|
200
|
+
const resolved = resolveTypeAndStage(type, stage);
|
|
201
|
+
if (resolved?.primordia) {
|
|
202
|
+
type = resolved.type;
|
|
203
|
+
stage = resolved.stage;
|
|
204
|
+
}
|
|
133
205
|
// Build ordered object with JSON-LD fields first
|
|
134
206
|
const ordered = {
|
|
135
207
|
'@context': specimen['@context'],
|
|
136
208
|
'@type': specimen['@type'],
|
|
137
209
|
id: specimen.id,
|
|
138
210
|
version: specimen.version,
|
|
139
|
-
type
|
|
211
|
+
type,
|
|
140
212
|
species: specimen.species,
|
|
141
213
|
};
|
|
142
214
|
// Add optional fields in order, only if defined
|
|
143
215
|
if (specimen.strain !== undefined) {
|
|
144
216
|
ordered['strain'] = specimen.strain;
|
|
145
217
|
}
|
|
146
|
-
if (
|
|
147
|
-
ordered['stage'] =
|
|
218
|
+
if (stage !== undefined) {
|
|
219
|
+
ordered['stage'] = stage;
|
|
148
220
|
}
|
|
149
221
|
if (specimen.created !== undefined) {
|
|
150
222
|
ordered['created'] = specimen.created;
|
package/dist/esm/specimen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specimen.js","sourceRoot":"","sources":["../../src/specimen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"specimen.js","sourceRoot":"","sources":["../../src/specimen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAE7D,SAAS,gBAAgB;IACvB,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,iFAAiF;QAC1F,UAAU,EAAE,0CAA0C;KACvD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,MAAmC;IACvD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAoB,EACpB,UAAiC,EAAE;IAEnC,MAAM,EAAE,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE1C,kFAAkF;IAClF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,CAAC,IAAI,KAAK;YACxC,+DAA+D;YAC/D,0BAA0B,CAC7B,CAAC;IACJ,CAAC;IAED,IAAI,OAA2B,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;YACnF,CAAC;YACD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC1B,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,kBAAkB,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,MAAM,QAAQ,GAAa;QACzB,UAAU,EAAE,YAAY;QACxB,OAAO,EAAE,UAAU;QACnB,EAAE;QACF,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;IAEF,sCAAsC;IACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACrC,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IACnC,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IACjC,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC/B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IAClD,6EAA6E;IAC7E,2EAA2E;IAC3E,oEAAoE;IACpE,IAAI,IAAI,GAAW,QAAQ,CAAC,IAAI,CAAC;IACjC,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC3B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC;QACxB,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrB,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IACzB,CAAC;IAED,iDAAiD;IACjD,MAAM,OAAO,GAA4B;QACvC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;QAChC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;QAC1B,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,IAAI;QACJ,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC;IAEF,gDAAgD;IAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;IACxC,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC;IAClD,CAAC;IAED,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;IACxC,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC5C,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC"}
|