aviation-chart 2.0.34 → 2.0.36
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/nav-sdk.d.ts +1 -0
- package/dist/nav-sdk.esm.js +421 -150
- package/package.json +2 -2
package/dist/nav-sdk.d.ts
CHANGED
package/dist/nav-sdk.esm.js
CHANGED
|
@@ -2029,7 +2029,7 @@ const AMM_LAYER_GROUPS = {
|
|
|
2029
2029
|
ammHolding: ['amm-holding', 'amm-holding-label'],
|
|
2030
2030
|
ammStand: ['amm-stand-label', 'amm-stand-line'],
|
|
2031
2031
|
ammRestricted: ['amm-restricted-fill'],
|
|
2032
|
-
ammHotspot: ['amm-hotspot-fill'],
|
|
2032
|
+
ammHotspot: ['amm-hotspot-fill', 'amm-hotpost-label'],
|
|
2033
2033
|
/** 障碍物(点 + 面) */
|
|
2034
2034
|
ammObstacle: ['amm-obstacle-region-fill', 'amm-obstacle-point-label'],
|
|
2035
2035
|
ammConstruction: ['amm-construction-fill', 'amm-construction-stroke', 'amm-construction-label'],
|
|
@@ -7713,9 +7713,13 @@ function isBytes$1(a) {
|
|
|
7713
7713
|
'BYTES_PER_ELEMENT' in a &&
|
|
7714
7714
|
a.BYTES_PER_ELEMENT === 1));
|
|
7715
7715
|
}
|
|
7716
|
+
// Shared error-message prefix builder. Only called on throw paths, so assert
|
|
7717
|
+
// success paths never pay for the string concatenation.
|
|
7718
|
+
const atitle$1 = (title) => (title ? `"${title}" ` : '');
|
|
7716
7719
|
/**
|
|
7717
7720
|
* Asserts something is boolean.
|
|
7718
|
-
* @param
|
|
7721
|
+
* @param value - Value to validate.
|
|
7722
|
+
* @returns The validated boolean.
|
|
7719
7723
|
* @throws On wrong argument types. {@link TypeError}
|
|
7720
7724
|
* @example
|
|
7721
7725
|
* Validates a boolean option before branching on it.
|
|
@@ -7724,13 +7728,15 @@ function isBytes$1(a) {
|
|
|
7724
7728
|
* abool(true);
|
|
7725
7729
|
* ```
|
|
7726
7730
|
*/
|
|
7727
|
-
function abool(
|
|
7728
|
-
if (typeof
|
|
7729
|
-
throw new TypeError(
|
|
7731
|
+
function abool(value, title = '') {
|
|
7732
|
+
if (typeof value !== 'boolean')
|
|
7733
|
+
throw new TypeError(atitle$1(title) + 'expected boolean, got type=' + typeof value);
|
|
7734
|
+
return value;
|
|
7730
7735
|
}
|
|
7731
7736
|
/**
|
|
7732
7737
|
* Asserts something is a non-negative safe integer.
|
|
7733
7738
|
* @param n - Value to validate.
|
|
7739
|
+
* @returns The validated number.
|
|
7734
7740
|
* @throws On wrong argument types. {@link TypeError}
|
|
7735
7741
|
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
7736
7742
|
* @example
|
|
@@ -7740,11 +7746,12 @@ function abool(b) {
|
|
|
7740
7746
|
* anumber(1);
|
|
7741
7747
|
* ```
|
|
7742
7748
|
*/
|
|
7743
|
-
function anumber$1(n) {
|
|
7749
|
+
function anumber$1(n, title = '') {
|
|
7744
7750
|
if (typeof n !== 'number')
|
|
7745
|
-
throw new TypeError('number
|
|
7751
|
+
throw new TypeError(atitle$1(title) + 'expected number, got ' + typeof n);
|
|
7746
7752
|
if (!Number.isSafeInteger(n) || n < 0)
|
|
7747
|
-
throw new RangeError('
|
|
7753
|
+
throw new RangeError(atitle$1(title) + 'expected integer >= 0, got ' + n);
|
|
7754
|
+
return n;
|
|
7748
7755
|
}
|
|
7749
7756
|
/**
|
|
7750
7757
|
* Asserts something is Uint8Array.
|
|
@@ -7763,19 +7770,20 @@ function anumber$1(n) {
|
|
|
7763
7770
|
* ```
|
|
7764
7771
|
*/
|
|
7765
7772
|
function abytes$1(value, length, title = '') {
|
|
7773
|
+
// Success path first: this runs at the start of every update() / digestInto(), and the
|
|
7774
|
+
// common `abytes(data)` form must not pay for length handling it does not use.
|
|
7775
|
+
if (isBytes$1(value) && (length === undefined || value.length === length))
|
|
7776
|
+
return value;
|
|
7777
|
+
// Error path: recompute freely to build the exact message.
|
|
7778
|
+
if (length !== undefined)
|
|
7779
|
+
anumber$1(length, 'length');
|
|
7766
7780
|
const bytes = isBytes$1(value);
|
|
7767
|
-
const
|
|
7768
|
-
const
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
7774
|
-
if (!bytes)
|
|
7775
|
-
throw new TypeError(message);
|
|
7776
|
-
throw new RangeError(message);
|
|
7777
|
-
}
|
|
7778
|
-
return value;
|
|
7781
|
+
const ofLen = length !== undefined ? ` of length ${length}` : '';
|
|
7782
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
7783
|
+
const message = atitle$1(title) + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
7784
|
+
if (!bytes)
|
|
7785
|
+
throw new TypeError(message);
|
|
7786
|
+
throw new RangeError(message);
|
|
7779
7787
|
}
|
|
7780
7788
|
/**
|
|
7781
7789
|
* Asserts a hash- or MAC-like instance has not been destroyed or finished.
|
|
@@ -7791,21 +7799,21 @@ function abytes$1(value, length, title = '') {
|
|
|
7791
7799
|
* ```
|
|
7792
7800
|
*/
|
|
7793
7801
|
function aexists$1(instance, checkFinished = true) {
|
|
7802
|
+
// Runs on every update()/digestInto(); the flags are library-owned booleans, so only their
|
|
7803
|
+
// truthiness is checked - re-validating their type per call was pure hot-path overhead.
|
|
7794
7804
|
if (instance.destroyed)
|
|
7795
|
-
throw new Error('
|
|
7805
|
+
throw new Error('hash was destroyed');
|
|
7796
7806
|
if (checkFinished && instance.finished)
|
|
7797
|
-
throw new Error('
|
|
7807
|
+
throw new Error('digest() was already called');
|
|
7798
7808
|
}
|
|
7799
7809
|
/**
|
|
7800
|
-
* Asserts output is a
|
|
7810
|
+
* Asserts output is a sufficiently-sized byte array.
|
|
7801
7811
|
* @param out - Output buffer to validate.
|
|
7802
7812
|
* @param instance - Hash-like instance providing `outputLen`.
|
|
7803
7813
|
* This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`,
|
|
7804
7814
|
* unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths.
|
|
7805
7815
|
* @throws On wrong argument types. {@link TypeError}
|
|
7806
|
-
* @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views.
|
|
7807
7816
|
* @throws On wrong output buffer lengths. {@link RangeError}
|
|
7808
|
-
* @throws On wrong output buffer alignment. {@link Error}
|
|
7809
7817
|
* @example
|
|
7810
7818
|
* Verifies that a caller-provided output buffer is large enough.
|
|
7811
7819
|
*
|
|
@@ -7813,13 +7821,34 @@ function aexists$1(instance, checkFinished = true) {
|
|
|
7813
7821
|
* aoutput(new Uint8Array(16), { outputLen: 16 });
|
|
7814
7822
|
* ```
|
|
7815
7823
|
*/
|
|
7816
|
-
function aoutput$1(out, instance
|
|
7824
|
+
function aoutput$1(out, instance) {
|
|
7817
7825
|
abytes$1(out, undefined, 'output');
|
|
7826
|
+
// `outputLen` is a library-owned readonly number; the negated comparison keeps failing fast
|
|
7827
|
+
// when it is missing/NaN (comparisons with undefined/NaN are false) without an anumber() call.
|
|
7818
7828
|
const min = instance.outputLen;
|
|
7819
|
-
if (out.length
|
|
7820
|
-
throw new RangeError('
|
|
7829
|
+
if (!(out.length >= min)) {
|
|
7830
|
+
throw new RangeError('"output" expected length >= ' + min);
|
|
7821
7831
|
}
|
|
7822
|
-
|
|
7832
|
+
}
|
|
7833
|
+
/**
|
|
7834
|
+
* Asserts output is a sufficiently-sized, 4-byte-aligned byte array.
|
|
7835
|
+
* {@link aoutput} plus an {@link isAligned32} check, for `digestInto()` paths
|
|
7836
|
+
* that write through zero-allocation `u32` word views.
|
|
7837
|
+
* @param out - Output buffer to validate.
|
|
7838
|
+
* @param instance - Hash-like instance providing `outputLen`.
|
|
7839
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
7840
|
+
* @throws On wrong output buffer lengths. {@link RangeError}
|
|
7841
|
+
* @throws On wrong output buffer alignment. {@link Error}
|
|
7842
|
+
* @example
|
|
7843
|
+
* Verifies that a caller-provided output buffer is large enough and aligned.
|
|
7844
|
+
*
|
|
7845
|
+
* ```ts
|
|
7846
|
+
* aoutput32(new Uint8Array(16), { outputLen: 16 });
|
|
7847
|
+
* ```
|
|
7848
|
+
*/
|
|
7849
|
+
function aoutput32(out, instance) {
|
|
7850
|
+
aoutput$1(out, instance);
|
|
7851
|
+
if (!isAligned32(out))
|
|
7823
7852
|
throw new Error('invalid output, must be aligned');
|
|
7824
7853
|
}
|
|
7825
7854
|
/**
|
|
@@ -7898,10 +7927,12 @@ const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344])
|
|
|
7898
7927
|
* byteSwap(0x11223344);
|
|
7899
7928
|
* ```
|
|
7900
7929
|
*/
|
|
7901
|
-
|
|
7902
|
-
((word <<
|
|
7903
|
-
|
|
7904
|
-
|
|
7930
|
+
function byteSwap(word) {
|
|
7931
|
+
return (((word << 24) & 0xff000000) |
|
|
7932
|
+
((word << 8) & 0xff0000) |
|
|
7933
|
+
((word >>> 8) & 0xff00) |
|
|
7934
|
+
((word >>> 24) & 0xff));
|
|
7935
|
+
}
|
|
7905
7936
|
/**
|
|
7906
7937
|
* Normalizes one 32-bit word to the little-endian representation expected by cipher cores.
|
|
7907
7938
|
* @param n - Unsigned 32-bit word to normalize.
|
|
@@ -7927,11 +7958,12 @@ const swap8IfBE = isLE
|
|
|
7927
7958
|
* byteSwap32(new Uint32Array([0x11223344]));
|
|
7928
7959
|
* ```
|
|
7929
7960
|
*/
|
|
7930
|
-
|
|
7931
|
-
for (let i = 0; i < arr.length; i++)
|
|
7961
|
+
function byteSwap32(arr) {
|
|
7962
|
+
for (let i = 0; i < arr.length; i++) {
|
|
7932
7963
|
arr[i] = byteSwap(arr[i]);
|
|
7964
|
+
}
|
|
7933
7965
|
return arr;
|
|
7934
|
-
}
|
|
7966
|
+
}
|
|
7935
7967
|
/**
|
|
7936
7968
|
* Normalizes a Uint32Array view to the little-endian representation expected by cipher cores.
|
|
7937
7969
|
* @param u - Word view to normalize in place.
|
|
@@ -7959,6 +7991,8 @@ const swap32IfBE = isLE
|
|
|
7959
7991
|
* ```
|
|
7960
7992
|
*/
|
|
7961
7993
|
function equalBytes(a, b) {
|
|
7994
|
+
a = abytes$1(a);
|
|
7995
|
+
b = abytes$1(b);
|
|
7962
7996
|
if (a.length !== b.length)
|
|
7963
7997
|
return false;
|
|
7964
7998
|
let diff = 0;
|
|
@@ -7991,8 +8025,9 @@ function wrapMacConstructor(keyLen, macCons, fromMsg) {
|
|
|
7991
8025
|
* Wraps a cipher: validates args, ensures encrypt() can only be called once.
|
|
7992
8026
|
* Used internally by the exported cipher constructors.
|
|
7993
8027
|
* Output-buffer support is inferred from the wrapped `encrypt` / `decrypt`
|
|
7994
|
-
* arity (`fn.length === 2`),
|
|
7995
|
-
*
|
|
8028
|
+
* arity (`fn.length === 2`), so wrapped output-capable methods must use a normal
|
|
8029
|
+
* second parameter, not a default/rest parameter. AAD support is explicit in
|
|
8030
|
+
* `params.withAAD`; optional AAD starts after the nonce slot when one is present.
|
|
7996
8031
|
* @__NO_SIDE_EFFECTS__
|
|
7997
8032
|
* @param params - Static cipher metadata. See {@link CipherParams}.
|
|
7998
8033
|
* @param constructor - Cipher constructor.
|
|
@@ -8007,10 +8042,18 @@ const wrapCipher = (params, constructor) => {
|
|
|
8007
8042
|
const nonce = args[0];
|
|
8008
8043
|
abytes$1(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');
|
|
8009
8044
|
}
|
|
8010
|
-
//
|
|
8045
|
+
// Keep tag length available for decrypt-size checks after constructor validation.
|
|
8011
8046
|
const tagl = params.tagLength;
|
|
8012
|
-
|
|
8013
|
-
|
|
8047
|
+
const aadStart = params.nonceLength !== undefined ? 1 : 0;
|
|
8048
|
+
// No-AAD constructors otherwise silently ignore byte args meant as AAD.
|
|
8049
|
+
if (!params.withAAD) {
|
|
8050
|
+
for (let i = aadStart; i < args.length; i++)
|
|
8051
|
+
if (isBytes$1(args[i]))
|
|
8052
|
+
throw new Error('AAD not supported');
|
|
8053
|
+
}
|
|
8054
|
+
// Validate the first AAD slot early; rest-arg AAD constructors validate the tail themselves.
|
|
8055
|
+
if (params.withAAD && args[aadStart] !== undefined)
|
|
8056
|
+
abytes$1(args[aadStart], undefined, 'AAD');
|
|
8014
8057
|
const cipher = constructor(key, ...args);
|
|
8015
8058
|
const checkOutput = (fnLength, output) => {
|
|
8016
8059
|
if (output !== undefined) {
|
|
@@ -8025,15 +8068,16 @@ const wrapCipher = (params, constructor) => {
|
|
|
8025
8068
|
encrypt(data, output) {
|
|
8026
8069
|
if (called)
|
|
8027
8070
|
throw new Error('cannot encrypt() twice with same key + nonce');
|
|
8071
|
+
// Any encrypt attempt consumes the instance, even if validation rejects below.
|
|
8028
8072
|
called = true;
|
|
8029
|
-
abytes$1(data);
|
|
8073
|
+
abytes$1(data, undefined, 'data');
|
|
8030
8074
|
checkOutput(cipher.encrypt.length, output);
|
|
8031
8075
|
return cipher.encrypt(data, output);
|
|
8032
8076
|
},
|
|
8033
8077
|
decrypt(data, output) {
|
|
8034
|
-
abytes$1(data);
|
|
8078
|
+
abytes$1(data, undefined, 'data');
|
|
8035
8079
|
if (tagl && data.length < tagl)
|
|
8036
|
-
throw new Error('"ciphertext" expected length
|
|
8080
|
+
throw new Error('"ciphertext" expected length >= tagLength=' + tagl);
|
|
8037
8081
|
checkOutput(cipher.decrypt.length, output);
|
|
8038
8082
|
return cipher.decrypt(data, output);
|
|
8039
8083
|
},
|
|
@@ -8051,7 +8095,8 @@ const wrapCipher = (params, constructor) => {
|
|
|
8051
8095
|
* @param onlyAligned - Whether `out` must be 4-byte aligned.
|
|
8052
8096
|
* @returns Output buffer ready for writing.
|
|
8053
8097
|
* @throws On wrong argument types. {@link TypeError}
|
|
8054
|
-
* @throws If the provided output buffer has the wrong size
|
|
8098
|
+
* @throws If the provided output buffer has the wrong size. {@link RangeError}
|
|
8099
|
+
* @throws If the provided output buffer has the wrong alignment. {@link Error}
|
|
8055
8100
|
* @example
|
|
8056
8101
|
* Reuses a caller-provided output buffer when lengths match.
|
|
8057
8102
|
*
|
|
@@ -8063,17 +8108,16 @@ function getOutput(expectedLength, out, onlyAligned = true) {
|
|
|
8063
8108
|
if (out === undefined)
|
|
8064
8109
|
return new Uint8Array(expectedLength);
|
|
8065
8110
|
// Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object.
|
|
8066
|
-
abytes$1(out,
|
|
8067
|
-
if (out.length !== expectedLength)
|
|
8068
|
-
throw new Error('"output" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length);
|
|
8111
|
+
abytes$1(out, expectedLength, 'output');
|
|
8069
8112
|
if (onlyAligned && !isAligned32(out))
|
|
8070
8113
|
throw new Error('invalid output, must be aligned');
|
|
8071
8114
|
return out;
|
|
8072
8115
|
}
|
|
8073
8116
|
/**
|
|
8074
|
-
* Encodes data and AAD
|
|
8075
|
-
* @param dataLength - Data length
|
|
8076
|
-
*
|
|
8117
|
+
* Encodes data and AAD lengths into a 16-byte buffer.
|
|
8118
|
+
* @param dataLength - Data length. Units are caller-defined: GCM passes bit
|
|
8119
|
+
* lengths, ChaCha20-Poly1305 passes byte lengths — the helper writes the raw values.
|
|
8120
|
+
* @param aadLength - AAD length, same unit convention as `dataLength`.
|
|
8077
8121
|
* The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305
|
|
8078
8122
|
* conventions even though the helper parameter order is `(dataLength, aadLength)`.
|
|
8079
8123
|
* @param isLE - Whether to encode lengths as little-endian.
|
|
@@ -8315,7 +8359,7 @@ class GHASH {
|
|
|
8315
8359
|
aexists$1(this);
|
|
8316
8360
|
// `digestInto(out)` is the no-allocation fast path, so callers must pass a
|
|
8317
8361
|
// 32-bit-aligned buffer before we reinterpret it with `u32(out)`.
|
|
8318
|
-
|
|
8362
|
+
aoutput32(out, this);
|
|
8319
8363
|
this.finished = true;
|
|
8320
8364
|
// NIST SP 800-38D §6.4 returns the final 128-bit block Y_m.
|
|
8321
8365
|
// `digestInto()` follows the relaxed `aoutput()` contract, so only
|
|
@@ -8326,7 +8370,9 @@ class GHASH {
|
|
|
8326
8370
|
o32[1] = s1;
|
|
8327
8371
|
o32[2] = s2;
|
|
8328
8372
|
o32[3] = s3;
|
|
8329
|
-
|
|
8373
|
+
// Only the tag words need host-endian normalization; oversized output tails are caller-owned.
|
|
8374
|
+
if (!isLE)
|
|
8375
|
+
swap32IfBE(o32.subarray(0, BLOCK_SIZE$1 / 4));
|
|
8330
8376
|
}
|
|
8331
8377
|
digest() {
|
|
8332
8378
|
const res = new Uint8Array(BLOCK_SIZE$1);
|
|
@@ -8440,7 +8486,7 @@ const rotl32_8 = (n) => (n << 8) | (n >>> 24);
|
|
|
8440
8486
|
// so index is u16, instead of u8. This speeds up things, unexpectedly
|
|
8441
8487
|
function genTtable(sbox, fn) {
|
|
8442
8488
|
if (sbox.length !== 256)
|
|
8443
|
-
throw new Error('
|
|
8489
|
+
throw new Error('wrong sbox length');
|
|
8444
8490
|
const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));
|
|
8445
8491
|
const T1 = T0.map(rotl32_8);
|
|
8446
8492
|
const T2 = T1.map(rotl32_8);
|
|
@@ -8559,22 +8605,21 @@ function ctr32(xk, isLE, nonce, src, dst) {
|
|
|
8559
8605
|
// RFC 8452 AES-GCM-SIV increments the first 32 bits as a little-endian u32.
|
|
8560
8606
|
const ctrPos = isLE ? 0 : 12;
|
|
8561
8607
|
const srcLen = src.length;
|
|
8562
|
-
// Fill block (empty, ctr=0)
|
|
8563
8608
|
let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value
|
|
8564
|
-
let { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]));
|
|
8565
8609
|
// process blocks
|
|
8566
8610
|
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
|
8611
|
+
const { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]));
|
|
8567
8612
|
dst32[i + 0] = src32[i + 0] ^ swap8IfBE(s0);
|
|
8568
8613
|
dst32[i + 1] = src32[i + 1] ^ swap8IfBE(s1);
|
|
8569
8614
|
dst32[i + 2] = src32[i + 2] ^ swap8IfBE(s2);
|
|
8570
8615
|
dst32[i + 3] = src32[i + 3] ^ swap8IfBE(s3);
|
|
8571
8616
|
ctrNum = (ctrNum + 1) >>> 0; // u32 wrap
|
|
8572
8617
|
view.setUint32(ctrPos, ctrNum, isLE);
|
|
8573
|
-
({ s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3])));
|
|
8574
8618
|
}
|
|
8575
8619
|
// leftovers (less than a block)
|
|
8576
8620
|
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
|
8577
8621
|
if (start < srcLen) {
|
|
8622
|
+
const { s0, s1, s2, s3 } = encrypt(xk, swap8IfBE(c32[0]), swap8IfBE(c32[1]), swap8IfBE(c32[2]), swap8IfBE(c32[3]));
|
|
8578
8623
|
const b32 = new Uint32Array([s0, s1, s2, s3]);
|
|
8579
8624
|
swap32IfBE(b32);
|
|
8580
8625
|
const buf = u8$1(b32);
|
|
@@ -8623,11 +8668,12 @@ function computeTag(fn, isLE, key, data, AAD) {
|
|
|
8623
8668
|
* import { randomBytes } from '@noble/ciphers/utils.js';
|
|
8624
8669
|
* const key = randomBytes(16);
|
|
8625
8670
|
* const nonce = randomBytes(12);
|
|
8626
|
-
* const
|
|
8671
|
+
* const aad = new TextEncoder().encode('session metadata');
|
|
8672
|
+
* const cipher = gcm(key, nonce, aad);
|
|
8627
8673
|
* cipher.encrypt(new Uint8Array([1, 2, 3]));
|
|
8628
8674
|
* ```
|
|
8629
8675
|
*/
|
|
8630
|
-
const gcm = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true }, function aesgcm(key, nonce, AAD) {
|
|
8676
|
+
const gcm = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16, withAAD: true, varSizeNonce: true }, function aesgcm(key, nonce, AAD) {
|
|
8631
8677
|
// SP 800-38D lets implementations narrow supported IV lengths.
|
|
8632
8678
|
// This wrapper intentionally requires at least 8 bytes; OpenSSL accepts shorter IVs too.
|
|
8633
8679
|
// 12-byte nonces take the fast path; other allowed lengths use GHASH to derive J0.
|
|
@@ -8693,7 +8739,7 @@ const gcm = /* @__PURE__ */ wrapCipher({ blockSize: 16, nonceLength: 12, tagLeng
|
|
|
8693
8739
|
// tag before CTR so unauthenticated plaintext is never materialized.
|
|
8694
8740
|
if (!equalBytes(tag, passedTag)) {
|
|
8695
8741
|
clean$1(...toClean);
|
|
8696
|
-
throw new Error('aes
|
|
8742
|
+
throw new Error('aes-gcm: invalid tag');
|
|
8697
8743
|
}
|
|
8698
8744
|
const out = ctr32(xk, false, counter, data);
|
|
8699
8745
|
clean$1(...toClean);
|
|
@@ -8723,10 +8769,14 @@ function isBytes(a) {
|
|
|
8723
8769
|
'BYTES_PER_ELEMENT' in a &&
|
|
8724
8770
|
a.BYTES_PER_ELEMENT === 1));
|
|
8725
8771
|
}
|
|
8772
|
+
// Shared error-message prefix builder. Only called on throw paths, so assert
|
|
8773
|
+
// success paths never pay for the string concatenation.
|
|
8774
|
+
const atitle = (title) => (title ? `"${title}" ` : '');
|
|
8726
8775
|
/**
|
|
8727
8776
|
* Asserts something is a non-negative integer.
|
|
8728
8777
|
* @param n - number to validate
|
|
8729
8778
|
* @param title - label included in thrown errors
|
|
8779
|
+
* @returns The validated number.
|
|
8730
8780
|
* @throws On wrong argument types. {@link TypeError}
|
|
8731
8781
|
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
8732
8782
|
* @example
|
|
@@ -8736,14 +8786,11 @@ function isBytes(a) {
|
|
|
8736
8786
|
* ```
|
|
8737
8787
|
*/
|
|
8738
8788
|
function anumber(n, title = '') {
|
|
8739
|
-
if (typeof n !== 'number')
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
const prefix = title && `"${title}" `;
|
|
8745
|
-
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
8746
|
-
}
|
|
8789
|
+
if (typeof n !== 'number')
|
|
8790
|
+
throw new TypeError(atitle(title) + 'expected number, got ' + typeof n);
|
|
8791
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
8792
|
+
throw new RangeError(atitle(title) + 'expected integer >= 0, got ' + n);
|
|
8793
|
+
return n;
|
|
8747
8794
|
}
|
|
8748
8795
|
/**
|
|
8749
8796
|
* Asserts something is Uint8Array.
|
|
@@ -8760,19 +8807,20 @@ function anumber(n, title = '') {
|
|
|
8760
8807
|
* ```
|
|
8761
8808
|
*/
|
|
8762
8809
|
function abytes(value, length, title = '') {
|
|
8810
|
+
// Success path first: this runs at the start of every update() / digestInto(), and the
|
|
8811
|
+
// common `abytes(data)` form must not pay for length handling it does not use.
|
|
8812
|
+
if (isBytes(value) && (length === undefined || value.length === length))
|
|
8813
|
+
return value;
|
|
8814
|
+
// Error path: recompute freely to build the exact message.
|
|
8815
|
+
if (length !== undefined)
|
|
8816
|
+
anumber(length, 'length');
|
|
8763
8817
|
const bytes = isBytes(value);
|
|
8764
|
-
const
|
|
8765
|
-
const
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
8771
|
-
if (!bytes)
|
|
8772
|
-
throw new TypeError(message);
|
|
8773
|
-
throw new RangeError(message);
|
|
8774
|
-
}
|
|
8775
|
-
return value;
|
|
8818
|
+
const ofLen = length !== undefined ? ` of length ${length}` : '';
|
|
8819
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
8820
|
+
const message = atitle(title) + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
8821
|
+
if (!bytes)
|
|
8822
|
+
throw new TypeError(message);
|
|
8823
|
+
throw new RangeError(message);
|
|
8776
8824
|
}
|
|
8777
8825
|
/**
|
|
8778
8826
|
* Asserts something is a wrapped hash constructor.
|
|
@@ -8790,16 +8838,28 @@ function abytes(value, length, title = '') {
|
|
|
8790
8838
|
*/
|
|
8791
8839
|
function ahash(h) {
|
|
8792
8840
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
|
8793
|
-
throw new TypeError('
|
|
8841
|
+
throw new TypeError('expected hash wrapped by utils.createHasher');
|
|
8794
8842
|
anumber(h.outputLen);
|
|
8795
8843
|
anumber(h.blockLen);
|
|
8796
8844
|
// HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass
|
|
8797
8845
|
// validation and can produce empty outputs instead of failing fast.
|
|
8798
|
-
if (h.outputLen < 1)
|
|
8799
|
-
throw new Error('
|
|
8800
|
-
if (h.blockLen < 1)
|
|
8801
|
-
throw new Error('"blockLen" must be >= 1');
|
|
8846
|
+
if (h.outputLen < 1 || h.blockLen < 1)
|
|
8847
|
+
throw new Error('hash blockLen / outputLen must be >= 1');
|
|
8802
8848
|
}
|
|
8849
|
+
const aobject = (value, label) => {
|
|
8850
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
8851
|
+
throw new TypeError((label === 'object' ? '' : `"${label}" `) + 'expected object, got type=' + typeof value);
|
|
8852
|
+
};
|
|
8853
|
+
const aopts = (value, label) => {
|
|
8854
|
+
aobject(value, label);
|
|
8855
|
+
const proto = Object.getPrototypeOf(value);
|
|
8856
|
+
if (proto !== Object.prototype && proto !== null)
|
|
8857
|
+
throw new TypeError(`"${label}" expected plain object`);
|
|
8858
|
+
// Object.assign() treats an own "__proto__" source key as a write to the target's legacy
|
|
8859
|
+
// prototype setter. Reject it before merging so inherited option values cannot be injected.
|
|
8860
|
+
if (Object.hasOwn(value, '__proto__'))
|
|
8861
|
+
throw new TypeError(`"${label}.__proto__" is not allowed`);
|
|
8862
|
+
};
|
|
8803
8863
|
/**
|
|
8804
8864
|
* Asserts a hash instance has not been destroyed or finished.
|
|
8805
8865
|
* @param instance - hash instance to validate
|
|
@@ -8815,10 +8875,12 @@ function ahash(h) {
|
|
|
8815
8875
|
* ```
|
|
8816
8876
|
*/
|
|
8817
8877
|
function aexists(instance, checkFinished = true) {
|
|
8878
|
+
// Runs on every update()/digestInto(); the flags are library-owned booleans, so only their
|
|
8879
|
+
// truthiness is checked - re-validating their type per call was pure hot-path overhead.
|
|
8818
8880
|
if (instance.destroyed)
|
|
8819
|
-
throw new Error('
|
|
8881
|
+
throw new Error('hash was destroyed');
|
|
8820
8882
|
if (checkFinished && instance.finished)
|
|
8821
|
-
throw new Error('
|
|
8883
|
+
throw new Error('digest() was already called');
|
|
8822
8884
|
}
|
|
8823
8885
|
/**
|
|
8824
8886
|
* Asserts output is a sufficiently-sized byte array.
|
|
@@ -8837,10 +8899,12 @@ function aexists(instance, checkFinished = true) {
|
|
|
8837
8899
|
* ```
|
|
8838
8900
|
*/
|
|
8839
8901
|
function aoutput(out, instance) {
|
|
8840
|
-
abytes(out, undefined, '
|
|
8902
|
+
abytes(out, undefined, 'output');
|
|
8903
|
+
// `outputLen` is a library-owned readonly number; the negated comparison keeps failing fast
|
|
8904
|
+
// when it is missing/NaN (comparisons with undefined/NaN are false) without an anumber() call.
|
|
8841
8905
|
const min = instance.outputLen;
|
|
8842
|
-
if (out.length
|
|
8843
|
-
throw new RangeError('"
|
|
8906
|
+
if (!(out.length >= min)) {
|
|
8907
|
+
throw new RangeError('"output" expected length >= ' + min);
|
|
8844
8908
|
}
|
|
8845
8909
|
}
|
|
8846
8910
|
/**
|
|
@@ -8884,6 +8948,28 @@ function createView(arr) {
|
|
|
8884
8948
|
function rotr(word, shift) {
|
|
8885
8949
|
return (word << (32 - shift)) | (word >>> shift);
|
|
8886
8950
|
}
|
|
8951
|
+
/**
|
|
8952
|
+
* Merges default options and passed options.
|
|
8953
|
+
* @param defaults - base option object
|
|
8954
|
+
* @param opts - user overrides
|
|
8955
|
+
* @param title - label included in thrown override errors
|
|
8956
|
+
* @returns Fresh merged option object with a null prototype.
|
|
8957
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
8958
|
+
* @example
|
|
8959
|
+
* Merge user overrides onto default options.
|
|
8960
|
+
* ```ts
|
|
8961
|
+
* checkOpts({ dkLen: 32 }, { asyncTick: 10 });
|
|
8962
|
+
* ```
|
|
8963
|
+
*/
|
|
8964
|
+
function checkOpts(defaults, opts, title = 'opts') {
|
|
8965
|
+
aopts(defaults, 'defaults');
|
|
8966
|
+
if (opts !== undefined)
|
|
8967
|
+
aopts(opts, title);
|
|
8968
|
+
// Callers read optional fields directly, so omitted values must not fall through to ambient
|
|
8969
|
+
// Object.prototype pollution (for example a forged `dkLen` changing SHAKE's default output).
|
|
8970
|
+
const merged = Object.assign(Object.create(null), defaults, opts);
|
|
8971
|
+
return merged;
|
|
8972
|
+
}
|
|
8887
8973
|
/**
|
|
8888
8974
|
* Creates a callable hash function from a stateful class constructor.
|
|
8889
8975
|
* @param hashCons - hash constructor or factory
|
|
@@ -8892,6 +8978,7 @@ function rotr(word, shift) {
|
|
|
8892
8978
|
* Wrapper construction eagerly calls `hashCons(undefined)` once to read
|
|
8893
8979
|
* `outputLen` / `blockLen`, so constructor side effects happen at module
|
|
8894
8980
|
* init time.
|
|
8981
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
8895
8982
|
* @example
|
|
8896
8983
|
* Wrap a stateful hash constructor into a callable helper.
|
|
8897
8984
|
* ```ts
|
|
@@ -8902,6 +8989,9 @@ function rotr(word, shift) {
|
|
|
8902
8989
|
* ```
|
|
8903
8990
|
*/
|
|
8904
8991
|
function createHasher(hashCons, info = {}) {
|
|
8992
|
+
if (typeof hashCons !== 'function')
|
|
8993
|
+
throw new TypeError('"hashCons" expected function, got type=' + typeof hashCons);
|
|
8994
|
+
info = checkOpts({}, info, 'info');
|
|
8905
8995
|
const hashC = (msg, opts) => hashCons(opts)
|
|
8906
8996
|
.update(msg)
|
|
8907
8997
|
.digest();
|
|
@@ -8953,7 +9043,7 @@ class _HMAC {
|
|
|
8953
9043
|
abytes(key, undefined, 'key');
|
|
8954
9044
|
this.iHash = hash.create();
|
|
8955
9045
|
if (typeof this.iHash.update !== 'function')
|
|
8956
|
-
throw new Error('
|
|
9046
|
+
throw new Error('expected Hash instance');
|
|
8957
9047
|
this.blockLen = this.iHash.blockLen;
|
|
8958
9048
|
this.outputLen = this.iHash.outputLen;
|
|
8959
9049
|
const blockLen = this.blockLen;
|
|
@@ -8998,12 +9088,13 @@ class _HMAC {
|
|
|
8998
9088
|
// Create new instance without calling constructor since the key
|
|
8999
9089
|
// is already in state and we don't know it.
|
|
9000
9090
|
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
9001
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
9091
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen, canXOF } = this;
|
|
9002
9092
|
to = to;
|
|
9003
9093
|
to.finished = finished;
|
|
9004
9094
|
to.destroyed = destroyed;
|
|
9005
9095
|
to.blockLen = blockLen;
|
|
9006
9096
|
to.outputLen = outputLen;
|
|
9097
|
+
to.canXOF = canXOF;
|
|
9007
9098
|
to.oHash = oHash._cloneInto(to.oHash);
|
|
9008
9099
|
to.iHash = iHash._cloneInto(to.iHash);
|
|
9009
9100
|
return to;
|
|
@@ -9023,6 +9114,20 @@ const hmac = /* @__PURE__ */ (() => {
|
|
|
9023
9114
|
return hmac_;
|
|
9024
9115
|
})();
|
|
9025
9116
|
|
|
9117
|
+
// Split a JS number into u32 halves without a BigInt allocation. Exact only for integers
|
|
9118
|
+
// `0 <= n < 2**53`; callers use it on byte / bit counters, which JS length math caps far below
|
|
9119
|
+
// that (an ArrayBuffer cannot exceed 2**53 - 1 bytes).
|
|
9120
|
+
const fromNumH = (n) => (n / 2 ** 32) | 0;
|
|
9121
|
+
const fromNumL = (n) => n >>> 0;
|
|
9122
|
+
// Drop-in replacement for `view.setBigUint64(byteOffset, BigInt(n), isLE)` without the per-call
|
|
9123
|
+
// BigInt allocation. Same `n < 2**53` precondition as `fromNumH`/`fromNumL`.
|
|
9124
|
+
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
9125
|
+
const h = fromNumH(n);
|
|
9126
|
+
const l = fromNumL(n);
|
|
9127
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
9128
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
9129
|
+
}
|
|
9130
|
+
|
|
9026
9131
|
/**
|
|
9027
9132
|
* Internal Merkle-Damgard hash utils.
|
|
9028
9133
|
* @module
|
|
@@ -9105,6 +9210,7 @@ class HashMD {
|
|
|
9105
9210
|
abytes(data);
|
|
9106
9211
|
const { view, buffer, blockLen } = this;
|
|
9107
9212
|
const len = data.length;
|
|
9213
|
+
let processed = false;
|
|
9108
9214
|
for (let pos = 0; pos < len;) {
|
|
9109
9215
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
9110
9216
|
// Fast path only when there is no buffered partial block: `take === blockLen` implies
|
|
@@ -9113,18 +9219,25 @@ class HashMD {
|
|
|
9113
9219
|
const dataView = createView(data);
|
|
9114
9220
|
for (; blockLen <= len - pos; pos += blockLen)
|
|
9115
9221
|
this.process(dataView, pos);
|
|
9222
|
+
processed = true;
|
|
9116
9223
|
continue;
|
|
9117
9224
|
}
|
|
9118
|
-
|
|
9225
|
+
// When the whole input is buffered in one go (common for short messages), passing `data`
|
|
9226
|
+
// directly avoids allocating a subarray view.
|
|
9227
|
+
buffer.set(pos === 0 && take === len ? data : data.subarray(pos, pos + take), this.pos);
|
|
9119
9228
|
this.pos += take;
|
|
9120
9229
|
pos += take;
|
|
9121
9230
|
if (this.pos === blockLen) {
|
|
9122
9231
|
this.process(view, 0);
|
|
9123
9232
|
this.pos = 0;
|
|
9233
|
+
processed = true;
|
|
9124
9234
|
}
|
|
9125
9235
|
}
|
|
9126
9236
|
this.length += data.length;
|
|
9127
|
-
|
|
9237
|
+
// Shared schedule buffers only pick up input-derived words inside process(); if everything
|
|
9238
|
+
// was buffered without processing, there is nothing to zero.
|
|
9239
|
+
if (processed)
|
|
9240
|
+
this.roundClean();
|
|
9128
9241
|
return this;
|
|
9129
9242
|
}
|
|
9130
9243
|
digestInto(out) {
|
|
@@ -9136,32 +9249,33 @@ class HashMD {
|
|
|
9136
9249
|
// was previously not allocated here. But it won't change performance.
|
|
9137
9250
|
const { buffer, view, blockLen, isLE } = this;
|
|
9138
9251
|
let { pos } = this;
|
|
9139
|
-
// append the bit '1' to the message
|
|
9252
|
+
// append the bit '1' to the message, then zero-pad the rest of the block
|
|
9140
9253
|
buffer[pos++] = 0b10000000;
|
|
9141
|
-
|
|
9254
|
+
buffer.fill(0, pos);
|
|
9142
9255
|
// we have less than padOffset left in buffer, so we cannot put length in
|
|
9143
9256
|
// current block, need process it and pad again
|
|
9144
9257
|
if (this.padOffset > blockLen - pos) {
|
|
9145
9258
|
this.process(view, 0);
|
|
9146
|
-
|
|
9259
|
+
buffer.fill(0);
|
|
9147
9260
|
}
|
|
9148
|
-
// Pad until full block byte with zeros
|
|
9149
|
-
for (let i = pos; i < blockLen; i++)
|
|
9150
|
-
buffer[i] = 0;
|
|
9151
9261
|
// `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from
|
|
9152
9262
|
// the padding fill above, and JS will overflow before user input can make that half non-zero.
|
|
9153
|
-
// So we only need to write the low 64 bits here
|
|
9154
|
-
|
|
9263
|
+
// So we only need to write the low 64 bits here (`length * 8` only scales the exponent of an
|
|
9264
|
+
// integer below 2**53, so the split inside the helper stays exact).
|
|
9265
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE);
|
|
9155
9266
|
this.process(view, 0);
|
|
9156
|
-
|
|
9267
|
+
// The final block above is processed outside update(), so the shared message-schedule
|
|
9268
|
+
// buffers (e.g. SHA256_W) would otherwise retain input-derived words after digest().
|
|
9269
|
+
this.roundClean();
|
|
9270
|
+
// digest() passes our own `buffer` as `out`; reuse its cached view instead of allocating one.
|
|
9271
|
+
const oview = out === buffer ? view : createView(out);
|
|
9157
9272
|
const len = this.outputLen;
|
|
9158
9273
|
// NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT
|
|
9159
|
-
if (len % 4)
|
|
9160
|
-
throw new Error('_sha2: outputLen must be aligned to 32bit');
|
|
9161
9274
|
const outLen = len / 4;
|
|
9162
9275
|
const state = this.get();
|
|
9163
|
-
|
|
9164
|
-
|
|
9276
|
+
// Subclass-misconfiguration invariant: outputLen must be 32-bit aligned and fit the state.
|
|
9277
|
+
if (len % 4 || outLen > state.length)
|
|
9278
|
+
throw new Error('invalid outputLen');
|
|
9165
9279
|
for (let i = 0; i < outLen; i++)
|
|
9166
9280
|
oview.setUint32(4 * i, state[i], isLE);
|
|
9167
9281
|
}
|
|
@@ -9174,18 +9288,16 @@ class HashMD {
|
|
|
9174
9288
|
this.destroy();
|
|
9175
9289
|
return res;
|
|
9176
9290
|
}
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
to.set(...this.get());
|
|
9180
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
9291
|
+
_cloneIntoMeta(to) {
|
|
9292
|
+
const { buffer, length, finished, destroyed, pos } = this;
|
|
9181
9293
|
to.destroyed = destroyed;
|
|
9182
9294
|
to.finished = finished;
|
|
9183
9295
|
to.length = length;
|
|
9184
9296
|
to.pos = pos;
|
|
9185
9297
|
// Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and
|
|
9186
9298
|
// later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.
|
|
9187
|
-
if (
|
|
9188
|
-
to.buffer.set(buffer);
|
|
9299
|
+
if (pos)
|
|
9300
|
+
to.buffer.set(buffer); // Avoid a hot modulo guard.
|
|
9189
9301
|
return to;
|
|
9190
9302
|
}
|
|
9191
9303
|
clone() {
|
|
@@ -9229,8 +9341,28 @@ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
|
9229
9341
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
9230
9342
|
/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */
|
|
9231
9343
|
class SHA2_32B extends HashMD {
|
|
9232
|
-
|
|
9344
|
+
// We cannot use array here since array allows indexing by variable
|
|
9345
|
+
// which means optimizer/compiler cannot use registers.
|
|
9346
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
9347
|
+
// V8's field representation and makes sha256 3x slower (measured).
|
|
9348
|
+
A = 0;
|
|
9349
|
+
B = 0;
|
|
9350
|
+
C = 0;
|
|
9351
|
+
D = 0;
|
|
9352
|
+
E = 0;
|
|
9353
|
+
F = 0;
|
|
9354
|
+
G = 0;
|
|
9355
|
+
H = 0;
|
|
9356
|
+
constructor(outputLen, IV) {
|
|
9233
9357
|
super(64, outputLen, 8, false);
|
|
9358
|
+
this.A = IV[0] | 0;
|
|
9359
|
+
this.B = IV[1] | 0;
|
|
9360
|
+
this.C = IV[2] | 0;
|
|
9361
|
+
this.D = IV[3] | 0;
|
|
9362
|
+
this.E = IV[4] | 0;
|
|
9363
|
+
this.F = IV[5] | 0;
|
|
9364
|
+
this.G = IV[6] | 0;
|
|
9365
|
+
this.H = IV[7] | 0;
|
|
9234
9366
|
}
|
|
9235
9367
|
get() {
|
|
9236
9368
|
const { A, B, C, D, E, F, G, H } = this;
|
|
@@ -9247,6 +9379,10 @@ class SHA2_32B extends HashMD {
|
|
|
9247
9379
|
this.G = G | 0;
|
|
9248
9380
|
this.H = H | 0;
|
|
9249
9381
|
}
|
|
9382
|
+
_cloneInto(to) {
|
|
9383
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
9384
|
+
return this._cloneIntoMeta(to);
|
|
9385
|
+
}
|
|
9250
9386
|
process(view, offset) {
|
|
9251
9387
|
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
|
|
9252
9388
|
for (let i = 0; i < 16; i++, offset += 4)
|
|
@@ -9298,18 +9434,8 @@ class SHA2_32B extends HashMD {
|
|
|
9298
9434
|
}
|
|
9299
9435
|
/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */
|
|
9300
9436
|
class _SHA256 extends SHA2_32B {
|
|
9301
|
-
// We cannot use array here since array allows indexing by variable
|
|
9302
|
-
// which means optimizer/compiler cannot use registers.
|
|
9303
|
-
A = SHA256_IV[0] | 0;
|
|
9304
|
-
B = SHA256_IV[1] | 0;
|
|
9305
|
-
C = SHA256_IV[2] | 0;
|
|
9306
|
-
D = SHA256_IV[3] | 0;
|
|
9307
|
-
E = SHA256_IV[4] | 0;
|
|
9308
|
-
F = SHA256_IV[5] | 0;
|
|
9309
|
-
G = SHA256_IV[6] | 0;
|
|
9310
|
-
H = SHA256_IV[7] | 0;
|
|
9311
9437
|
constructor() {
|
|
9312
|
-
super(32);
|
|
9438
|
+
super(32, SHA256_IV);
|
|
9313
9439
|
}
|
|
9314
9440
|
}
|
|
9315
9441
|
/**
|
|
@@ -9320,6 +9446,7 @@ class _SHA256 extends SHA2_32B {
|
|
|
9320
9446
|
* - Each sha256 hash is executing 2^18 bit operations.
|
|
9321
9447
|
* - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.
|
|
9322
9448
|
* @param msg - message bytes to hash
|
|
9449
|
+
* @param opts - Reserved hash options.
|
|
9323
9450
|
* @returns Digest bytes.
|
|
9324
9451
|
* @example
|
|
9325
9452
|
* Hash a message with SHA2-256.
|
|
@@ -9846,8 +9973,9 @@ function createTileProtocol(cipher, fetchImpl = fetch) {
|
|
|
9846
9973
|
...(params.headers ? { headers: params.headers } : {}),
|
|
9847
9974
|
...(params.credentials ? { credentials: params.credentials } : {}),
|
|
9848
9975
|
});
|
|
9849
|
-
if (!response.ok)
|
|
9850
|
-
throw new Error(`tile ${response.status}`);
|
|
9976
|
+
if (!response.ok) {
|
|
9977
|
+
throw Object.assign(new Error(`tile ${response.status}`), { status: response.status, url });
|
|
9978
|
+
}
|
|
9851
9979
|
const envelope = await response.arrayBuffer();
|
|
9852
9980
|
signal.throwIfAborted();
|
|
9853
9981
|
const data = envelope.byteLength ? await cipher.decrypt(url, envelope, signal) : new ArrayBuffer(0);
|
|
@@ -9923,6 +10051,143 @@ function watchAMMVersion(map, fetchImpl = fetch, intervalMs = 60000) {
|
|
|
9923
10051
|
return stop;
|
|
9924
10052
|
}
|
|
9925
10053
|
|
|
10054
|
+
function tileIdentity(template) {
|
|
10055
|
+
const http = template.replace(/^kunyu:\/\//, "");
|
|
10056
|
+
const match = /^(https?:\/\/[^?#]+)\/tiles\/(?:e\/)?(\d{6})\//.exec(http);
|
|
10057
|
+
return match ? { prefix: match[1], period: match[2] } : undefined;
|
|
10058
|
+
}
|
|
10059
|
+
function watchNavDataVersion(map, fetchImpl = fetch, intervalMs = 60000) {
|
|
10060
|
+
let stopped = false;
|
|
10061
|
+
let pending;
|
|
10062
|
+
let observedSource;
|
|
10063
|
+
let observedSignature = "";
|
|
10064
|
+
let lastErrorRefresh = -Infinity;
|
|
10065
|
+
function state() {
|
|
10066
|
+
const source = map.getSource("navdata");
|
|
10067
|
+
const definition = map.getStyle()?.sources.navdata;
|
|
10068
|
+
const tiles = definition?.tiles;
|
|
10069
|
+
const identity = tiles?.[0] && tileIdentity(tiles[0]);
|
|
10070
|
+
if (!source?.setTiles || !tiles?.length || !identity)
|
|
10071
|
+
return undefined;
|
|
10072
|
+
if (!tiles.every(tile => {
|
|
10073
|
+
const other = tileIdentity(tile);
|
|
10074
|
+
return !!other && other.period === identity.period && other.prefix === identity.prefix;
|
|
10075
|
+
}))
|
|
10076
|
+
return undefined;
|
|
10077
|
+
return { source, tiles: [...tiles], signature: JSON.stringify(tiles), ...identity };
|
|
10078
|
+
}
|
|
10079
|
+
function refresh() {
|
|
10080
|
+
if (stopped)
|
|
10081
|
+
return Promise.resolve();
|
|
10082
|
+
const current = state();
|
|
10083
|
+
if (!current) {
|
|
10084
|
+
pending?.controller.abort();
|
|
10085
|
+
return Promise.resolve();
|
|
10086
|
+
}
|
|
10087
|
+
if (pending?.source === current.source && pending.signature === current.signature && !pending.controller.signal.aborted)
|
|
10088
|
+
return pending.promise;
|
|
10089
|
+
pending?.controller.abort();
|
|
10090
|
+
observedSource = current.source;
|
|
10091
|
+
observedSignature = current.signature;
|
|
10092
|
+
const controller = new AbortController();
|
|
10093
|
+
const job = { controller, source: current.source, signature: current.signature, promise: Promise.resolve() };
|
|
10094
|
+
pending = job;
|
|
10095
|
+
job.promise = Promise.resolve().then(async () => {
|
|
10096
|
+
if (stopped || controller.signal.aborted) {
|
|
10097
|
+
if (pending === job)
|
|
10098
|
+
pending = undefined;
|
|
10099
|
+
return;
|
|
10100
|
+
}
|
|
10101
|
+
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
10102
|
+
try {
|
|
10103
|
+
const response = await fetchImpl(`${current.prefix}/navdata/manifest?period=${current.period}`, {
|
|
10104
|
+
cache: "no-store", signal: controller.signal,
|
|
10105
|
+
});
|
|
10106
|
+
if (!response.ok)
|
|
10107
|
+
return;
|
|
10108
|
+
const manifest = await response.json();
|
|
10109
|
+
const latest = state();
|
|
10110
|
+
if (stopped || controller.signal.aborted || latest?.source !== current.source || latest.signature !== current.signature)
|
|
10111
|
+
return;
|
|
10112
|
+
if (manifest?.available !== true || manifest.period !== current.period || manifest.schemaVersion !== "1" ||
|
|
10113
|
+
typeof manifest.artifactVersion !== "string" || !manifest.artifactVersion)
|
|
10114
|
+
return;
|
|
10115
|
+
const next = current.tiles.map(tile => {
|
|
10116
|
+
const hashAt = tile.indexOf("#");
|
|
10117
|
+
const hash = hashAt < 0 ? "" : tile.slice(hashAt);
|
|
10118
|
+
const base = hashAt < 0 ? tile : tile.slice(0, hashAt);
|
|
10119
|
+
const queryAt = base.indexOf("?");
|
|
10120
|
+
const path = queryAt < 0 ? base : base.slice(0, queryAt);
|
|
10121
|
+
const query = new URLSearchParams(queryAt < 0 ? "" : base.slice(queryAt + 1));
|
|
10122
|
+
query.set("v", manifest.artifactVersion);
|
|
10123
|
+
return `${path}?${query.toString()}${hash}`;
|
|
10124
|
+
});
|
|
10125
|
+
const signature = JSON.stringify(next);
|
|
10126
|
+
if (signature === current.signature)
|
|
10127
|
+
return;
|
|
10128
|
+
observedSource = current.source;
|
|
10129
|
+
observedSignature = signature;
|
|
10130
|
+
current.source.setTiles(next);
|
|
10131
|
+
}
|
|
10132
|
+
catch {
|
|
10133
|
+
}
|
|
10134
|
+
finally {
|
|
10135
|
+
clearTimeout(timeout);
|
|
10136
|
+
if (pending === job)
|
|
10137
|
+
pending = undefined;
|
|
10138
|
+
}
|
|
10139
|
+
});
|
|
10140
|
+
return job.promise;
|
|
10141
|
+
}
|
|
10142
|
+
function styleChanged() {
|
|
10143
|
+
if (stopped)
|
|
10144
|
+
return;
|
|
10145
|
+
const current = state();
|
|
10146
|
+
if (!current) {
|
|
10147
|
+
pending?.controller.abort();
|
|
10148
|
+
observedSource = undefined;
|
|
10149
|
+
observedSignature = "";
|
|
10150
|
+
return;
|
|
10151
|
+
}
|
|
10152
|
+
if (current.source !== observedSource || current.signature !== observedSignature)
|
|
10153
|
+
void refresh();
|
|
10154
|
+
}
|
|
10155
|
+
function tileError(event) {
|
|
10156
|
+
const error = event?.error;
|
|
10157
|
+
if (stopped || !(error?.status === 410 || /^tile 410(?:\s|$)/.test(error?.message ?? "")))
|
|
10158
|
+
return;
|
|
10159
|
+
if (event.sourceId && event.sourceId !== "navdata")
|
|
10160
|
+
return;
|
|
10161
|
+
const current = state();
|
|
10162
|
+
if (!current)
|
|
10163
|
+
return;
|
|
10164
|
+
const failed = typeof error.url === "string" ? tileIdentity(error.url) : undefined;
|
|
10165
|
+
if (failed ? failed.prefix !== current.prefix || failed.period !== current.period : event.sourceId !== "navdata")
|
|
10166
|
+
return;
|
|
10167
|
+
const now = Date.now();
|
|
10168
|
+
if (now - lastErrorRefresh < 2000)
|
|
10169
|
+
return;
|
|
10170
|
+
lastErrorRefresh = now;
|
|
10171
|
+
void refresh();
|
|
10172
|
+
}
|
|
10173
|
+
const timer = setInterval(() => { void refresh(); }, intervalMs);
|
|
10174
|
+
function stop() {
|
|
10175
|
+
if (stopped)
|
|
10176
|
+
return;
|
|
10177
|
+
stopped = true;
|
|
10178
|
+
clearInterval(timer);
|
|
10179
|
+
pending?.controller.abort();
|
|
10180
|
+
map.off("remove", stop);
|
|
10181
|
+
map.off("error", tileError);
|
|
10182
|
+
map.off("styledata", styleChanged);
|
|
10183
|
+
}
|
|
10184
|
+
map.on("remove", stop);
|
|
10185
|
+
map.on("error", tileError);
|
|
10186
|
+
map.on("styledata", styleChanged);
|
|
10187
|
+
void refresh();
|
|
10188
|
+
return { refresh, stop };
|
|
10189
|
+
}
|
|
10190
|
+
|
|
9926
10191
|
// ICAO aviation chart layer styles — token-driven multi-theme.
|
|
9927
10192
|
//
|
|
9928
10193
|
// 单一 buildLayers(T):图层结构只写一份(以 light 为准);凡随主题变化的值
|
|
@@ -10267,10 +10532,10 @@ function buildLayers(themeId = 'light') {
|
|
|
10267
10532
|
{
|
|
10268
10533
|
id: 'airspace_label_center_layer', type: 'symbol', source: sourceId, 'source-layer': 'fir-centroid',
|
|
10269
10534
|
minzoom: 3,
|
|
10270
|
-
|
|
10535
|
+
maxzoom: 7,
|
|
10271
10536
|
layout: {
|
|
10272
10537
|
'text-field': '{CODE_ID}',
|
|
10273
|
-
'text-font':
|
|
10538
|
+
'text-font': ['Frutiger Regular'],
|
|
10274
10539
|
'symbol-placement': 'point',
|
|
10275
10540
|
'text-max-width': 8,
|
|
10276
10541
|
'symbol-sort-key': ['*', -1, ['get', 'SIZE']],
|
|
@@ -10287,11 +10552,11 @@ function buildLayers(themeId = 'light') {
|
|
|
10287
10552
|
["linear"],
|
|
10288
10553
|
["sqrt", ["get", "SIZE"]],
|
|
10289
10554
|
100, 9,
|
|
10290
|
-
316,
|
|
10291
|
-
707,
|
|
10292
|
-
1000,
|
|
10293
|
-
1414,
|
|
10294
|
-
2236,
|
|
10555
|
+
316, 10,
|
|
10556
|
+
707, 12,
|
|
10557
|
+
1000, 13,
|
|
10558
|
+
1414, 14,
|
|
10559
|
+
2236, 16
|
|
10295
10560
|
],
|
|
10296
10561
|
|
|
10297
10562
|
// Z4:区域视角
|
|
@@ -10300,12 +10565,12 @@ function buildLayers(themeId = 'light') {
|
|
|
10300
10565
|
"interpolate",
|
|
10301
10566
|
["linear"],
|
|
10302
10567
|
["sqrt", ["get", "SIZE"]],
|
|
10303
|
-
100,
|
|
10304
|
-
316,
|
|
10305
|
-
707,
|
|
10306
|
-
1000,
|
|
10307
|
-
1414,
|
|
10308
|
-
2236,
|
|
10568
|
+
100, 9,
|
|
10569
|
+
316, 11,
|
|
10570
|
+
707, 13,
|
|
10571
|
+
1000, 15,
|
|
10572
|
+
1414, 16,
|
|
10573
|
+
2236, 18
|
|
10309
10574
|
],
|
|
10310
10575
|
|
|
10311
10576
|
// Z6:FIR 最后显示层级
|
|
@@ -10314,19 +10579,19 @@ function buildLayers(themeId = 'light') {
|
|
|
10314
10579
|
"interpolate",
|
|
10315
10580
|
["linear"],
|
|
10316
10581
|
["sqrt", ["get", "SIZE"]],
|
|
10317
|
-
100,
|
|
10318
|
-
316,
|
|
10319
|
-
707,
|
|
10320
|
-
1000,
|
|
10321
|
-
1414,
|
|
10322
|
-
2236,
|
|
10582
|
+
100, 10,
|
|
10583
|
+
316, 12,
|
|
10584
|
+
707, 13,
|
|
10585
|
+
1000, 15,
|
|
10586
|
+
1414, 16,
|
|
10587
|
+
2236, 18
|
|
10323
10588
|
]
|
|
10324
|
-
]
|
|
10589
|
+
],
|
|
10325
10590
|
},
|
|
10326
10591
|
paint: {
|
|
10327
10592
|
'text-color': T.airspaceStroke,
|
|
10328
10593
|
...T.centerHalo,
|
|
10329
|
-
'text-opacity': ['interpolate', ['linear'], ['zoom'], 3, 0.
|
|
10594
|
+
'text-opacity': ['interpolate', ['linear'], ['zoom'], 3, 0.5, 8, 0.5, 12, 0.5],
|
|
10330
10595
|
},
|
|
10331
10596
|
},
|
|
10332
10597
|
{
|
|
@@ -10635,7 +10900,8 @@ function buildLayers(themeId = 'light') {
|
|
|
10635
10900
|
true // zoom >5,全部显示
|
|
10636
10901
|
],
|
|
10637
10902
|
layout: {
|
|
10638
|
-
"icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-
|
|
10903
|
+
"icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-milext-circle", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MILEXT"], "airport-mil-circle", "airport-civ-cirlce"],
|
|
10904
|
+
// "icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-mil", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MILEXT"], "airport-milext", "airport-civ"],
|
|
10639
10905
|
"symbol-z-order": "viewport-y",
|
|
10640
10906
|
"text-letter-spacing": 0.05,
|
|
10641
10907
|
"icon-pitch-alignment": "map",
|
|
@@ -11014,7 +11280,7 @@ function buildLayers(themeId = 'light') {
|
|
|
11014
11280
|
'text-max-width': 20,
|
|
11015
11281
|
'text-allow-overlap': false,
|
|
11016
11282
|
'text-size': ['interpolate', ['exponential', 2], ['zoom'], 5, 6, 7, 10.5],
|
|
11017
|
-
'text-radial-offset': 1,
|
|
11283
|
+
'text-radial-offset': 1.5,
|
|
11018
11284
|
'text-justify': 'auto',
|
|
11019
11285
|
'text-variable-anchor': ['bottom', 'right', 'left', 'top', 'bottom-right', 'bottom-left', 'top-right', 'top-left'],
|
|
11020
11286
|
'text-font': ['Fira Code SemiBold'],
|
|
@@ -11258,6 +11524,8 @@ class MapSDK {
|
|
|
11258
11524
|
this.initializeAviationLayers();
|
|
11259
11525
|
this._stopAMMVersioning?.();
|
|
11260
11526
|
this._stopAMMVersioning = watchAMMVersion(this.map);
|
|
11527
|
+
this._navDataVersioning?.stop();
|
|
11528
|
+
this._navDataVersioning = watchNavDataVersion(this.map);
|
|
11261
11529
|
}
|
|
11262
11530
|
this.map.fire("loadComplete", { notam: this.notam, adsb: this.adsb });
|
|
11263
11531
|
this.map.fire("aviation:ready", { notam: this.notam, adsb: this.adsb });
|
|
@@ -11681,6 +11949,7 @@ class MapSDK {
|
|
|
11681
11949
|
const navdata = this.map?.getSource("navdata");
|
|
11682
11950
|
if (navdata?.setTiles) {
|
|
11683
11951
|
navdata.setTiles([navdataTilesUrl(this._chartApiUrl, period, this._apiVersion, !!this._tileCipher)]);
|
|
11952
|
+
void this._navDataVersioning?.refresh();
|
|
11684
11953
|
}
|
|
11685
11954
|
if (from !== undefined && from !== period) {
|
|
11686
11955
|
this.map?.fire("periodchange", { from, to: period });
|
|
@@ -11853,6 +12122,8 @@ class MapSDK {
|
|
|
11853
12122
|
return;
|
|
11854
12123
|
this._stopAMMVersioning?.();
|
|
11855
12124
|
this._stopAMMVersioning = undefined;
|
|
12125
|
+
this._navDataVersioning?.stop();
|
|
12126
|
+
this._navDataVersioning = undefined;
|
|
11856
12127
|
this.globalConfig.setMapReinitCallback(null);
|
|
11857
12128
|
this.pluginManager.destroy();
|
|
11858
12129
|
this.performanceManager.destroy();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aviation-chart",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.36",
|
|
4
4
|
"description": "KunYu aviation map SDK",
|
|
5
5
|
"main": "dist/nav-sdk.esm.js",
|
|
6
6
|
"module": "dist/nav-sdk.esm.js",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"vite": "^4.0.0"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@geoman-io/maplibre-geoman-free": "
|
|
71
|
+
"@geoman-io/maplibre-geoman-free": "0.4.8",
|
|
72
72
|
"@noble/ciphers": "^2.2.0",
|
|
73
73
|
"@noble/hashes": "^2.2.0",
|
|
74
74
|
"@turf/circle": "^6.5.0",
|