aviation-chart 2.0.35 → 2.0.37

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 CHANGED
@@ -965,6 +965,7 @@ declare class MapSDK implements IMapSDK {
965
965
  private _apiVersion;
966
966
  private _tileCipher;
967
967
  private _stopAMMVersioning;
968
+ private _navDataVersioning;
968
969
  readonly ready: Promise<void>;
969
970
  private _resolveReady;
970
971
  private _rejectReady;
@@ -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 b - Value to validate.
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(b) {
7728
- if (typeof b !== 'boolean')
7729
- throw new TypeError(`boolean expected, not ${b}`);
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 expected, got ' + typeof n);
7751
+ throw new TypeError(atitle$1(title) + 'expected number, got ' + typeof n);
7746
7752
  if (!Number.isSafeInteger(n) || n < 0)
7747
- throw new RangeError('positive integer expected, got ' + n);
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 len = value?.length;
7768
- const needsLen = length !== undefined;
7769
- if (!bytes || (needsLen && len !== length)) {
7770
- const prefix = title && `"${title}" `;
7771
- const ofLen = needsLen ? ` of length ${length}` : '';
7772
- const got = bytes ? `length=${len}` : `type=${typeof value}`;
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('Hash instance has been destroyed');
7805
+ throw new Error('hash was destroyed');
7796
7806
  if (checkFinished && instance.finished)
7797
- throw new Error('Hash#digest() has already been called');
7807
+ throw new Error('digest() was already called');
7798
7808
  }
7799
7809
  /**
7800
- * Asserts output is a properly-sized byte array.
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, onlyAligned = false) {
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 < min) {
7820
- throw new RangeError('digestInto() expects output buffer of length at least ' + min);
7829
+ if (!(out.length >= min)) {
7830
+ throw new RangeError('"output" expected length >= ' + min);
7821
7831
  }
7822
- if (onlyAligned && !isAligned32(out))
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
- const byteSwap = (word) => ((word << 24) & 0xff000000) |
7902
- ((word << 8) & 0xff0000) |
7903
- ((word >>> 8) & 0xff00) |
7904
- ((word >>> 24) & 0xff);
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
- const byteSwap32 = (arr) => {
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`), and tag-bearing constructors are expected to use
7995
- * `args[1]` for optional AAD.
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
- // Validate AAD if tagLength present
8045
+ // Keep tag length available for decrypt-size checks after constructor validation.
8011
8046
  const tagl = params.tagLength;
8012
- if (tagl && args[1] !== undefined)
8013
- abytes$1(args[1], undefined, 'AAD');
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 bigger than tagLength=' + tagl);
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 or alignment. {@link Error}
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, undefined, 'output');
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 bit lengths into a 16-byte buffer.
8075
- * @param dataLength - Data length in bits.
8076
- * @param aadLength - AAD length in bits.
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
- aoutput$1(out, this, true);
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
- swap32IfBE(o32);
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('Wrong sbox length');
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 cipher = gcm(key, nonce);
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/gcm: invalid ghash tag');
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
- const prefix = title && `"${title}" `;
8741
- throw new TypeError(`${prefix}expected number, got ${typeof n}`);
8742
- }
8743
- if (!Number.isSafeInteger(n) || n < 0) {
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 len = value?.length;
8765
- const needsLen = length !== undefined;
8766
- if (!bytes || (needsLen && len !== length)) {
8767
- const prefix = title && `"${title}" `;
8768
- const ofLen = needsLen ? ` of length ${length}` : '';
8769
- const got = bytes ? `length=${len}` : `type=${typeof value}`;
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('Hash must wrapped by utils.createHasher');
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('"outputLen" must be >= 1');
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('Hash instance has been destroyed');
8881
+ throw new Error('hash was destroyed');
8820
8882
  if (checkFinished && instance.finished)
8821
- throw new Error('Hash#digest() has already been called');
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, 'digestInto() output');
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 < min) {
8843
- throw new RangeError('"digestInto() output" expected to be of length >=' + min);
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('Expected instance of class which extends utils.Hash');
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
- buffer.set(data.subarray(pos, pos + take), this.pos);
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
- this.roundClean();
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
- clean(this.buffer.subarray(pos));
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
- pos = 0;
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
- view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
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
- const oview = createView(out);
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
- if (outLen > state.length)
9164
- throw new Error('_sha2: outputLen bigger than state');
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
- _cloneInto(to) {
9178
- to ||= new this.constructor();
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 (length % blockLen)
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
- constructor(outputLen) {
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 为准);凡随主题变化的值
@@ -10217,6 +10482,10 @@ function buildLayers(themeId = 'light') {
10217
10482
  },
10218
10483
  {
10219
10484
  "id": "boundary", "type": "line", "source": "boundary", "minzoom": 0,
10485
+ layout: {
10486
+ "line-join": "bevel",
10487
+ "line-cap": "butt",
10488
+ },
10220
10489
  "paint": {
10221
10490
  "line-width": ["interpolate", ["linear"], ["zoom"], 0, 1, 7, 4],
10222
10491
  "line-opacity": 1,
@@ -10267,10 +10536,10 @@ function buildLayers(themeId = 'light') {
10267
10536
  {
10268
10537
  id: 'airspace_label_center_layer', type: 'symbol', source: sourceId, 'source-layer': 'fir-centroid',
10269
10538
  minzoom: 3,
10270
- "maxzoom": 6,
10539
+ maxzoom: 7,
10271
10540
  layout: {
10272
10541
  'text-field': '{CODE_ID}',
10273
- 'text-font': frutigerBold,
10542
+ 'text-font': ['Frutiger Regular'],
10274
10543
  'symbol-placement': 'point',
10275
10544
  'text-max-width': 8,
10276
10545
  'symbol-sort-key': ['*', -1, ['get', 'SIZE']],
@@ -10287,11 +10556,11 @@ function buildLayers(themeId = 'light') {
10287
10556
  ["linear"],
10288
10557
  ["sqrt", ["get", "SIZE"]],
10289
10558
  100, 9,
10290
- 316, 11,
10291
- 707, 13,
10292
- 1000, 14,
10293
- 1414, 16,
10294
- 2236, 18
10559
+ 316, 10,
10560
+ 707, 12,
10561
+ 1000, 13,
10562
+ 1414, 14,
10563
+ 2236, 16
10295
10564
  ],
10296
10565
 
10297
10566
  // Z4:区域视角
@@ -10300,12 +10569,12 @@ function buildLayers(themeId = 'light') {
10300
10569
  "interpolate",
10301
10570
  ["linear"],
10302
10571
  ["sqrt", ["get", "SIZE"]],
10303
- 100, 10,
10304
- 316, 12,
10305
- 707, 14,
10306
- 1000, 16,
10307
- 1414, 18,
10308
- 2236, 20
10572
+ 100, 9,
10573
+ 316, 11,
10574
+ 707, 13,
10575
+ 1000, 15,
10576
+ 1414, 16,
10577
+ 2236, 18
10309
10578
  ],
10310
10579
 
10311
10580
  // Z6:FIR 最后显示层级
@@ -10314,19 +10583,19 @@ function buildLayers(themeId = 'light') {
10314
10583
  "interpolate",
10315
10584
  ["linear"],
10316
10585
  ["sqrt", ["get", "SIZE"]],
10317
- 100, 11,
10318
- 316, 13,
10319
- 707, 15,
10320
- 1000, 17,
10321
- 1414, 19,
10322
- 2236, 21
10586
+ 100, 10,
10587
+ 316, 12,
10588
+ 707, 13,
10589
+ 1000, 15,
10590
+ 1414, 16,
10591
+ 2236, 18
10323
10592
  ]
10324
- ]
10593
+ ],
10325
10594
  },
10326
10595
  paint: {
10327
10596
  'text-color': T.airspaceStroke,
10328
10597
  ...T.centerHalo,
10329
- 'text-opacity': ['interpolate', ['linear'], ['zoom'], 3, 0.85, 8, 0.7, 12, 0.5],
10598
+ 'text-opacity': ['interpolate', ['linear'], ['zoom'], 3, 0.5, 8, 0.5, 12, 0.5],
10330
10599
  },
10331
10600
  },
10332
10601
  {
@@ -10635,7 +10904,8 @@ function buildLayers(themeId = 'light') {
10635
10904
  true // zoom >5,全部显示
10636
10905
  ],
10637
10906
  layout: {
10638
- "icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-mil", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MILEXT"], "airport-milext", "airport-civ"],
10907
+ "icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-milext-circle", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MILEXT"], "airport-mil-circle", "airport-civ-cirlce"],
10908
+ // "icon-image": ["case", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MIL"], "airport-mil", ["==", ["get", "CODE_TYPE_MIL_OPS"], "MILEXT"], "airport-milext", "airport-civ"],
10639
10909
  "symbol-z-order": "viewport-y",
10640
10910
  "text-letter-spacing": 0.05,
10641
10911
  "icon-pitch-alignment": "map",
@@ -10894,7 +11164,15 @@ function buildLayers(themeId = 'light') {
10894
11164
  {
10895
11165
  id: 'vor_icon', minzoom: 4, type: 'symbol', source: sourceId, 'source-layer': 'vor',
10896
11166
  layout: {
10897
- "icon-image": "navig:vordme",
11167
+ // "icon-image": "navig:vordme",
11168
+ 'icon-image': [
11169
+ 'case',
11170
+ ['==', ['get', 'NAVAID_TYPE'], 'VOR'],
11171
+ 'navig:vor',
11172
+ ['==', ['get', 'NAVAID_TYPE'], 'VORDME'],
11173
+ 'navig:vordme',
11174
+ 'navig:vordme'
11175
+ ],
10898
11176
  "icon-pitch-alignment": "map",
10899
11177
  "icon-size": {
10900
11178
  "base": 2,
@@ -10950,7 +11228,7 @@ function buildLayers(themeId = 'light') {
10950
11228
  {
10951
11229
  id: 'vor_label', type: 'symbol', source: sourceId, 'source-layer': 'vor', minzoom: 5, maxzoom: 8,
10952
11230
  layout: {
10953
- 'text-field': ['get', 'CODE_ID'], 'text-font': ['Frutiger Regular'], 'text-size': 10, 'text-anchor': 'top',
11231
+ 'text-field': ['get', 'CODE_ID'], 'text-font': ['Frutiger Regular'], 'text-size': 9, 'text-anchor': 'top',
10954
11232
  'text-offset': [0, 0.5]
10955
11233
  },
10956
11234
  paint: { 'text-color': T.vor, 'text-halo-color': T.halo, 'text-halo-width': 1 },
@@ -11014,7 +11292,7 @@ function buildLayers(themeId = 'light') {
11014
11292
  'text-max-width': 20,
11015
11293
  'text-allow-overlap': false,
11016
11294
  'text-size': ['interpolate', ['exponential', 2], ['zoom'], 5, 6, 7, 10.5],
11017
- 'text-radial-offset': 1,
11295
+ 'text-radial-offset': 1.5,
11018
11296
  'text-justify': 'auto',
11019
11297
  'text-variable-anchor': ['bottom', 'right', 'left', 'top', 'bottom-right', 'bottom-left', 'top-right', 'top-left'],
11020
11298
  'text-font': ['Fira Code SemiBold'],
@@ -11258,6 +11536,8 @@ class MapSDK {
11258
11536
  this.initializeAviationLayers();
11259
11537
  this._stopAMMVersioning?.();
11260
11538
  this._stopAMMVersioning = watchAMMVersion(this.map);
11539
+ this._navDataVersioning?.stop();
11540
+ this._navDataVersioning = watchNavDataVersion(this.map);
11261
11541
  }
11262
11542
  this.map.fire("loadComplete", { notam: this.notam, adsb: this.adsb });
11263
11543
  this.map.fire("aviation:ready", { notam: this.notam, adsb: this.adsb });
@@ -11681,6 +11961,7 @@ class MapSDK {
11681
11961
  const navdata = this.map?.getSource("navdata");
11682
11962
  if (navdata?.setTiles) {
11683
11963
  navdata.setTiles([navdataTilesUrl(this._chartApiUrl, period, this._apiVersion, !!this._tileCipher)]);
11964
+ void this._navDataVersioning?.refresh();
11684
11965
  }
11685
11966
  if (from !== undefined && from !== period) {
11686
11967
  this.map?.fire("periodchange", { from, to: period });
@@ -11853,6 +12134,8 @@ class MapSDK {
11853
12134
  return;
11854
12135
  this._stopAMMVersioning?.();
11855
12136
  this._stopAMMVersioning = undefined;
12137
+ this._navDataVersioning?.stop();
12138
+ this._navDataVersioning = undefined;
11856
12139
  this.globalConfig.setMapReinitCallback(null);
11857
12140
  this.pluginManager.destroy();
11858
12141
  this.performanceManager.destroy();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aviation-chart",
3
- "version": "2.0.35",
3
+ "version": "2.0.37",
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": "^0.4.8",
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",