diff --git a/CefGlue.Avalonia/CefGlue.Avalonia.csproj b/CefGlue.Avalonia/CefGlue.Avalonia.csproj
index 90db6b3b..3f945156 100644
--- a/CefGlue.Avalonia/CefGlue.Avalonia.csproj
+++ b/CefGlue.Avalonia/CefGlue.Avalonia.csproj
@@ -25,6 +25,7 @@
+
none
diff --git a/CefGlue.BrowserProcess/CefGlue.BrowserProcess.csproj b/CefGlue.BrowserProcess/CefGlue.BrowserProcess.csproj
index cbc69938..d46e6fc4 100644
--- a/CefGlue.BrowserProcess/CefGlue.BrowserProcess.csproj
+++ b/CefGlue.BrowserProcess/CefGlue.BrowserProcess.csproj
@@ -11,13 +11,13 @@
Configuration=$(Configuration);Platform=$(Platform);TargetFramework=$(TargetFramework);IsPublishing=True;PublishTrimmed=True;SelfContained=True;RuntimeIdentifier=
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/CefGlue.BrowserProcess/JavascriptExecution/JavascriptExecutionEngineRenderSide.cs b/CefGlue.BrowserProcess/JavascriptExecution/JavascriptExecutionEngineRenderSide.cs
index 402676b4..479e379f 100644
--- a/CefGlue.BrowserProcess/JavascriptExecution/JavascriptExecutionEngineRenderSide.cs
+++ b/CefGlue.BrowserProcess/JavascriptExecution/JavascriptExecutionEngineRenderSide.cs
@@ -27,7 +27,7 @@ private static void HandleJavascriptEvaluation(MessageReceivedEventArgs args)
TaskId = message.TaskId,
Success = success,
Exception = success ? null : exception.Message,
- ResultAsJson = value?.GetStringValue()
+ Result = value?.GetArrayBuffer()
};
var cefResponseMessage = response.ToCefProcessMessage();
diff --git a/CefGlue.BrowserProcess/ObjectBinding/CefGlueGlobalScript.js b/CefGlue.BrowserProcess/ObjectBinding/CefGlueGlobalScript.js
index c2dfebb7..4d1b5827 100644
--- a/CefGlue.BrowserProcess/ObjectBinding/CefGlueGlobalScript.js
+++ b/CefGlue.BrowserProcess/ObjectBinding/CefGlueGlobalScript.js
@@ -1,81 +1,98 @@
-var $GlobalObjectName$;
-if (!$GlobalObjectName$) {
- $GlobalObjectName$ = (function () {
- const idPropertyName = "$JsonIdAttribute$";
- const refPropertyName = "$JsonRefAttribute$";
- const valuesPropertyName = "$JsonValuesAttribute$";
- function isString(value) {
- return typeof value === "string";
- }
- function convertBase64ToBinary(value) {
- const byteCharacters = atob(value);
- const byteArray = new Array(byteCharacters.length);
- for (let i = 0; i < byteCharacters.length; i++) {
- byteArray[i] = byteCharacters.charCodeAt(i);
- }
- return new Uint8Array(byteArray);;
- }
- function convertBinaryToBase64(byteArray) {
- return btoa(String.fromCharCode(...byteArray));
- }
- function convertStringToJsType(value) {
- switch (value.substring(0, $DataMarkerLength$)) {
- case "$StringMarker$":
- return value.substring($DataMarkerLength$);
- case "$DateTimeMarker$":
- return new Date(value.substring($DataMarkerLength$));
- case "$BinaryMarker$":
- return convertBase64ToBinary(value.substring($DataMarkerLength$));
- }
- return value;
+var cefglue = (function (exports) {
+ 'use strict';
+
+ function isString(value) {
+ return typeof value === "string";
+ }
+ function isFunction(value) {
+ return typeof value === "function";
+ }
+ function isArrayBuffer(value) {
+ return value instanceof ArrayBuffer;
+ }
+
+ const idPropertyName = "$id";
+ const refPropertyName = "$ref";
+ const valuesPropertyName = "$values";
+ // special data markers used to distinguish the several string types
+ var TypeMarker;
+ (function (TypeMarker) {
+ TypeMarker["dateTime"] = "D";
+ TypeMarker["string"] = "S";
+ TypeMarker["binary"] = "B";
+ })(TypeMarker || (TypeMarker = {}));
+ function convertBase64ToBinary(value) {
+ const byteCharacters = atob(value);
+ const byteArray = new Array(byteCharacters.length);
+ for (let i = 0; i < byteCharacters.length; i++) {
+ byteArray[i] = byteCharacters.charCodeAt(i);
}
- function revive(name, value, refs, pendingRefs) {
- if (value) {
- const id = value[idPropertyName];
- if (id !== undefined) {
- delete value[idPropertyName];
- const pendingRef = pendingRefs.get(id);
- if (pendingRef) {
- Object.assign(pendingRef, value);
- value = pendingRef;
- }
- refs.set(id, value);
- return value;
- }
- const refId = value[refPropertyName];
- if (refId !== undefined) {
- const ref = refs.get(refId);
- if (ref) {
- return ref;
- }
- const pendingRef = pendingRefs.get(refId);
- if (pendingRef) {
- value = pendingRef;
- } else {
- value = {};
- pendingRefs.set(refId, value);
- }
- return value;
- }
- if (isString(value)) {
- return convertStringToJsType(value);
- }
+ return new Uint8Array(byteArray);
+ }
+ function convertBinaryToBase64(byteArray) {
+ return btoa(String.fromCharCode(...byteArray));
+ }
+ class JsonSerializer {
+ static Instance = new JsonSerializer();
+ static convertStringToJsType(value) {
+ switch (value.substring(0, 1)) {
+ case TypeMarker.string:
+ return value.substring(1);
+ case TypeMarker.dateTime:
+ return new Date(value.substring(1));
+ case TypeMarker.binary:
+ return convertBase64ToBinary(value.substring(1));
}
return value;
}
- function parseResult(result) {
+ deserialize(value) {
const refs = new Map();
const pendingRefs = new Map();
- return isString(result) ? JSON.parse(result, (name, value) => revive(name, value, refs, pendingRefs)) : result;
+ const textDecoder = new TextDecoder();
+ return JSON.parse(textDecoder.decode(value), function (name, value) {
+ if (value) {
+ const id = value[idPropertyName];
+ if (id !== undefined) {
+ delete value[idPropertyName];
+ const pendingRef = pendingRefs.get(id);
+ if (pendingRef) {
+ Object.assign(pendingRef, value);
+ value = pendingRef;
+ }
+ refs.set(id, value);
+ return value;
+ }
+ const refId = value[refPropertyName];
+ if (refId !== undefined) {
+ const ref = refs.get(refId);
+ if (ref) {
+ return ref;
+ }
+ const pendingRef = pendingRefs.get(refId);
+ if (pendingRef) {
+ value = pendingRef;
+ }
+ else {
+ value = {};
+ pendingRefs.set(refId, value);
+ }
+ return value;
+ }
+ if (isString(value)) {
+ return JsonSerializer.convertStringToJsType(value);
+ }
+ }
+ return value;
+ });
}
- function objectsStringifier(skipReferenceForInitialArrayObject) {
+ serialize(value, options = {}) {
const refs = new Map();
const marker = Symbol("marker");
- return function (key, value) {
+ const textEncoder = new TextEncoder();
+ return textEncoder.encode(JSON.stringify(value, function (key, value) {
if (value === null || value === undefined) {
return value;
}
-
if (key === idPropertyName || key === refPropertyName || (key === valuesPropertyName && Reflect.has(this, marker))) {
// its the id, ref or special values property
return value;
@@ -86,12 +103,12 @@ if (!$GlobalObjectName$) {
// in this case, we need to return the date as a string, but prefixed with the DateTimeMarker
// (there can be a remote problem that the property is accessed two times, which can cause undesirable side effects)
if (Reflect.get(this, key) instanceof Date) {
- return "$DateTimeMarker$" + value;
+ return TypeMarker.dateTime + value;
}
- return "$StringMarker$" + value;
+ return TypeMarker.string + value;
case "object":
if (value instanceof Uint8Array) {
- return "$BinaryMarker$" + convertBinaryToBase64(value);
+ return TypeMarker.binary + convertBinaryToBase64(value);
}
if (Reflect.has(value, marker)) {
return value;
@@ -108,12 +125,11 @@ if (!$GlobalObjectName$) {
const id = refs.size.toString();
refs.set(value, { [refPropertyName]: id, [marker]: undefined });
if (Array.isArray(value)) {
- if (skipReferenceForInitialArrayObject && key === "") {
+ if (options.skipReferenceForInitialArrayObject && key === "") {
// For arrays, when the flag is on, the resulting string is not wrapped in "{$id:"",$values:[..]}"
// instead, it returns the plain array "[...]"
return value;
}
-
// If it is an array, wrap the array and add an id and a marker
return { [idPropertyName]: id, [valuesPropertyName]: value, [marker]: undefined };
}
@@ -124,58 +140,1694 @@ if (!$GlobalObjectName$) {
return Object.assign(tmpObj, value, tmpObj);
}
return Object.assign(tmpObj, value);
+ })).buffer;
+ }
+ }
+
+ function utf8Count(str) {
+ const strLength = str.length;
+ let byteLength = 0;
+ let pos = 0;
+ while (pos < strLength) {
+ let value = str.charCodeAt(pos++);
+ if ((value & 0xffffff80) === 0) {
+ // 1-byte
+ byteLength++;
+ continue;
}
+ else if ((value & 0xfffff800) === 0) {
+ // 2-bytes
+ byteLength += 2;
+ }
+ else {
+ // handle surrogate pair
+ if (value >= 0xd800 && value <= 0xdbff) {
+ // high surrogate
+ if (pos < strLength) {
+ const extra = str.charCodeAt(pos);
+ if ((extra & 0xfc00) === 0xdc00) {
+ ++pos;
+ value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+ }
+ }
+ }
+ if ((value & 0xffff0000) === 0) {
+ // 3-byte
+ byteLength += 3;
+ }
+ else {
+ // 4-byte
+ byteLength += 4;
+ }
+ }
+ }
+ return byteLength;
+ }
+ function utf8EncodeJs(str, output, outputOffset) {
+ const strLength = str.length;
+ let offset = outputOffset;
+ let pos = 0;
+ while (pos < strLength) {
+ let value = str.charCodeAt(pos++);
+ if ((value & 0xffffff80) === 0) {
+ // 1-byte
+ output[offset++] = value;
+ continue;
+ }
+ else if ((value & 0xfffff800) === 0) {
+ // 2-bytes
+ output[offset++] = ((value >> 6) & 0x1f) | 0xc0;
+ }
+ else {
+ // handle surrogate pair
+ if (value >= 0xd800 && value <= 0xdbff) {
+ // high surrogate
+ if (pos < strLength) {
+ const extra = str.charCodeAt(pos);
+ if ((extra & 0xfc00) === 0xdc00) {
+ ++pos;
+ value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+ }
+ }
+ }
+ if ((value & 0xffff0000) === 0) {
+ // 3-byte
+ output[offset++] = ((value >> 12) & 0x0f) | 0xe0;
+ output[offset++] = ((value >> 6) & 0x3f) | 0x80;
+ }
+ else {
+ // 4-byte
+ output[offset++] = ((value >> 18) & 0x07) | 0xf0;
+ output[offset++] = ((value >> 12) & 0x3f) | 0x80;
+ output[offset++] = ((value >> 6) & 0x3f) | 0x80;
+ }
+ }
+ output[offset++] = (value & 0x3f) | 0x80;
+ }
+ }
+ // TextEncoder and TextDecoder are standardized in whatwg encoding:
+ // https://encoding.spec.whatwg.org/
+ // and available in all the modern browsers:
+ // https://caniuse.com/textencoder
+ // They are available in Node.js since v12 LTS as well:
+ // https://nodejs.org/api/globals.html#textencoder
+ let sharedTextEncoder;
+ // This threshold should be determined by benchmarking, which might vary in engines and input data.
+ // Run `npx ts-node benchmark/encode-string.ts` for details.
+ const TEXT_ENCODER_THRESHOLD = 50;
+ function utf8EncodeTE(str, output, outputOffset) {
+ if (!sharedTextEncoder) {
+ sharedTextEncoder = new TextEncoder();
+ }
+ sharedTextEncoder.encodeInto(str, output.subarray(outputOffset));
+ }
+ function utf8Encode(str, output, outputOffset) {
+ if (str.length > TEXT_ENCODER_THRESHOLD) {
+ utf8EncodeTE(str, output, outputOffset);
}
+ else {
+ utf8EncodeJs(str, output, outputOffset);
+ }
+ }
+ const CHUNK_SIZE = 0x1_000;
+ function utf8DecodeJs(bytes, inputOffset, byteLength) {
+ let offset = inputOffset;
+ const end = offset + byteLength;
+ const units = [];
+ let result = "";
+ while (offset < end) {
+ const byte1 = bytes[offset++];
+ if ((byte1 & 0x80) === 0) {
+ // 1 byte
+ units.push(byte1);
+ }
+ else if ((byte1 & 0xe0) === 0xc0) {
+ // 2 bytes
+ const byte2 = bytes[offset++] & 0x3f;
+ units.push(((byte1 & 0x1f) << 6) | byte2);
+ }
+ else if ((byte1 & 0xf0) === 0xe0) {
+ // 3 bytes
+ const byte2 = bytes[offset++] & 0x3f;
+ const byte3 = bytes[offset++] & 0x3f;
+ units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
+ }
+ else if ((byte1 & 0xf8) === 0xf0) {
+ // 4 bytes
+ const byte2 = bytes[offset++] & 0x3f;
+ const byte3 = bytes[offset++] & 0x3f;
+ const byte4 = bytes[offset++] & 0x3f;
+ let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
+ if (unit > 0xffff) {
+ unit -= 0x10000;
+ units.push(((unit >>> 10) & 0x3ff) | 0xd800);
+ unit = 0xdc00 | (unit & 0x3ff);
+ }
+ units.push(unit);
+ }
+ else {
+ units.push(byte1);
+ }
+ if (units.length >= CHUNK_SIZE) {
+ result += String.fromCharCode(...units);
+ units.length = 0;
+ }
+ }
+ if (units.length > 0) {
+ result += String.fromCharCode(...units);
+ }
+ return result;
+ }
+ let sharedTextDecoder;
+ // This threshold should be determined by benchmarking, which might vary in engines and input data.
+ // Run `npx ts-node benchmark/decode-string.ts` for details.
+ const TEXT_DECODER_THRESHOLD = 200;
+ function utf8DecodeTD(bytes, inputOffset, byteLength) {
+ if (!sharedTextDecoder) {
+ sharedTextDecoder = new TextDecoder();
+ }
+ const stringBytes = bytes.subarray(inputOffset, inputOffset + byteLength);
+ return sharedTextDecoder.decode(stringBytes);
+ }
+ function utf8Decode(bytes, inputOffset, byteLength) {
+ if (byteLength > TEXT_DECODER_THRESHOLD) {
+ return utf8DecodeTD(bytes, inputOffset, byteLength);
+ }
+ else {
+ return utf8DecodeJs(bytes, inputOffset, byteLength);
+ }
+ }
+
+ /**
+ * ExtData is used to handle Extension Types that are not registered to ExtensionCodec.
+ */
+ class ExtData {
+ type;
+ data;
+ constructor(type, data) {
+ this.type = type;
+ this.data = data;
+ }
+ }
+
+ class DecodeError extends Error {
+ constructor(message) {
+ super(message);
+ // fix the prototype chain in a cross-platform way
+ const proto = Object.create(DecodeError.prototype);
+ Object.setPrototypeOf(this, proto);
+ Object.defineProperty(this, "name", {
+ configurable: true,
+ enumerable: false,
+ value: DecodeError.name,
+ });
+ }
+ }
+
+ // Integer Utility
+ const UINT32_MAX = 0xffff_ffff;
+ // DataView extension to handle int64 / uint64,
+ // where the actual range is 53-bits integer (a.k.a. safe integer)
+ function setUint64(view, offset, value) {
+ const high = value / 0x1_0000_0000;
+ const low = value; // high bits are truncated by DataView
+ view.setUint32(offset, high);
+ view.setUint32(offset + 4, low);
+ }
+ function setInt64(view, offset, value) {
+ const high = Math.floor(value / 0x1_0000_0000);
+ const low = value; // high bits are truncated by DataView
+ view.setUint32(offset, high);
+ view.setUint32(offset + 4, low);
+ }
+ function getInt64(view, offset) {
+ const high = view.getInt32(offset);
+ const low = view.getUint32(offset + 4);
+ return high * 0x1_0000_0000 + low;
+ }
+ function getUint64(view, offset) {
+ const high = view.getUint32(offset);
+ const low = view.getUint32(offset + 4);
+ return high * 0x1_0000_0000 + low;
+ }
+
+ // https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type
+ const EXT_TIMESTAMP = -1;
+ const TIMESTAMP32_MAX_SEC = 0x100000000 - 1; // 32-bit unsigned int
+ const TIMESTAMP64_MAX_SEC = 0x400000000 - 1; // 34-bit unsigned int
+ function encodeTimeSpecToTimestamp({ sec, nsec }) {
+ if (sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC) {
+ // Here sec >= 0 && nsec >= 0
+ if (nsec === 0 && sec <= TIMESTAMP32_MAX_SEC) {
+ // timestamp 32 = { sec32 (unsigned) }
+ const rv = new Uint8Array(4);
+ const view = new DataView(rv.buffer);
+ view.setUint32(0, sec);
+ return rv;
+ }
+ else {
+ // timestamp 64 = { nsec30 (unsigned), sec34 (unsigned) }
+ const secHigh = sec / 0x100000000;
+ const secLow = sec & 0xffffffff;
+ const rv = new Uint8Array(8);
+ const view = new DataView(rv.buffer);
+ // nsec30 | secHigh2
+ view.setUint32(0, (nsec << 2) | (secHigh & 0x3));
+ // secLow32
+ view.setUint32(4, secLow);
+ return rv;
+ }
+ }
+ else {
+ // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }
+ const rv = new Uint8Array(12);
+ const view = new DataView(rv.buffer);
+ view.setUint32(0, nsec);
+ setInt64(view, 4, sec);
+ return rv;
+ }
+ }
+ function encodeDateToTimeSpec(date) {
+ const msec = date.getTime();
+ const sec = Math.floor(msec / 1e3);
+ const nsec = (msec - sec * 1e3) * 1e6;
+ // Normalizes { sec, nsec } to ensure nsec is unsigned.
+ const nsecInSec = Math.floor(nsec / 1e9);
return {
- $PromiseFactoryFunctionName$: function () {
- const result = {};
- const promise = new Promise(function (resolve, reject) {
- result.resolve = function (result) {
- resolve(parseResult(result));
- };
- result.reject = reject;
- });
- result.promise = promise;
- return result;
- },
- $InterceptorFactoryFunctionName$: function (targetObj) {
- const functionsMap = new Map();
- const handler = {
- set() { },
- get(target, propKey, receiver) {
- const func = functionsMap.get(propKey);
- if (func) {
- return func;
- }
- const targetValue = Reflect.get(target, propKey);
- if (typeof targetValue !== "function") {
- return targetValue;
- }
- const interceptor = function (...args) {
- const convertedArgs = args.length === 0 ? args : [JSON.stringify(args, objectsStringifier(/*skipReferenceForInitialArrayObject*/true))];
- return targetValue.apply(target, convertedArgs);
- };
- functionsMap.set(propKey, interceptor);
- return interceptor;
+ sec: sec + nsecInSec,
+ nsec: nsec - nsecInSec * 1e9,
+ };
+ }
+ function encodeTimestampExtension(object) {
+ if (object instanceof Date) {
+ const timeSpec = encodeDateToTimeSpec(object);
+ return encodeTimeSpecToTimestamp(timeSpec);
+ }
+ else {
+ return null;
+ }
+ }
+ function decodeTimestampToTimeSpec(data) {
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
+ // data may be 32, 64, or 96 bits
+ switch (data.byteLength) {
+ case 4: {
+ // timestamp 32 = { sec32 }
+ const sec = view.getUint32(0);
+ const nsec = 0;
+ return { sec, nsec };
+ }
+ case 8: {
+ // timestamp 64 = { nsec30, sec34 }
+ const nsec30AndSecHigh2 = view.getUint32(0);
+ const secLow32 = view.getUint32(4);
+ const sec = (nsec30AndSecHigh2 & 0x3) * 0x100000000 + secLow32;
+ const nsec = nsec30AndSecHigh2 >>> 2;
+ return { sec, nsec };
+ }
+ case 12: {
+ // timestamp 96 = { nsec32 (unsigned), sec64 (signed) }
+ const sec = getInt64(view, 4);
+ const nsec = view.getUint32(0);
+ return { sec, nsec };
+ }
+ default:
+ throw new DecodeError(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${data.length}`);
+ }
+ }
+ function decodeTimestampExtension(data) {
+ const timeSpec = decodeTimestampToTimeSpec(data);
+ return new Date(timeSpec.sec * 1e3 + timeSpec.nsec / 1e6);
+ }
+ const timestampExtension = {
+ type: EXT_TIMESTAMP,
+ encode: encodeTimestampExtension,
+ decode: decodeTimestampExtension,
+ };
+
+ // ExtensionCodec to handle MessagePack extensions
+ class ExtensionCodec {
+ static defaultCodec = new ExtensionCodec();
+ // ensures ExtensionCodecType matches ExtensionCodec
+ // this will make type errors a lot more clear
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ __brand;
+ // built-in extensions
+ builtInEncoders = [];
+ builtInDecoders = [];
+ // custom extensions
+ encoders = [];
+ decoders = [];
+ constructor() {
+ this.register(timestampExtension);
+ }
+ register({ type, encode, decode, }) {
+ if (type >= 0) {
+ // custom extensions
+ this.encoders[type] = encode;
+ this.decoders[type] = decode;
+ }
+ else {
+ // built-in extensions
+ const index = 1 + type;
+ this.builtInEncoders[index] = encode;
+ this.builtInDecoders[index] = decode;
+ }
+ }
+ tryToEncode(object, context) {
+ // built-in extensions
+ for (let i = 0; i < this.builtInEncoders.length; i++) {
+ const encodeExt = this.builtInEncoders[i];
+ if (encodeExt != null) {
+ const data = encodeExt(object, context);
+ if (data != null) {
+ const type = -1 - i;
+ return new ExtData(type, data);
+ }
+ }
+ }
+ // custom extensions
+ for (let i = 0; i < this.encoders.length; i++) {
+ const encodeExt = this.encoders[i];
+ if (encodeExt != null) {
+ const data = encodeExt(object, context);
+ if (data != null) {
+ const type = i;
+ return new ExtData(type, data);
+ }
+ }
+ }
+ if (object instanceof ExtData) {
+ // to keep ExtData as is
+ return object;
+ }
+ return null;
+ }
+ decode(data, type, context) {
+ const decodeExt = type < 0 ? this.builtInDecoders[-1 - type] : this.decoders[type];
+ if (decodeExt) {
+ return decodeExt(data, type, context);
+ }
+ else {
+ // decode() does not fail, returns ExtData instead.
+ return new ExtData(type, data);
+ }
+ }
+ }
+
+ function ensureUint8Array(buffer) {
+ if (buffer instanceof Uint8Array) {
+ return buffer;
+ }
+ else if (ArrayBuffer.isView(buffer)) {
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
+ }
+ else if (buffer instanceof ArrayBuffer) {
+ return new Uint8Array(buffer);
+ }
+ else {
+ // ArrayLike
+ return Uint8Array.from(buffer);
+ }
+ }
+ function createDataView(buffer) {
+ if (buffer instanceof ArrayBuffer) {
+ return new DataView(buffer);
+ }
+ const bufferView = ensureUint8Array(buffer);
+ return new DataView(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);
+ }
+
+ const DEFAULT_MAX_DEPTH = 100;
+ const DEFAULT_INITIAL_BUFFER_SIZE = 2048;
+ class Encoder {
+ extensionCodec;
+ context;
+ useBigInt64;
+ maxDepth;
+ initialBufferSize;
+ sortKeys;
+ forceFloat32;
+ ignoreUndefined;
+ forceIntegerToFloat;
+ pos;
+ view;
+ bytes;
+ constructor(options) {
+ this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;
+ this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined
+ this.useBigInt64 = options?.useBigInt64 ?? false;
+ this.maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
+ this.initialBufferSize = options?.initialBufferSize ?? DEFAULT_INITIAL_BUFFER_SIZE;
+ this.sortKeys = options?.sortKeys ?? false;
+ this.forceFloat32 = options?.forceFloat32 ?? false;
+ this.ignoreUndefined = options?.ignoreUndefined ?? false;
+ this.forceIntegerToFloat = options?.forceIntegerToFloat ?? false;
+ this.pos = 0;
+ this.view = new DataView(new ArrayBuffer(this.initialBufferSize));
+ this.bytes = new Uint8Array(this.view.buffer);
+ }
+ reinitializeState() {
+ this.pos = 0;
+ }
+ /**
+ * This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.
+ *
+ * @returns Encodes the object and returns a shared reference the encoder's internal buffer.
+ */
+ encodeSharedRef(object) {
+ this.reinitializeState();
+ this.doEncode(object, 1);
+ return this.bytes.subarray(0, this.pos);
+ }
+ /**
+ * @returns Encodes the object and returns a copy of the encoder's internal buffer.
+ */
+ encode(object) {
+ this.reinitializeState();
+ this.doEncode(object, 1);
+ return this.bytes.slice(0, this.pos);
+ }
+ doEncode(object, depth) {
+ if (depth > this.maxDepth) {
+ throw new Error(`Too deep objects in depth ${depth}`);
+ }
+ if (object == null) {
+ this.encodeNil();
+ }
+ else if (typeof object === "boolean") {
+ this.encodeBoolean(object);
+ }
+ else if (typeof object === "number") {
+ if (!this.forceIntegerToFloat) {
+ this.encodeNumber(object);
+ }
+ else {
+ this.encodeNumberAsFloat(object);
+ }
+ }
+ else if (typeof object === "string") {
+ this.encodeString(object);
+ }
+ else if (this.useBigInt64 && typeof object === "bigint") {
+ this.encodeBigInt64(object);
+ }
+ else {
+ this.encodeObject(object, depth);
+ }
+ }
+ ensureBufferSizeToWrite(sizeToWrite) {
+ const requiredSize = this.pos + sizeToWrite;
+ if (this.view.byteLength < requiredSize) {
+ this.resizeBuffer(requiredSize * 2);
+ }
+ }
+ resizeBuffer(newSize) {
+ const newBuffer = new ArrayBuffer(newSize);
+ const newBytes = new Uint8Array(newBuffer);
+ const newView = new DataView(newBuffer);
+ newBytes.set(this.bytes);
+ this.view = newView;
+ this.bytes = newBytes;
+ }
+ encodeNil() {
+ this.writeU8(0xc0);
+ }
+ encodeBoolean(object) {
+ if (object === false) {
+ this.writeU8(0xc2);
+ }
+ else {
+ this.writeU8(0xc3);
+ }
+ }
+ encodeNumber(object) {
+ if (!this.forceIntegerToFloat && Number.isSafeInteger(object)) {
+ if (object >= 0) {
+ if (object < 0x80) {
+ // positive fixint
+ this.writeU8(object);
+ }
+ else if (object < 0x100) {
+ // uint 8
+ this.writeU8(0xcc);
+ this.writeU8(object);
+ }
+ else if (object < 0x10000) {
+ // uint 16
+ this.writeU8(0xcd);
+ this.writeU16(object);
+ }
+ else if (object < 0x100000000) {
+ // uint 32
+ this.writeU8(0xce);
+ this.writeU32(object);
+ }
+ else if (!this.useBigInt64) {
+ // uint 64
+ this.writeU8(0xcf);
+ this.writeU64(object);
+ }
+ else {
+ this.encodeNumberAsFloat(object);
+ }
+ }
+ else {
+ if (object >= -0x20) {
+ // negative fixint
+ this.writeU8(0xe0 | (object + 0x20));
+ }
+ else if (object >= -0x80) {
+ // int 8
+ this.writeU8(0xd0);
+ this.writeI8(object);
+ }
+ else if (object >= -0x8000) {
+ // int 16
+ this.writeU8(0xd1);
+ this.writeI16(object);
+ }
+ else if (object >= -0x80000000) {
+ // int 32
+ this.writeU8(0xd2);
+ this.writeI32(object);
+ }
+ else if (!this.useBigInt64) {
+ // int 64
+ this.writeU8(0xd3);
+ this.writeI64(object);
+ }
+ else {
+ this.encodeNumberAsFloat(object);
+ }
+ }
+ }
+ else {
+ this.encodeNumberAsFloat(object);
+ }
+ }
+ encodeNumberAsFloat(object) {
+ if (this.forceFloat32) {
+ // float 32
+ this.writeU8(0xca);
+ this.writeF32(object);
+ }
+ else {
+ // float 64
+ this.writeU8(0xcb);
+ this.writeF64(object);
+ }
+ }
+ encodeBigInt64(object) {
+ if (object >= BigInt(0)) {
+ // uint 64
+ this.writeU8(0xcf);
+ this.writeBigUint64(object);
+ }
+ else {
+ // int 64
+ this.writeU8(0xd3);
+ this.writeBigInt64(object);
+ }
+ }
+ writeStringHeader(byteLength) {
+ if (byteLength < 32) {
+ // fixstr
+ this.writeU8(0xa0 + byteLength);
+ }
+ else if (byteLength < 0x100) {
+ // str 8
+ this.writeU8(0xd9);
+ this.writeU8(byteLength);
+ }
+ else if (byteLength < 0x10000) {
+ // str 16
+ this.writeU8(0xda);
+ this.writeU16(byteLength);
+ }
+ else if (byteLength < 0x100000000) {
+ // str 32
+ this.writeU8(0xdb);
+ this.writeU32(byteLength);
+ }
+ else {
+ throw new Error(`Too long string: ${byteLength} bytes in UTF-8`);
+ }
+ }
+ encodeString(object) {
+ const maxHeaderSize = 1 + 4;
+ const byteLength = utf8Count(object);
+ this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);
+ this.writeStringHeader(byteLength);
+ utf8Encode(object, this.bytes, this.pos);
+ this.pos += byteLength;
+ }
+ encodeObject(object, depth) {
+ // try to encode objects with custom codec first of non-primitives
+ const ext = this.extensionCodec.tryToEncode(object, this.context);
+ if (ext != null) {
+ this.encodeExtension(ext);
+ }
+ else if (Array.isArray(object)) {
+ this.encodeArray(object, depth);
+ }
+ else if (ArrayBuffer.isView(object)) {
+ this.encodeBinary(object);
+ }
+ else if (typeof object === "object") {
+ this.encodeMap(object, depth);
+ }
+ else {
+ // symbol, function and other special object come here unless extensionCodec handles them.
+ throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);
+ }
+ }
+ encodeBinary(object) {
+ const size = object.byteLength;
+ if (size < 0x100) {
+ // bin 8
+ this.writeU8(0xc4);
+ this.writeU8(size);
+ }
+ else if (size < 0x10000) {
+ // bin 16
+ this.writeU8(0xc5);
+ this.writeU16(size);
+ }
+ else if (size < 0x100000000) {
+ // bin 32
+ this.writeU8(0xc6);
+ this.writeU32(size);
+ }
+ else {
+ throw new Error(`Too large binary: ${size}`);
+ }
+ const bytes = ensureUint8Array(object);
+ this.writeU8a(bytes);
+ }
+ encodeArray(object, depth) {
+ const size = object.length;
+ if (size < 16) {
+ // fixarray
+ this.writeU8(0x90 + size);
+ }
+ else if (size < 0x10000) {
+ // array 16
+ this.writeU8(0xdc);
+ this.writeU16(size);
+ }
+ else if (size < 0x100000000) {
+ // array 32
+ this.writeU8(0xdd);
+ this.writeU32(size);
+ }
+ else {
+ throw new Error(`Too large array: ${size}`);
+ }
+ for (const item of object) {
+ this.doEncode(item, depth + 1);
+ }
+ }
+ countWithoutUndefined(object, keys) {
+ let count = 0;
+ for (const key of keys) {
+ if (object[key] !== undefined) {
+ count++;
+ }
+ }
+ return count;
+ }
+ encodeMap(object, depth) {
+ const keys = Object.keys(object);
+ if (this.sortKeys) {
+ keys.sort();
+ }
+ const size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;
+ if (size < 16) {
+ // fixmap
+ this.writeU8(0x80 + size);
+ }
+ else if (size < 0x10000) {
+ // map 16
+ this.writeU8(0xde);
+ this.writeU16(size);
+ }
+ else if (size < 0x100000000) {
+ // map 32
+ this.writeU8(0xdf);
+ this.writeU32(size);
+ }
+ else {
+ throw new Error(`Too large map object: ${size}`);
+ }
+ for (const key of keys) {
+ const value = object[key];
+ if (!(this.ignoreUndefined && value === undefined)) {
+ this.encodeString(key);
+ this.doEncode(value, depth + 1);
+ }
+ }
+ }
+ encodeExtension(ext) {
+ const size = ext.data.length;
+ if (size === 1) {
+ // fixext 1
+ this.writeU8(0xd4);
+ }
+ else if (size === 2) {
+ // fixext 2
+ this.writeU8(0xd5);
+ }
+ else if (size === 4) {
+ // fixext 4
+ this.writeU8(0xd6);
+ }
+ else if (size === 8) {
+ // fixext 8
+ this.writeU8(0xd7);
+ }
+ else if (size === 16) {
+ // fixext 16
+ this.writeU8(0xd8);
+ }
+ else if (size < 0x100) {
+ // ext 8
+ this.writeU8(0xc7);
+ this.writeU8(size);
+ }
+ else if (size < 0x10000) {
+ // ext 16
+ this.writeU8(0xc8);
+ this.writeU16(size);
+ }
+ else if (size < 0x100000000) {
+ // ext 32
+ this.writeU8(0xc9);
+ this.writeU32(size);
+ }
+ else {
+ throw new Error(`Too large extension object: ${size}`);
+ }
+ this.writeI8(ext.type);
+ this.writeU8a(ext.data);
+ }
+ writeU8(value) {
+ this.ensureBufferSizeToWrite(1);
+ this.view.setUint8(this.pos, value);
+ this.pos++;
+ }
+ writeU8a(values) {
+ const size = values.length;
+ this.ensureBufferSizeToWrite(size);
+ this.bytes.set(values, this.pos);
+ this.pos += size;
+ }
+ writeI8(value) {
+ this.ensureBufferSizeToWrite(1);
+ this.view.setInt8(this.pos, value);
+ this.pos++;
+ }
+ writeU16(value) {
+ this.ensureBufferSizeToWrite(2);
+ this.view.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+ writeI16(value) {
+ this.ensureBufferSizeToWrite(2);
+ this.view.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+ writeU32(value) {
+ this.ensureBufferSizeToWrite(4);
+ this.view.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+ writeI32(value) {
+ this.ensureBufferSizeToWrite(4);
+ this.view.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+ writeF32(value) {
+ this.ensureBufferSizeToWrite(4);
+ this.view.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+ writeF64(value) {
+ this.ensureBufferSizeToWrite(8);
+ this.view.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+ writeU64(value) {
+ this.ensureBufferSizeToWrite(8);
+ setUint64(this.view, this.pos, value);
+ this.pos += 8;
+ }
+ writeI64(value) {
+ this.ensureBufferSizeToWrite(8);
+ setInt64(this.view, this.pos, value);
+ this.pos += 8;
+ }
+ writeBigUint64(value) {
+ this.ensureBufferSizeToWrite(8);
+ this.view.setBigUint64(this.pos, value);
+ this.pos += 8;
+ }
+ writeBigInt64(value) {
+ this.ensureBufferSizeToWrite(8);
+ this.view.setBigInt64(this.pos, value);
+ this.pos += 8;
+ }
+ }
+
+ /**
+ * It encodes `value` in the MessagePack format and
+ * returns a byte buffer.
+ *
+ * The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.
+ */
+ function encode(value, options) {
+ const encoder = new Encoder(options);
+ return encoder.encodeSharedRef(value);
+ }
+
+ function prettyByte(byte) {
+ return `${byte < 0 ? "-" : ""}0x${Math.abs(byte).toString(16).padStart(2, "0")}`;
+ }
+
+ const DEFAULT_MAX_KEY_LENGTH = 16;
+ const DEFAULT_MAX_LENGTH_PER_KEY = 16;
+ class CachedKeyDecoder {
+ maxKeyLength;
+ maxLengthPerKey;
+ hit = 0;
+ miss = 0;
+ caches;
+ constructor(maxKeyLength = DEFAULT_MAX_KEY_LENGTH, maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY) {
+ this.maxKeyLength = maxKeyLength;
+ this.maxLengthPerKey = maxLengthPerKey;
+ // avoid `new Array(N)`, which makes a sparse array,
+ // because a sparse array is typically slower than a non-sparse array.
+ this.caches = [];
+ for (let i = 0; i < this.maxKeyLength; i++) {
+ this.caches.push([]);
+ }
+ }
+ canBeCached(byteLength) {
+ return byteLength > 0 && byteLength <= this.maxKeyLength;
+ }
+ find(bytes, inputOffset, byteLength) {
+ const records = this.caches[byteLength - 1];
+ FIND_CHUNK: for (const record of records) {
+ const recordBytes = record.bytes;
+ for (let j = 0; j < byteLength; j++) {
+ if (recordBytes[j] !== bytes[inputOffset + j]) {
+ continue FIND_CHUNK;
}
+ }
+ return record.str;
+ }
+ return null;
+ }
+ store(bytes, value) {
+ const records = this.caches[bytes.length - 1];
+ const record = { bytes, str: value };
+ if (records.length >= this.maxLengthPerKey) {
+ // `records` are full!
+ // Set `record` to an arbitrary position.
+ records[(Math.random() * records.length) | 0] = record;
+ }
+ else {
+ records.push(record);
+ }
+ }
+ decode(bytes, inputOffset, byteLength) {
+ const cachedValue = this.find(bytes, inputOffset, byteLength);
+ if (cachedValue != null) {
+ this.hit++;
+ return cachedValue;
+ }
+ this.miss++;
+ const str = utf8DecodeJs(bytes, inputOffset, byteLength);
+ // Ensure to copy a slice of bytes because the byte may be NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.
+ const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);
+ this.store(slicedCopyOfBytes, str);
+ return str;
+ }
+ }
+
+ const STATE_ARRAY = "array";
+ const STATE_MAP_KEY = "map_key";
+ const STATE_MAP_VALUE = "map_value";
+ const isValidMapKeyType = (key) => {
+ return typeof key === "string" || typeof key === "number";
+ };
+ class StackPool {
+ stack = [];
+ stackHeadPosition = -1;
+ get length() {
+ return this.stackHeadPosition + 1;
+ }
+ top() {
+ return this.stack[this.stackHeadPosition];
+ }
+ pushArrayState(size) {
+ const state = this.getUninitializedStateFromPool();
+ state.type = STATE_ARRAY;
+ state.position = 0;
+ state.size = size;
+ state.array = new Array(size);
+ }
+ pushMapState(size) {
+ const state = this.getUninitializedStateFromPool();
+ state.type = STATE_MAP_KEY;
+ state.readCount = 0;
+ state.size = size;
+ state.map = {};
+ }
+ getUninitializedStateFromPool() {
+ this.stackHeadPosition++;
+ if (this.stackHeadPosition === this.stack.length) {
+ const partialState = {
+ type: undefined,
+ size: 0,
+ array: undefined,
+ position: 0,
+ readCount: 0,
+ map: undefined,
+ key: null,
};
- return new Proxy(targetObj, handler);
- },
- checkObjectBound: function (objName) {
- native function $BindNativeFunctionName$();
- if (window.hasOwnProperty(objName)) {
- // quick check
- return Promise.resolve(true);
- }
- return $BindNativeFunctionName$(objName);
- },
- deleteObjectBound: function (objName) {
- native function $UnbindNativeFunctionName$();
- $UnbindNativeFunctionName$(objName);
- },
- $EvaluateScriptFunctionName$: function (fn) {
- return JSON.stringify(fn(), objectsStringifier());
+ this.stack.push(partialState);
+ }
+ return this.stack[this.stackHeadPosition];
+ }
+ release(state) {
+ const topStackState = this.stack[this.stackHeadPosition];
+ if (topStackState !== state) {
+ throw new Error("Invalid stack state. Released state is not on top of the stack.");
+ }
+ if (state.type === STATE_ARRAY) {
+ const partialState = state;
+ partialState.size = 0;
+ partialState.array = undefined;
+ partialState.position = 0;
+ partialState.type = undefined;
+ }
+ if (state.type === STATE_MAP_KEY || state.type === STATE_MAP_VALUE) {
+ const partialState = state;
+ partialState.size = 0;
+ partialState.map = undefined;
+ partialState.readCount = 0;
+ partialState.type = undefined;
+ }
+ this.stackHeadPosition--;
+ }
+ reset() {
+ this.stack.length = 0;
+ this.stackHeadPosition = -1;
+ }
+ }
+ const HEAD_BYTE_REQUIRED = -1;
+ const EMPTY_VIEW = new DataView(new ArrayBuffer(0));
+ const EMPTY_BYTES = new Uint8Array(EMPTY_VIEW.buffer);
+ try {
+ // IE11: The spec says it should throw RangeError,
+ // IE11: but in IE11 it throws TypeError.
+ EMPTY_VIEW.getInt8(0);
+ }
+ catch (e) {
+ if (!(e instanceof RangeError)) {
+ throw new Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access");
+ }
+ }
+ const DataViewIndexOutOfBoundsError = RangeError;
+ const MORE_DATA = new DataViewIndexOutOfBoundsError("Insufficient data");
+ const sharedCachedKeyDecoder = new CachedKeyDecoder();
+ class Decoder {
+ extensionCodec;
+ context;
+ useBigInt64;
+ maxStrLength;
+ maxBinLength;
+ maxArrayLength;
+ maxMapLength;
+ maxExtLength;
+ keyDecoder;
+ totalPos = 0;
+ pos = 0;
+ view = EMPTY_VIEW;
+ bytes = EMPTY_BYTES;
+ headByte = HEAD_BYTE_REQUIRED;
+ stack = new StackPool();
+ constructor(options) {
+ this.extensionCodec = options?.extensionCodec ?? ExtensionCodec.defaultCodec;
+ this.context = options?.context; // needs a type assertion because EncoderOptions has no context property when ContextType is undefined
+ this.useBigInt64 = options?.useBigInt64 ?? false;
+ this.maxStrLength = options?.maxStrLength ?? UINT32_MAX;
+ this.maxBinLength = options?.maxBinLength ?? UINT32_MAX;
+ this.maxArrayLength = options?.maxArrayLength ?? UINT32_MAX;
+ this.maxMapLength = options?.maxMapLength ?? UINT32_MAX;
+ this.maxExtLength = options?.maxExtLength ?? UINT32_MAX;
+ this.keyDecoder = options?.keyDecoder !== undefined ? options.keyDecoder : sharedCachedKeyDecoder;
+ }
+ reinitializeState() {
+ this.totalPos = 0;
+ this.headByte = HEAD_BYTE_REQUIRED;
+ this.stack.reset();
+ // view, bytes, and pos will be re-initialized in setBuffer()
+ }
+ setBuffer(buffer) {
+ this.bytes = ensureUint8Array(buffer);
+ this.view = createDataView(this.bytes);
+ this.pos = 0;
+ }
+ appendBuffer(buffer) {
+ if (this.headByte === HEAD_BYTE_REQUIRED && !this.hasRemaining(1)) {
+ this.setBuffer(buffer);
+ }
+ else {
+ const remainingData = this.bytes.subarray(this.pos);
+ const newData = ensureUint8Array(buffer);
+ // concat remainingData + newData
+ const newBuffer = new Uint8Array(remainingData.length + newData.length);
+ newBuffer.set(remainingData);
+ newBuffer.set(newData, remainingData.length);
+ this.setBuffer(newBuffer);
+ }
+ }
+ hasRemaining(size) {
+ return this.view.byteLength - this.pos >= size;
+ }
+ createExtraByteError(posToShow) {
+ const { view, pos } = this;
+ return new RangeError(`Extra ${view.byteLength - pos} of ${view.byteLength} byte(s) found at buffer[${posToShow}]`);
+ }
+ /**
+ * @throws {@link DecodeError}
+ * @throws {@link RangeError}
+ */
+ decode(buffer) {
+ this.reinitializeState();
+ this.setBuffer(buffer);
+ const object = this.doDecodeSync();
+ if (this.hasRemaining(1)) {
+ throw this.createExtraByteError(this.pos);
+ }
+ return object;
+ }
+ *decodeMulti(buffer) {
+ this.reinitializeState();
+ this.setBuffer(buffer);
+ while (this.hasRemaining(1)) {
+ yield this.doDecodeSync();
+ }
+ }
+ async decodeAsync(stream) {
+ let decoded = false;
+ let object;
+ for await (const buffer of stream) {
+ if (decoded) {
+ throw this.createExtraByteError(this.totalPos);
+ }
+ this.appendBuffer(buffer);
+ try {
+ object = this.doDecodeSync();
+ decoded = true;
+ }
+ catch (e) {
+ if (!(e instanceof DataViewIndexOutOfBoundsError)) {
+ throw e; // rethrow
+ }
+ // fallthrough
+ }
+ this.totalPos += this.pos;
+ }
+ if (decoded) {
+ if (this.hasRemaining(1)) {
+ throw this.createExtraByteError(this.totalPos);
+ }
+ return object;
+ }
+ const { headByte, pos, totalPos } = this;
+ throw new RangeError(`Insufficient data in parsing ${prettyByte(headByte)} at ${totalPos} (${pos} in the current buffer)`);
+ }
+ decodeArrayStream(stream) {
+ return this.decodeMultiAsync(stream, true);
+ }
+ decodeStream(stream) {
+ return this.decodeMultiAsync(stream, false);
+ }
+ async *decodeMultiAsync(stream, isArray) {
+ let isArrayHeaderRequired = isArray;
+ let arrayItemsLeft = -1;
+ for await (const buffer of stream) {
+ if (isArray && arrayItemsLeft === 0) {
+ throw this.createExtraByteError(this.totalPos);
+ }
+ this.appendBuffer(buffer);
+ if (isArrayHeaderRequired) {
+ arrayItemsLeft = this.readArraySize();
+ isArrayHeaderRequired = false;
+ this.complete();
+ }
+ try {
+ while (true) {
+ yield this.doDecodeSync();
+ if (--arrayItemsLeft === 0) {
+ break;
+ }
+ }
+ }
+ catch (e) {
+ if (!(e instanceof DataViewIndexOutOfBoundsError)) {
+ throw e; // rethrow
+ }
+ // fallthrough
+ }
+ this.totalPos += this.pos;
+ }
+ }
+ doDecodeSync() {
+ DECODE: while (true) {
+ const headByte = this.readHeadByte();
+ let object;
+ if (headByte >= 0xe0) {
+ // negative fixint (111x xxxx) 0xe0 - 0xff
+ object = headByte - 0x100;
+ }
+ else if (headByte < 0xc0) {
+ if (headByte < 0x80) {
+ // positive fixint (0xxx xxxx) 0x00 - 0x7f
+ object = headByte;
+ }
+ else if (headByte < 0x90) {
+ // fixmap (1000 xxxx) 0x80 - 0x8f
+ const size = headByte - 0x80;
+ if (size !== 0) {
+ this.pushMapState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = {};
+ }
+ }
+ else if (headByte < 0xa0) {
+ // fixarray (1001 xxxx) 0x90 - 0x9f
+ const size = headByte - 0x90;
+ if (size !== 0) {
+ this.pushArrayState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = [];
+ }
+ }
+ else {
+ // fixstr (101x xxxx) 0xa0 - 0xbf
+ const byteLength = headByte - 0xa0;
+ object = this.decodeUtf8String(byteLength, 0);
+ }
+ }
+ else if (headByte === 0xc0) {
+ // nil
+ object = null;
+ }
+ else if (headByte === 0xc2) {
+ // false
+ object = false;
+ }
+ else if (headByte === 0xc3) {
+ // true
+ object = true;
+ }
+ else if (headByte === 0xca) {
+ // float 32
+ object = this.readF32();
+ }
+ else if (headByte === 0xcb) {
+ // float 64
+ object = this.readF64();
+ }
+ else if (headByte === 0xcc) {
+ // uint 8
+ object = this.readU8();
+ }
+ else if (headByte === 0xcd) {
+ // uint 16
+ object = this.readU16();
+ }
+ else if (headByte === 0xce) {
+ // uint 32
+ object = this.readU32();
+ }
+ else if (headByte === 0xcf) {
+ // uint 64
+ if (this.useBigInt64) {
+ object = this.readU64AsBigInt();
+ }
+ else {
+ object = this.readU64();
+ }
+ }
+ else if (headByte === 0xd0) {
+ // int 8
+ object = this.readI8();
+ }
+ else if (headByte === 0xd1) {
+ // int 16
+ object = this.readI16();
+ }
+ else if (headByte === 0xd2) {
+ // int 32
+ object = this.readI32();
+ }
+ else if (headByte === 0xd3) {
+ // int 64
+ if (this.useBigInt64) {
+ object = this.readI64AsBigInt();
+ }
+ else {
+ object = this.readI64();
+ }
+ }
+ else if (headByte === 0xd9) {
+ // str 8
+ const byteLength = this.lookU8();
+ object = this.decodeUtf8String(byteLength, 1);
+ }
+ else if (headByte === 0xda) {
+ // str 16
+ const byteLength = this.lookU16();
+ object = this.decodeUtf8String(byteLength, 2);
+ }
+ else if (headByte === 0xdb) {
+ // str 32
+ const byteLength = this.lookU32();
+ object = this.decodeUtf8String(byteLength, 4);
+ }
+ else if (headByte === 0xdc) {
+ // array 16
+ const size = this.readU16();
+ if (size !== 0) {
+ this.pushArrayState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = [];
+ }
+ }
+ else if (headByte === 0xdd) {
+ // array 32
+ const size = this.readU32();
+ if (size !== 0) {
+ this.pushArrayState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = [];
+ }
+ }
+ else if (headByte === 0xde) {
+ // map 16
+ const size = this.readU16();
+ if (size !== 0) {
+ this.pushMapState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = {};
+ }
+ }
+ else if (headByte === 0xdf) {
+ // map 32
+ const size = this.readU32();
+ if (size !== 0) {
+ this.pushMapState(size);
+ this.complete();
+ continue DECODE;
+ }
+ else {
+ object = {};
+ }
+ }
+ else if (headByte === 0xc4) {
+ // bin 8
+ const size = this.lookU8();
+ object = this.decodeBinary(size, 1);
+ }
+ else if (headByte === 0xc5) {
+ // bin 16
+ const size = this.lookU16();
+ object = this.decodeBinary(size, 2);
+ }
+ else if (headByte === 0xc6) {
+ // bin 32
+ const size = this.lookU32();
+ object = this.decodeBinary(size, 4);
+ }
+ else if (headByte === 0xd4) {
+ // fixext 1
+ object = this.decodeExtension(1, 0);
+ }
+ else if (headByte === 0xd5) {
+ // fixext 2
+ object = this.decodeExtension(2, 0);
+ }
+ else if (headByte === 0xd6) {
+ // fixext 4
+ object = this.decodeExtension(4, 0);
+ }
+ else if (headByte === 0xd7) {
+ // fixext 8
+ object = this.decodeExtension(8, 0);
+ }
+ else if (headByte === 0xd8) {
+ // fixext 16
+ object = this.decodeExtension(16, 0);
+ }
+ else if (headByte === 0xc7) {
+ // ext 8
+ const size = this.lookU8();
+ object = this.decodeExtension(size, 1);
+ }
+ else if (headByte === 0xc8) {
+ // ext 16
+ const size = this.lookU16();
+ object = this.decodeExtension(size, 2);
+ }
+ else if (headByte === 0xc9) {
+ // ext 32
+ const size = this.lookU32();
+ object = this.decodeExtension(size, 4);
+ }
+ else {
+ throw new DecodeError(`Unrecognized type byte: ${prettyByte(headByte)}`);
+ }
+ this.complete();
+ const stack = this.stack;
+ while (stack.length > 0) {
+ // arrays and maps
+ const state = stack.top();
+ if (state.type === STATE_ARRAY) {
+ state.array[state.position] = object;
+ state.position++;
+ if (state.position === state.size) {
+ object = state.array;
+ stack.release(state);
+ }
+ else {
+ continue DECODE;
+ }
+ }
+ else if (state.type === STATE_MAP_KEY) {
+ if (!isValidMapKeyType(object)) {
+ throw new DecodeError("The type of key must be string or number but " + typeof object);
+ }
+ if (object === "__proto__") {
+ throw new DecodeError("The key __proto__ is not allowed");
+ }
+ state.key = object;
+ state.type = STATE_MAP_VALUE;
+ continue DECODE;
+ }
+ else {
+ // it must be `state.type === State.MAP_VALUE` here
+ state.map[state.key] = object;
+ state.readCount++;
+ if (state.readCount === state.size) {
+ object = state.map;
+ stack.release(state);
+ }
+ else {
+ state.key = null;
+ state.type = STATE_MAP_KEY;
+ continue DECODE;
+ }
+ }
+ }
+ return object;
+ }
+ }
+ readHeadByte() {
+ if (this.headByte === HEAD_BYTE_REQUIRED) {
+ this.headByte = this.readU8();
+ // console.log("headByte", prettyByte(this.headByte));
+ }
+ return this.headByte;
+ }
+ complete() {
+ this.headByte = HEAD_BYTE_REQUIRED;
+ }
+ readArraySize() {
+ const headByte = this.readHeadByte();
+ switch (headByte) {
+ case 0xdc:
+ return this.readU16();
+ case 0xdd:
+ return this.readU32();
+ default: {
+ if (headByte < 0xa0) {
+ return headByte - 0x90;
+ }
+ else {
+ throw new DecodeError(`Unrecognized array type byte: ${prettyByte(headByte)}`);
+ }
+ }
+ }
+ }
+ pushMapState(size) {
+ if (size > this.maxMapLength) {
+ throw new DecodeError(`Max length exceeded: map length (${size}) > maxMapLengthLength (${this.maxMapLength})`);
+ }
+ this.stack.pushMapState(size);
+ }
+ pushArrayState(size) {
+ if (size > this.maxArrayLength) {
+ throw new DecodeError(`Max length exceeded: array length (${size}) > maxArrayLength (${this.maxArrayLength})`);
+ }
+ this.stack.pushArrayState(size);
+ }
+ decodeUtf8String(byteLength, headerOffset) {
+ if (byteLength > this.maxStrLength) {
+ throw new DecodeError(`Max length exceeded: UTF-8 byte length (${byteLength}) > maxStrLength (${this.maxStrLength})`);
+ }
+ if (this.bytes.byteLength < this.pos + headerOffset + byteLength) {
+ throw MORE_DATA;
+ }
+ const offset = this.pos + headerOffset;
+ let object;
+ if (this.stateIsMapKey() && this.keyDecoder?.canBeCached(byteLength)) {
+ object = this.keyDecoder.decode(this.bytes, offset, byteLength);
+ }
+ else {
+ object = utf8Decode(this.bytes, offset, byteLength);
+ }
+ this.pos += headerOffset + byteLength;
+ return object;
+ }
+ stateIsMapKey() {
+ if (this.stack.length > 0) {
+ const state = this.stack.top();
+ return state.type === STATE_MAP_KEY;
+ }
+ return false;
+ }
+ decodeBinary(byteLength, headOffset) {
+ if (byteLength > this.maxBinLength) {
+ throw new DecodeError(`Max length exceeded: bin length (${byteLength}) > maxBinLength (${this.maxBinLength})`);
+ }
+ if (!this.hasRemaining(byteLength + headOffset)) {
+ throw MORE_DATA;
+ }
+ const offset = this.pos + headOffset;
+ const object = this.bytes.subarray(offset, offset + byteLength);
+ this.pos += headOffset + byteLength;
+ return object;
+ }
+ decodeExtension(size, headOffset) {
+ if (size > this.maxExtLength) {
+ throw new DecodeError(`Max length exceeded: ext length (${size}) > maxExtLength (${this.maxExtLength})`);
+ }
+ const extType = this.view.getInt8(this.pos + headOffset);
+ const data = this.decodeBinary(size, headOffset + 1 /* extType */);
+ return this.extensionCodec.decode(data, extType, this.context);
+ }
+ lookU8() {
+ return this.view.getUint8(this.pos);
+ }
+ lookU16() {
+ return this.view.getUint16(this.pos);
+ }
+ lookU32() {
+ return this.view.getUint32(this.pos);
+ }
+ readU8() {
+ const value = this.view.getUint8(this.pos);
+ this.pos++;
+ return value;
+ }
+ readI8() {
+ const value = this.view.getInt8(this.pos);
+ this.pos++;
+ return value;
+ }
+ readU16() {
+ const value = this.view.getUint16(this.pos);
+ this.pos += 2;
+ return value;
+ }
+ readI16() {
+ const value = this.view.getInt16(this.pos);
+ this.pos += 2;
+ return value;
+ }
+ readU32() {
+ const value = this.view.getUint32(this.pos);
+ this.pos += 4;
+ return value;
+ }
+ readI32() {
+ const value = this.view.getInt32(this.pos);
+ this.pos += 4;
+ return value;
+ }
+ readU64() {
+ const value = getUint64(this.view, this.pos);
+ this.pos += 8;
+ return value;
+ }
+ readI64() {
+ const value = getInt64(this.view, this.pos);
+ this.pos += 8;
+ return value;
+ }
+ readU64AsBigInt() {
+ const value = this.view.getBigUint64(this.pos);
+ this.pos += 8;
+ return value;
+ }
+ readI64AsBigInt() {
+ const value = this.view.getBigInt64(this.pos);
+ this.pos += 8;
+ return value;
+ }
+ readF32() {
+ const value = this.view.getFloat32(this.pos);
+ this.pos += 4;
+ return value;
+ }
+ readF64() {
+ const value = this.view.getFloat64(this.pos);
+ this.pos += 8;
+ return value;
+ }
+ }
+
+ /**
+ * It decodes a single MessagePack object in a buffer.
+ *
+ * This is a synchronous decoding function.
+ * See other variants for asynchronous decoding: {@link decodeAsync}, {@link decodeStream}, or {@link decodeArrayStream}.
+ *
+ * @throws {@link RangeError} if the buffer is incomplete, including the case where the buffer is empty.
+ * @throws {@link DecodeError} if the buffer contains invalid data.
+ */
+ function decode(buffer, options) {
+ const decoder = new Decoder(options);
+ return decoder.decode(buffer);
+ }
+
+ class MsgPackSerializer {
+ static Instance = new MsgPackSerializer();
+ deserialize(value) {
+ return decode(value);
+ }
+ serialize(value, _options) {
+ return encode(value).buffer;
+ }
+ }
+
+ let defaultSerializer = MsgPackSerializer.Instance;
+ const MsgPack = MsgPackSerializer.Instance;
+ const Json = JsonSerializer.Instance;
+ function setDefaultSerializer(serializer) {
+ defaultSerializer = serializer;
+ }
+ function getDefaultSerializer() {
+ return defaultSerializer;
+ }
+ function createPromise(serializer = defaultSerializer) {
+ const result = {};
+ const promise = new Promise(function (resolve, reject) {
+ result.resolve = function (result) {
+ resolve(isArrayBuffer(result)
+ ? serializer.deserialize(result)
+ : result);
+ };
+ result.reject = reject;
+ });
+ result.promise = promise;
+ return result;
+ }
+ function createInterceptor(targetObj, serializer = defaultSerializer) {
+ const functionsMap = new Map();
+ const handler = {
+ get(target, propKey, receiver) {
+ const func = functionsMap.get(propKey);
+ if (func) {
+ return func;
+ }
+ const targetValue = Reflect.get(target, propKey);
+ if (!isFunction(targetValue)) {
+ return targetValue;
+ }
+ const interceptor = function (...args) {
+ let parameters = args;
+ if (args.length > targetValue.length) {
+ parameters = args.slice(0, targetValue.length);
+ parameters.push(args.slice(targetValue.length));
+ }
+ const convertedArgs = parameters.length === 0
+ ? parameters
+ : [serializer.serialize(parameters, { skipReferenceForInitialArrayObject: true })];
+ return targetValue.apply(target, convertedArgs);
+ };
+ functionsMap.set(propKey, interceptor);
+ return interceptor;
}
};
- })();
-}
\ No newline at end of file
+ return new Proxy(targetObj, handler);
+ }
+ function checkObjectBound(objName) {
+ //native function Bind()
+ if (window.hasOwnProperty(objName)) {
+ // quick check
+ return Promise.resolve(true);
+ }
+ return Bind(objName);
+ }
+ function deleteObjectBound(objName) {
+ //native function Unbind()
+ Unbind(objName);
+ }
+ function evaluateScript(fn, serializer = defaultSerializer) {
+ return serializer.serialize(fn());
+ }
+
+ exports.Json = Json;
+ exports.MsgPack = MsgPack;
+ exports.checkObjectBound = checkObjectBound;
+ exports.createInterceptor = createInterceptor;
+ exports.createPromise = createPromise;
+ exports.deleteObjectBound = deleteObjectBound;
+ exports.evaluateScript = evaluateScript;
+ exports.getDefaultSerializer = getDefaultSerializer;
+ exports.setDefaultSerializer = setDefaultSerializer;
+
+ return exports;
+
+})({});
diff --git a/CefGlue.BrowserProcess/ObjectBinding/JavascriptHelper.cs b/CefGlue.BrowserProcess/ObjectBinding/JavascriptHelper.cs
index e8c79351..01e53110 100644
--- a/CefGlue.BrowserProcess/ObjectBinding/JavascriptHelper.cs
+++ b/CefGlue.BrowserProcess/ObjectBinding/JavascriptHelper.cs
@@ -9,10 +9,7 @@ namespace Xilium.CefGlue.BrowserProcess.ObjectBinding
internal static partial class JavascriptHelper
{
private const string CefGlueGlobalScriptFileName = "CefGlueGlobalScript.js";
- private const string GlobalObjectName = "cefglue";
- private const string PromiseFactoryFunctionName = "createPromise";
- private const string InterceptorFactoryFunctionName = "createInterceptor";
- private const string EvaluateScriptFunctionName = "evaluateScript";
+ private const string GlueObjectName = "cefglue";
private const string BindNativeFunctionName = "Bind";
private const string UnbindNativeFunctionName = "Unbind";
@@ -23,15 +20,15 @@ public static void Register(INativeObjectRegistry nativeObjectRegistry)
var currentAssembly = currentType.Assembly;
using (var stream = new StreamReader(currentAssembly.GetManifestResourceStream($"{currentNamespace}.{CefGlueGlobalScriptFileName}")))
{
- var cefGlueGlobalScript = FillScriptPlaceholders(stream.ReadToEnd());
- CefRuntime.RegisterExtension("cefglue", cefGlueGlobalScript, new V8BuiltinFunctionHandler(nativeObjectRegistry));
+ var cefGlueGlobalScript = stream.ReadToEnd();
+ CefRuntime.RegisterExtension(GlueObjectName, cefGlueGlobalScript, new V8BuiltinFunctionHandler(nativeObjectRegistry));
}
}
- public static PromiseHolder CreatePromise(this CefV8Context context)
+ public static PromiseHolder CreatePromise(this CefV8Context context, CefV8Value serializer = null)
{
- var promiseFactory = GetGlobalInnerValue(context, PromiseFactoryFunctionName);
- var promiseData = promiseFactory.ExecuteFunctionWithContext(context, null, new CefV8Value[0]); // create a promise and return the resolve and reject callbacks
+ var promiseFactory = GetGlueValue(context, JsGlueFunction.CreatePromise);
+ var promiseData = promiseFactory.ExecuteFunctionWithContext(context, null, [serializer ?? CefV8Value.CreateUndefined()]); // create a promise and return the resolve and reject callbacks
var promise = promiseData.GetValue("promise");
var resolve = promiseData.GetValue("resolve");
@@ -44,44 +41,38 @@ public static PromiseHolder CreatePromise(this CefV8Context context)
return new PromiseHolder(promise, resolve, reject, context);
}
- public static CefV8Value CreateInterceptorObject(this CefV8Context context, CefV8Value targetObj)
+ public static CefV8Value CreateInterceptorObject(this CefV8Context context, CefV8Value targetObj, CefV8Value serializer)
{
- var interceptorFactory = GetGlobalInnerValue(context, InterceptorFactoryFunctionName);
-
- return interceptorFactory.ExecuteFunctionWithContext(context, null, new[] { targetObj });
+ var interceptorFactory = context.GetGlueValue(JsGlueFunction.CreateInterceptor);
+
+ return interceptorFactory.ExecuteFunctionWithContext(context, null, [targetObj, serializer]);
+ }
+
+ public static CefV8Value GetGlueValue(this CefV8Value global, string innerValueKey)
+ {
+ return global.GetValue(GlueObjectName).GetValue(innerValueKey); // TODO what if cefGlueGlobal == null?
}
- private static CefV8Value GetGlobalInnerValue(CefV8Context context, string innerValueKey)
+ public static CefV8Value GetGlueValue(this CefV8Context context, string innerValueKey)
{
- var global = context.GetGlobal();
- var cefGlueGlobal = global.GetValue(GlobalObjectName); // TODO what if cefGlueGlobal == null?
-
- return cefGlueGlobal.GetValue(innerValueKey);
+ return context.GetGlobal().GetGlueValue(innerValueKey);
}
public static string WrapScriptForEvaluation(string script)
{
- return $"{GlobalObjectName}.{EvaluateScriptFunctionName}(function() {{{script}\n}})";
+ return $"{GlueObjectName}.{JsGlueFunction.EvaluateScript}(function() {{{script}\n}})";
+ }
+
+ public static void SetDefaultSerializer(this CefV8Context context, CefV8Value serializer)
+ {
+ var serializerFunction = context.GetGlueValue(JsGlueFunction.SetDefaultSerializer);
+ serializerFunction.ExecuteFunctionWithContext(context, null, [serializer]);
}
- private static string FillScriptPlaceholders(string script)
+ public static CefV8Value GetDefaultSerializer(this CefV8Context context)
{
- var sb = new StringBuilder(script);
- return sb
- .Replace("$GlobalObjectName$", GlobalObjectName)
- .Replace("$JsonIdAttribute$", JsonAttributes.Id)
- .Replace("$JsonRefAttribute$", JsonAttributes.Ref)
- .Replace("$JsonValuesAttribute$", JsonAttributes.Values)
- .Replace("$DataMarkerLength$", DataMarkers.MarkerLength.ToString())
- .Replace("$StringMarker$", DataMarkers.StringMarker)
- .Replace("$DateTimeMarker$", DataMarkers.DateTimeMarker)
- .Replace("$BinaryMarker$", DataMarkers.BinaryMarker)
- .Replace("$PromiseFactoryFunctionName$", PromiseFactoryFunctionName)
- .Replace("$InterceptorFactoryFunctionName$", InterceptorFactoryFunctionName)
- .Replace("$BindNativeFunctionName$", BindNativeFunctionName)
- .Replace("$UnbindNativeFunctionName$", UnbindNativeFunctionName)
- .Replace("$EvaluateScriptFunctionName$", EvaluateScriptFunctionName)
- .ToString();
+ var serializerFunction = context.GetGlueValue(JsGlueFunction.GetDefaultSerializer);
+ return serializerFunction.ExecuteFunctionWithContext(context, null, []);
}
}
}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/JavascriptToNativeDispatcherRenderSide.cs b/CefGlue.BrowserProcess/ObjectBinding/JavascriptToNativeDispatcherRenderSide.cs
index 0b2c9013..6ba1fa15 100644
--- a/CefGlue.BrowserProcess/ObjectBinding/JavascriptToNativeDispatcherRenderSide.cs
+++ b/CefGlue.BrowserProcess/ObjectBinding/JavascriptToNativeDispatcherRenderSide.cs
@@ -1,18 +1,21 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using Xilium.CefGlue.Common.Shared.Helpers;
using Xilium.CefGlue.Common.Shared.RendererProcessCommunication;
namespace Xilium.CefGlue.BrowserProcess.ObjectBinding
{
+ internal record ObjectRegistration(ObjectInfo Info, string Messaging);
+
internal class JavascriptToNativeDispatcherRenderSide : INativeObjectRegistry
{
private static volatile int lastCallId;
private readonly object _registrationSyncRoot = new object();
- private readonly Dictionary _registeredObjects = new Dictionary();
+ private readonly Dictionary _registeredObjects = new Dictionary();
private readonly ConcurrentDictionary _pendingCalls = new ConcurrentDictionary();
private readonly ConcurrentDictionary> _pendingBoundQueryTasks = new ConcurrentDictionary>();
@@ -28,17 +31,18 @@ public JavascriptToNativeDispatcherRenderSide(MessageDispatcher dispatcher)
private void HandleNativeObjectRegistration(MessageReceivedEventArgs args)
{
var message = Messages.NativeObjectRegistrationRequest.FromCefMessage(args.Message);
- var objectInfo = new ObjectRegistrationInfo(message.ObjectName, message.MethodsNames);
+ var registration = new ObjectRegistration(message.ObjectInfo, message.Messaging);
lock (_registrationSyncRoot)
{
- if (_registeredObjects.ContainsKey(objectInfo.Name))
+ string objectName = registration.Info.Name;
+ if (_registeredObjects.ContainsKey(objectName))
{
return;
}
- _registeredObjects.Add(objectInfo.Name, objectInfo);
- var taskSource = _pendingBoundQueryTasks.GetOrAdd(objectInfo.Name, _ => new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously));
+ _registeredObjects.Add(objectName, registration);
+ var taskSource = _pendingBoundQueryTasks.GetOrAdd(objectName, _ => new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously));
// register objects in the main frame
var frame = args.Browser.GetMainFrame();
@@ -50,7 +54,7 @@ private void HandleNativeObjectRegistration(MessageReceivedEventArgs args)
return;
}
- var objectCreated = CreateNativeObjects(new[] { objectInfo }, context);
+ var objectCreated = CreateNativeObjects(new [] { registration }, context);
if (!objectCreated)
{
@@ -74,32 +78,6 @@ private void HandleNativeObjectUnregistration(MessageReceivedEventArgs args)
}
}
- private PromiseHolder HandleNativeObjectCall(Messages.NativeObjectCallRequest message)
- {
- message.CallId = lastCallId++;
-
- using (var context = CefV8Context.GetCurrentContext().EnterOrFail(shallDispose: false)) // context will be released when promise is resolved
- {
- var frame = context.V8Context.GetFrame();
- if (frame == null)
- {
- // TODO, what now?
- return null;
- }
-
- var promiseHolder = context.V8Context.CreatePromise();
- if (!_pendingCalls.TryAdd(message.CallId, promiseHolder))
- {
- throw new InvalidOperationException("Call id already exists");
- }
-
- var cefMessage = message.ToCefProcessMessage();
- frame.SendProcessMessage(CefProcessId.Browser, cefMessage);
-
- return promiseHolder;
- }
- }
-
private void HandleNativeObjectCallResult(MessageReceivedEventArgs args)
{
var message = Messages.NativeObjectCallResult.FromCefMessage(args.Message);
@@ -112,7 +90,7 @@ private void HandleNativeObjectCallResult(MessageReceivedEventArgs args)
{
if (message.Success)
{
- var value = CefV8Value.CreateString(message.ResultAsJson);
+ var value = CefV8Value.CreateArrayBuffer(message.Result);
resolve(value);
}
else
@@ -165,27 +143,74 @@ void ReleasePromiseHolder(PromiseHolder promiseHolder)
}
}
- private bool CreateNativeObjects(IEnumerable objectInfos, CefV8Context context)
+ private bool CreateNativeObjects(IEnumerable objectRegistrations, CefV8Context context)
{
if (context.Enter())
{
try
{
var global = context.GetGlobal();
- foreach (var objectInfo in objectInfos)
+ foreach (var registration in objectRegistrations)
{
- var handler = new V8FunctionHandler(objectInfo.Name, HandleNativeObjectCall);
-
+ ObjectInfo objectInfo = registration.Info;
+
+ var handler = new V8FunctionHandler((string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception) =>
+ {
+ if (arguments.Length > 1)
+ {
+ throw new ArgumentException($"The array must be either empty or contain only one argument, a json string. The array has {arguments.Length} elements.", nameof(arguments));
+ }
+
+ using var context = CefV8Context.GetCurrentContext().EnterOrFail(shallDispose: false); // context will be released when promise is resolved
+ var message = new Messages.NativeObjectCallRequest()
+ {
+ ObjectName = objectInfo.Name,
+ CallId = lastCallId++,
+ MemberName = name,
+ Arguments = arguments.FirstOrDefault()?.GetArrayBuffer() ?? []
+ };
+
+ var frame = context.V8Context.GetFrame();
+ if (frame == null)
+ {
+ // TODO, what now?
+ returnValue = null;
+ exception = "Failed to create promise";
+ }
+
+ CefV8Value serializer = obj.GetValue("serializer");
+ PromiseHolder promiseHolder = context.V8Context.CreatePromise(serializer);
+ if (!_pendingCalls.TryAdd(message.CallId, promiseHolder))
+ {
+ throw new InvalidOperationException("Call id already exists");
+ }
+
+ var cefMessage = message.ToCefProcessMessage();
+ frame.SendProcessMessage(CefProcessId.Browser, cefMessage);
+
+ returnValue = promiseHolder.Promise;
+ exception = null;
+
+ return true;
+ });
+
+ CefV8Value serializer = registration.Messaging != null
+ ? global.GetGlueValue(registration.Messaging)
+ : CefV8Value.CreateUndefined();
+
var v8Obj = CefV8Value.CreateObject();
- foreach (var methodName in objectInfo.MethodsNames)
+ v8Obj.SetValue("serializer", serializer, CefV8PropertyAttribute.ReadOnly);
+
+ foreach (var method in objectInfo.Methods)
{
- var v8Function = CefV8Value.CreateFunction(methodName, handler);
- v8Obj.SetValue(methodName, v8Function);
+ var v8Function = CefV8Value.CreateFunction(method.Name, handler);
+ var result = v8Function.SetValue("length", CefV8Value.CreateInt(method.ParameterCount), CefV8PropertyAttribute.ReadOnly);
+ v8Obj.SetValue(method.Name, v8Function);
}
// the interceptor object is a proxy that will trap all calls to the native object and
// and pass the arguments serialized as json (to the native method)
- var interceptorObj = JavascriptHelper.CreateInterceptorObject(context, v8Obj);
+ var interceptorObj = JavascriptHelper.CreateInterceptorObject(context, v8Obj, serializer);
global.SetValue(objectInfo.Name, interceptorObj);
}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/JsGlueConstant.cs b/CefGlue.BrowserProcess/ObjectBinding/JsGlueConstant.cs
new file mode 100644
index 00000000..89253491
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/JsGlueConstant.cs
@@ -0,0 +1,8 @@
+
+namespace Xilium.CefGlue.BrowserProcess;
+
+public static class JsGlueConstant
+{
+ public const string MsgPack = "MsgPack";
+ public const string Json = "Json";
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/JsGlueFunction.cs b/CefGlue.BrowserProcess/ObjectBinding/JsGlueFunction.cs
new file mode 100644
index 00000000..ff6a6660
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/JsGlueFunction.cs
@@ -0,0 +1,13 @@
+
+namespace Xilium.CefGlue.BrowserProcess;
+
+public static class JsGlueFunction
+{
+ public const string SetDefaultSerializer = "setDefaultSerializer";
+ public const string GetDefaultSerializer = "getDefaultSerializer";
+ public const string CreatePromise = "createPromise";
+ public const string CreateInterceptor = "createInterceptor";
+ public const string CheckObjectBound = "checkObjectBound";
+ public const string DeleteObjectBound = "deleteObjectBound";
+ public const string EvaluateScript = "evaluateScript";
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/ScriptFunctions.cs b/CefGlue.BrowserProcess/ObjectBinding/ScriptFunctions.cs
new file mode 100644
index 00000000..53a4a902
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/ScriptFunctions.cs
@@ -0,0 +1,11 @@
+
+namespace Xilium.CefGlue.BrowserProcess;
+
+public static class ScriptFunctions
+{
+ public const string CreatePromise = "createPromise";
+ public const string CreateInterceptor = "createInterceptor";
+ public const string CheckObjectBound = "checkObjectBound";
+ public const string DeleteObjectBound = "deleteObjectBound";
+ public const string EvaluateScript = "evaluateScript";
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/V8FunctionHandler.cs b/CefGlue.BrowserProcess/ObjectBinding/V8FunctionHandler.cs
index 578cbcb8..00c5a2ac 100644
--- a/CefGlue.BrowserProcess/ObjectBinding/V8FunctionHandler.cs
+++ b/CefGlue.BrowserProcess/ObjectBinding/V8FunctionHandler.cs
@@ -5,45 +5,20 @@
namespace Xilium.CefGlue.BrowserProcess.ObjectBinding
{
+ delegate bool CallHandler(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception);
+
internal class V8FunctionHandler : CefV8Handler
{
- private readonly string _objectName;
- private readonly Func _functionCallHandler;
+ private readonly CallHandler _functionCallHandler;
- public V8FunctionHandler(string objectName, Func functionCallHandler)
+ public V8FunctionHandler(CallHandler functionCallHandler)
{
- _objectName = objectName;
_functionCallHandler = functionCallHandler;
}
protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
{
- if (arguments.Length > 1)
- {
- throw new ArgumentException($"The array must be either empty or contain only one argument, a json string. The array has {arguments.Length} elements.", nameof(arguments));
- }
-
- var message = new Messages.NativeObjectCallRequest()
- {
- ObjectName = _objectName,
- MemberName = name,
- ArgumentsAsJson = arguments.FirstOrDefault()?.GetStringValue() ?? string.Empty
- };
-
- var promiseHolder = _functionCallHandler(message);
-
- if (promiseHolder != null)
- {
- returnValue = promiseHolder.Promise;
- exception = null;
- }
- else
- {
- returnValue = null;
- exception = "Failed to create promise";
- }
-
- return true;
+ return _functionCallHandler(name, obj, arguments, out returnValue, out exception);
}
}
}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/.editorconfig b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.editorconfig
new file mode 100644
index 00000000..26b5383a
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.editorconfig
@@ -0,0 +1,17 @@
+# Remove the line below if you want to inherit .editorconfig settings from higher directories
+root = true
+
+#### Core EditorConfig Options ####
+
+[*]
+charset = utf-8
+
+# New line preferences
+insert_final_newline = true
+end_of_line = lf
+
+# Indentation and spacing
+indent_style = space
+indent_size = 3
+tab_width = 3
+max_line_length = 132
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/.gitignore b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.gitignore
new file mode 100644
index 00000000..fc963132
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.gitignore
@@ -0,0 +1,2 @@
+dist/
+.vscode/
\ No newline at end of file
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/.vscode/launch.json b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.vscode/launch.json
new file mode 100644
index 00000000..155c302f
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/.vscode/launch.json
@@ -0,0 +1,34 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "tsx",
+ "type": "node",
+ "request": "launch",
+ // Debug current file in VSCode
+ "program": "${file}",
+ "args": [ "src/main.ts", "dist/ScriptFunctions.cs" ],
+ /*
+ * Path to tsx binary
+ * Assuming locally installed
+ */
+ "runtimeExecutable": "tsx",
+ /*
+ * Open terminal when debugging starts (Optional)
+ * Useful to see console.logs
+ */
+ "console": "integratedTerminal",
+ "internalConsoleOptions": "neverOpen",
+ // Files to exclude from debugger (e.g. call stack)
+ "skipFiles": [
+ // Node.js internal core modules
+ "/**",
+ // Ignore all dependencies (optional)
+ "${workspaceFolder}/node_modules/**",
+ ],
+ }
+ ]
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/eslint.config.mjs b/CefGlue.BrowserProcess/ObjectBinding/js-glue/eslint.config.mjs
new file mode 100644
index 00000000..9049700e
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/eslint.config.mjs
@@ -0,0 +1,20 @@
+import globals from "globals";
+import pluginJs from "@eslint/js";
+import tseslint from "typescript-eslint";
+import prettier from 'prettier';
+
+export default [
+ {
+ plugins: {
+ prettier
+ },
+ files: ["**/*.{js,mjs,cjs,ts}"],
+ languageOptions: { globals: globals.browser },
+ rules: {
+ 'prettier/prettier': 'error',
+ }
+ },
+ prettier.configs.recommended,
+ pluginJs.configs.recommended,
+ tseslint.configs.recommended,
+];
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/package-lock.json b/CefGlue.BrowserProcess/ObjectBinding/js-glue/package-lock.json
new file mode 100644
index 00000000..2ec07050
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/package-lock.json
@@ -0,0 +1,3024 @@
+{
+ "name": "js-glue",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "js-glue",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@msgpack/msgpack": "^3.0.0-beta2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.10.0",
+ "@rollup/plugin-node-resolve": "^15.3.0",
+ "@rollup/plugin-terser": "^0.4.4",
+ "@rollup/plugin-typescript": "^11.1.6",
+ "@types/node": "^22.5.5",
+ "eslint": "^9.10.0",
+ "eslint-config-prettier": "^9.1.0",
+ "eslint-plugin-prettier": "^5.2.1",
+ "globals": "^15.9.0",
+ "prettier": "3.3.3",
+ "rollup": "^4.21.3",
+ "shx": "^0.3.4",
+ "tsx": "^4.19.1",
+ "typescript": "^5.6.2",
+ "typescript-eslint": "^8.5.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
+ "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
+ "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
+ "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
+ "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
+ "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
+ "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
+ "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
+ "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
+ "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
+ "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
+ "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
+ "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
+ "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
+ "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
+ "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
+ "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
+ "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
+ "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
+ "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
+ "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
+ "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
+ "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
+ "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
+ "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
+ "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
+ "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.4",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
+ "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
+ "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
+ "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
+ "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
+ "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@msgpack/msgpack": {
+ "version": "3.0.0-beta2",
+ "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.0.0-beta2.tgz",
+ "integrity": "sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
+ "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
+ "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-terser": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
+ "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "serialize-javascript": "^6.0.1",
+ "smob": "^1.0.0",
+ "terser": "^5.17.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-typescript": {
+ "version": "11.1.6",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz",
+ "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.1.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.14.0||^3.0.0||^4.0.0",
+ "tslib": "*",
+ "typescript": ">=3.7.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ },
+ "tslib": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz",
+ "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz",
+ "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz",
+ "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz",
+ "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz",
+ "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz",
+ "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz",
+ "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz",
+ "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz",
+ "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz",
+ "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz",
+ "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz",
+ "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz",
+ "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz",
+ "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz",
+ "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz",
+ "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.5.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
+ "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.19.2"
+ }
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz",
+ "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.5.0",
+ "@typescript-eslint/type-utils": "8.5.0",
+ "@typescript-eslint/utils": "8.5.0",
+ "@typescript-eslint/visitor-keys": "8.5.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz",
+ "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.5.0",
+ "@typescript-eslint/types": "8.5.0",
+ "@typescript-eslint/typescript-estree": "8.5.0",
+ "@typescript-eslint/visitor-keys": "8.5.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz",
+ "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.5.0",
+ "@typescript-eslint/visitor-keys": "8.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz",
+ "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.5.0",
+ "@typescript-eslint/utils": "8.5.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz",
+ "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz",
+ "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "8.5.0",
+ "@typescript-eslint/visitor-keys": "8.5.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz",
+ "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.5.0",
+ "@typescript-eslint/types": "8.5.0",
+ "@typescript-eslint/typescript-estree": "8.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz",
+ "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.5.0",
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
+ "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.23.1",
+ "@esbuild/android-arm": "0.23.1",
+ "@esbuild/android-arm64": "0.23.1",
+ "@esbuild/android-x64": "0.23.1",
+ "@esbuild/darwin-arm64": "0.23.1",
+ "@esbuild/darwin-x64": "0.23.1",
+ "@esbuild/freebsd-arm64": "0.23.1",
+ "@esbuild/freebsd-x64": "0.23.1",
+ "@esbuild/linux-arm": "0.23.1",
+ "@esbuild/linux-arm64": "0.23.1",
+ "@esbuild/linux-ia32": "0.23.1",
+ "@esbuild/linux-loong64": "0.23.1",
+ "@esbuild/linux-mips64el": "0.23.1",
+ "@esbuild/linux-ppc64": "0.23.1",
+ "@esbuild/linux-riscv64": "0.23.1",
+ "@esbuild/linux-s390x": "0.23.1",
+ "@esbuild/linux-x64": "0.23.1",
+ "@esbuild/netbsd-x64": "0.23.1",
+ "@esbuild/openbsd-arm64": "0.23.1",
+ "@esbuild/openbsd-x64": "0.23.1",
+ "@esbuild/sunos-x64": "0.23.1",
+ "@esbuild/win32-arm64": "0.23.1",
+ "@esbuild/win32-ia32": "0.23.1",
+ "@esbuild/win32-x64": "0.23.1"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
+ "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.11.0",
+ "@eslint/config-array": "^0.18.0",
+ "@eslint/eslintrc": "^3.1.0",
+ "@eslint/js": "9.10.0",
+ "@eslint/plugin-kit": "^0.1.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.3.0",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.0.2",
+ "eslint-visitor-keys": "^4.0.0",
+ "espree": "^10.1.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
+ "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.9.1"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": "*",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
+ "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
+ "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.12.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
+ "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "15.9.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+ "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+ "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz",
+ "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.21.3",
+ "@rollup/rollup-android-arm64": "4.21.3",
+ "@rollup/rollup-darwin-arm64": "4.21.3",
+ "@rollup/rollup-darwin-x64": "4.21.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.21.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.21.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.21.3",
+ "@rollup/rollup-linux-arm64-musl": "4.21.3",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.21.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.21.3",
+ "@rollup/rollup-linux-x64-gnu": "4.21.3",
+ "@rollup/rollup-linux-x64-musl": "4.21.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.21.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.21.3",
+ "@rollup/rollup-win32-x64-msvc": "4.21.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shelljs": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/shx": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
+ "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.3",
+ "shelljs": "^0.8.5"
+ },
+ "bin": {
+ "shx": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/smob": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
+ "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/synckit": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
+ "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.33.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.33.0.tgz",
+ "integrity": "sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/tsx": {
+ "version": "4.19.1",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
+ "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.23.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
+ "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.5.0.tgz",
+ "integrity": "sha512-uD+XxEoSIvqtm4KE97etm32Tn5MfaZWgWfMMREStLxR6JzvHkc2Tkj7zhTEK5XmtpTmKHNnG8Sot6qDfhHtR1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.5.0",
+ "@typescript-eslint/parser": "8.5.0",
+ "@typescript-eslint/utils": "8.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.19.8",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/package.json b/CefGlue.BrowserProcess/ObjectBinding/js-glue/package.json
new file mode 100644
index 00000000..6afe6129
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "js-glue",
+ "version": "1.0.0",
+ "description": "JavaScript side glue code fro CefGlue",
+ "main": "index.js",
+ "scripts": {
+ "build": "rollup -c && tsx tools/extract-symbols.ts dist/main.d.ts ../JsGlue Xilium.CefGlue.BrowserProcess && shx cp dist/main.js ../CefGlueGlobalScript.js",
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\""
+ },
+ "author": "",
+ "license": "ISC",
+ "devDependencies": {
+ "@eslint/js": "^9.10.0",
+ "@rollup/plugin-node-resolve": "^15.3.0",
+ "@rollup/plugin-terser": "^0.4.4",
+ "@rollup/plugin-typescript": "^11.1.6",
+ "@types/node": "^22.5.5",
+ "eslint": "^9.10.0",
+ "eslint-config-prettier": "^9.1.0",
+ "eslint-plugin-prettier": "^5.2.1",
+ "globals": "^15.9.0",
+ "prettier": "3.3.3",
+ "rollup": "^4.21.3",
+ "shx": "^0.3.4",
+ "tsx": "^4.19.1",
+ "typescript": "^5.6.2",
+ "typescript-eslint": "^8.5.0"
+ },
+ "dependencies": {
+ "@msgpack/msgpack": "^3.0.0-beta2"
+ }
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/prettier.config.mjs b/CefGlue.BrowserProcess/ObjectBinding/js-glue/prettier.config.mjs
new file mode 100644
index 00000000..b74bfc73
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/prettier.config.mjs
@@ -0,0 +1,6 @@
+export default {
+ trailingComma: "es2022",
+ tabWidth: 4,
+ semi: false,
+ singleQuote: true,
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/rollup.config.mjs b/CefGlue.BrowserProcess/ObjectBinding/js-glue/rollup.config.mjs
new file mode 100644
index 00000000..ef41cc28
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/rollup.config.mjs
@@ -0,0 +1,20 @@
+import typescript from '@rollup/plugin-typescript'
+import terser from '@rollup/plugin-terser'
+import nodeResolve from '@rollup/plugin-node-resolve'
+
+export default {
+ input: {
+ 'main': 'src/main.ts',
+ },
+ output: {
+ format: 'iife',
+ dir: 'dist',
+ name: 'cefglue',
+ compact: true,
+ },
+ plugins: [
+ typescript({ rootDir: 'src', declarationDir: 'dist', declaration: true }),
+ terser(),
+ nodeResolve(),
+ ]
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/json-serializer.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/json-serializer.ts
new file mode 100644
index 00000000..cd5d58c6
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/json-serializer.ts
@@ -0,0 +1,141 @@
+import { Serializer } from "./main";
+import { isString } from "./type-check";
+
+const idPropertyName = "$id";
+const refPropertyName = "$ref";
+const valuesPropertyName = "$values";
+
+// special data markers used to distinguish the several string types
+enum TypeMarker {
+ dateTime = "D",
+ string = "S",
+ binary = "B",
+}
+
+function convertBase64ToBinary(value: string) {
+ const byteCharacters = atob(value);
+ const byteArray = new Array(byteCharacters.length);
+ for (let i = 0; i < byteCharacters.length; i++) {
+ byteArray[i] = byteCharacters.charCodeAt(i);
+ }
+ return new Uint8Array(byteArray);;
+}
+function convertBinaryToBase64(byteArray: Uint8Array) {
+ return btoa(String.fromCharCode(...byteArray));
+}
+
+export class JsonSerializer implements Serializer {
+ static Instance = new JsonSerializer();
+
+ static convertStringToJsType(value: string) {
+ switch (value.substring(0, 1)) {
+ case TypeMarker.string:
+ return value.substring(1);
+ case TypeMarker.dateTime:
+ return new Date(value.substring(1));
+ case TypeMarker.binary:
+ return convertBase64ToBinary(value.substring(1));
+ }
+ return value;
+ }
+
+ deserialize(value: ArrayBuffer): T {
+ const refs = new Map();
+ const pendingRefs = new Map();
+ const textDecoder = new TextDecoder();
+ return JSON.parse(textDecoder.decode(value), function (name, value) {
+ if (value) {
+ const id = value[idPropertyName];
+ if (id !== undefined) {
+ delete value[idPropertyName];
+ const pendingRef = pendingRefs.get(id);
+ if (pendingRef) {
+ Object.assign(pendingRef, value);
+ value = pendingRef;
+ }
+ refs.set(id, value);
+ return value;
+ }
+ const refId = value[refPropertyName];
+ if (refId !== undefined) {
+ const ref = refs.get(refId);
+ if (ref) {
+ return ref;
+ }
+ const pendingRef = pendingRefs.get(refId);
+ if (pendingRef) {
+ value = pendingRef;
+ } else {
+ value = {};
+ pendingRefs.set(refId, value);
+ }
+ return value;
+ }
+ if (isString(value)) {
+ return JsonSerializer.convertStringToJsType(value);
+ }
+ }
+ return value;
+ });
+ }
+
+ serialize(value: any, options: Partial<{ skipReferenceForInitialArrayObject: boolean; }> = {}): ArrayBuffer {
+ const refs = new Map();
+ const marker = Symbol("marker");
+ const textEncoder = new TextEncoder();
+ return textEncoder.encode(JSON.stringify(value, function (this: object, key: string, value: object) {
+ if (value === null || value === undefined) {
+ return value;
+ }
+
+ if (key === idPropertyName || key === refPropertyName || (key === valuesPropertyName && Reflect.has(this, marker))) {
+ // its the id, ref or special values property
+ return value;
+ }
+ switch (typeof value) {
+ case "string":
+ // case the property is of type Date, the argument 'value' is of type 'string',
+ // in this case, we need to return the date as a string, but prefixed with the DateTimeMarker
+ // (there can be a remote problem that the property is accessed two times, which can cause undesirable side effects)
+ if (Reflect.get(this, key) instanceof Date) {
+ return TypeMarker.dateTime + value;
+ }
+ return TypeMarker.string + value;
+ case "object":
+ if (value instanceof Uint8Array) {
+ return TypeMarker.binary + convertBinaryToBase64(value);
+ }
+ if (Reflect.has(value, marker)) {
+ return value;
+ }
+ break;
+ default:
+ return value;
+ }
+ const ref = refs.get(value);
+ if (ref) {
+ // value has been seen, return that seen value
+ return ref;
+ }
+ const id = refs.size.toString();
+ refs.set(value, { [refPropertyName]: id, [marker]: undefined });
+ if (Array.isArray(value)) {
+ if (options.skipReferenceForInitialArrayObject && key === "") {
+ // For arrays, when the flag is on, the resulting string is not wrapped in "{$id:"",$values:[..]}"
+ // instead, it returns the plain array "[...]"
+ return value;
+ }
+
+ // If it is an array, wrap the array and add an id and a marker
+ return { [idPropertyName]: id, [valuesPropertyName]: value, [marker]: undefined };
+ }
+ const tmpObj = { [idPropertyName]: id, [marker]: undefined };
+ if (Reflect.has(value, idPropertyName)) {
+ console.warn(`Object contains ${idPropertyName} property which will be ignored.`);
+ // Ensure that the $id property is not overwritten by the value of the property with the same name that already exists inside of the 'value' object
+ return Object.assign(tmpObj, value, tmpObj);
+ }
+ return Object.assign(tmpObj, value);
+ })).buffer;
+ }
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/main.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/main.ts
new file mode 100644
index 00000000..9689e48f
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/main.ts
@@ -0,0 +1,87 @@
+import { isFunction, isArrayBuffer } from "./type-check"
+import { JsonSerializer } from "./json-serializer"
+import { MsgPackSerializer } from "./msgpack-serializer";
+
+export interface Serializer {
+ deserialize(value: ArrayBuffer): T;
+ serialize(value: any, options?: Partial<{ skipReferenceForInitialArrayObject: boolean }>): ArrayBuffer;
+}
+
+let defaultSerializer: Serializer = MsgPackSerializer.Instance;
+
+export const MsgPack: Serializer = MsgPackSerializer.Instance;
+export const Json: Serializer = JsonSerializer.Instance;
+
+export function setDefaultSerializer(serializer: Serializer) {
+ defaultSerializer = serializer;
+}
+
+export function getDefaultSerializer() {
+ return defaultSerializer;
+}
+
+export function createPromise(serializer = defaultSerializer): any {
+ const result: any = {};
+ const promise = new Promise(function (resolve, reject) {
+ result.resolve = function (result: ArrayBuffer) {
+ resolve(
+ isArrayBuffer(result)
+ ? serializer.deserialize(result)
+ : result
+ );
+ };
+ result.reject = reject;
+ });
+ result.promise = promise;
+ return result;
+}
+
+export function createInterceptor(targetObj: any, serializer = defaultSerializer): object {
+ const functionsMap = new Map();
+ const handler: ProxyHandler = {
+ get(target, propKey, receiver) {
+ const func = functionsMap.get(propKey);
+ if (func) {
+ return func;
+ }
+ const targetValue = Reflect.get(target, propKey);
+ if (!isFunction(targetValue)) {
+ return targetValue;
+ }
+ const interceptor = function (...args: any[]) {
+ let parameters = args
+ if (args.length > targetValue.length) {
+ parameters = args.slice(0, targetValue.length)
+ parameters.push(args.slice(targetValue.length))
+ }
+ const convertedArgs = parameters.length === 0
+ ? parameters
+ : [serializer.serialize(parameters, { skipReferenceForInitialArrayObject: true })];
+ return targetValue.apply(target, convertedArgs);
+ };
+ functionsMap.set(propKey, interceptor);
+ return interceptor;
+ }
+ };
+ return new Proxy(targetObj, handler);
+}
+declare function Unbind(objName: string): void;
+declare function Bind(objName: string): any;
+
+export function checkObjectBound(objName: string) {
+ //native function Bind()
+ if (window.hasOwnProperty(objName)) {
+ // quick check
+ return Promise.resolve(true);
+ }
+ return Bind(objName);
+}
+
+export function deleteObjectBound(objName: string) {
+ //native function Unbind()
+ Unbind(objName);
+}
+
+export function evaluateScript(fn: () => any, serializer = defaultSerializer) {
+ return serializer.serialize(fn());
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/msgpack-serializer.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/msgpack-serializer.ts
new file mode 100644
index 00000000..d8bdf224
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/msgpack-serializer.ts
@@ -0,0 +1,13 @@
+import { decode, encode } from "@msgpack/msgpack"
+import { Serializer } from "./main";
+
+export class MsgPackSerializer implements Serializer {
+ static Instance = new MsgPackSerializer();
+
+ deserialize(value: ArrayBuffer): T {
+ return decode(value)as T;
+ }
+ serialize(value: any, _options?: Partial<{ skipReferenceForInitialArrayObject: boolean; }>): ArrayBuffer {
+ return encode(value).buffer;
+ }
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/type-check.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/type-check.ts
new file mode 100644
index 00000000..bb03dfbe
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/src/type-check.ts
@@ -0,0 +1,12 @@
+
+export function isString(value: unknown): value is string {
+ return typeof value === "string";
+}
+
+export function isFunction(value: unknown): value is Function {
+ return typeof value === "function";
+}
+
+export function isArrayBuffer(value: unknown): value is ArrayBuffer {
+ return value instanceof ArrayBuffer;
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/extract-symbols.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/extract-symbols.ts
new file mode 100644
index 00000000..76ed8601
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/extract-symbols.ts
@@ -0,0 +1,74 @@
+import { readFileSync, writeFileSync } from 'node:fs';
+import { format, parse } from 'node:path';
+import { argv } from 'node:process';
+import { Declaration, DeclarationStatement, FunctionDeclaration, NamedDeclaration, Node, ScriptTarget, SyntaxKind, createSourceFile, isFunctionDeclaration, isVariableDeclaration } from 'typescript';
+import { toPascalCase } from './identifier-cases';
+
+if (argv.length < 5) {
+ console.error('Usage: extract-symbols ')
+ process.exit(1)
+}
+
+const source = removeQuotes(argv[2])
+const target = removeQuotes(argv[3])
+const namespace = removeQuotes(argv[4])
+const module = parse(target).name
+const sourceFile = createSourceFile(
+ source,
+ readFileSync(source, 'utf8'),
+ ScriptTarget.Latest,
+ true
+)
+
+function removeQuotes(argument: string) {
+ if ((argument.startsWith('"') && argument.endsWith('"')) || (argument.startsWith("'") && argument.endsWith("'"))) {
+ return argument.slice(1, -1);
+ }
+ return argument;
+}
+
+function hasExportModifier(declaration: FunctionDeclaration): boolean {
+ return declaration.modifiers?.some(modifier => modifier.kind === SyntaxKind.ExportKeyword) ?? false;
+}
+
+function* getFunctionDeclarations(node: Node): Iterable {
+ for (const childNode of node.getChildren()) {
+ if (isFunctionDeclaration(childNode) && hasExportModifier(childNode)) {
+ yield childNode;
+ }
+ yield* getFunctionDeclarations(childNode)
+ }
+}
+
+function* getVariableDeclarations(node: Node): Iterable {
+ for (const childNode of node.getChildren()) {
+ if (isVariableDeclaration(childNode)) {
+ yield childNode;
+ }
+ yield* getVariableDeclarations(childNode)
+ }
+}
+
+const functionDeclarations = [...getFunctionDeclarations(sourceFile)]
+const variableDeclarations = [...getVariableDeclarations(sourceFile)]
+function formatNamedDeclaration(decl: NamedDeclaration) {
+ const name = decl.name?.getText() ?? ''
+ return ` public const string ${toPascalCase(name)} = "${name}";`
+}
+writeFileSync(target+"Function.cs", `
+namespace ${namespace};
+
+public static class ${toPascalCase(module)+"Function"}
+{
+${functionDeclarations.map(formatNamedDeclaration).join('\n')}
+}
+`)
+
+writeFileSync(target+"Constant.cs", `
+namespace ${namespace};
+
+public static class ${toPascalCase(module)+"Constant"}
+{
+${variableDeclarations.map(formatNamedDeclaration).join('\n')}
+}
+`)
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/identifier-cases.ts b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/identifier-cases.ts
new file mode 100644
index 00000000..99da5a07
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tools/identifier-cases.ts
@@ -0,0 +1,32 @@
+function splitIdentifier(id: string): string[] {
+ const matches = id.match(/\p{Lu}*[\p{Ll}\p{Nd}]+/gu);
+ return matches ? [...matches] : [];
+}
+function toTitleCase(word: string): string {
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+}
+function toLowerCase(word: string): string {
+ return word.toLowerCase();
+}
+function toUpperCase(word: string): string {
+ return word.toUpperCase();
+}
+export function toPascalCase(id: string): string {
+ return splitIdentifier(id).map(toTitleCase).join('');
+}
+export function toKebabCase(id: string): string {
+ return splitIdentifier(id).map(toLowerCase).join('-');
+}
+export function toUpperSnakeCase(id: string): string {
+ return splitIdentifier(id).map(toUpperCase).join('_');
+}
+export function toLowerSnakeCase(id: string): string {
+ return splitIdentifier(id).map(toLowerCase).join('_');
+}
+export function toSnakeCase(id: string): string {
+ return splitIdentifier(id).join('_');
+}
+export function toCamelCase(id: string) {
+ const words = splitIdentifier(id);
+ return words.length > 0 ? toLowerCase(words.shift()!) + words.map(toTitleCase).join('') : '';
+}
diff --git a/CefGlue.BrowserProcess/ObjectBinding/js-glue/tsconfig.json b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tsconfig.json
new file mode 100644
index 00000000..c79c040e
--- /dev/null
+++ b/CefGlue.BrowserProcess/ObjectBinding/js-glue/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Language and Environment */
+ "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+
+ /* Modules */
+ "module": "ES2022", /* Specify what module code is generated. */
+ "moduleResolution": "Node", /* Specify how TypeScript looks up a file from a given module specifier. */
+
+ /* JavaScript Support */
+ "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+
+ /* Interop Constraints */
+ "esModuleInterop": false, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+
+ /* Completeness */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ }
+}
diff --git a/CefGlue.Common.Shared/CefGlue.Common.Shared.csproj b/CefGlue.Common.Shared/CefGlue.Common.Shared.csproj
index 4b4ae342..4ffaa9d8 100644
--- a/CefGlue.Common.Shared/CefGlue.Common.Shared.csproj
+++ b/CefGlue.Common.Shared/CefGlue.Common.Shared.csproj
@@ -11,6 +11,7 @@
+
diff --git a/CefGlue.Common.Shared/Helpers/MessangingType.cs b/CefGlue.Common.Shared/Helpers/MessangingType.cs
new file mode 100644
index 00000000..016aac30
--- /dev/null
+++ b/CefGlue.Common.Shared/Helpers/MessangingType.cs
@@ -0,0 +1,7 @@
+namespace Xilium.CefGlue.Common.Shared.Helpers;
+
+public enum MessagingType
+{
+ Json,
+ MsgPack
+}
diff --git a/CefGlue.Common.Shared/RendererProcessCommunication/CefListExtensions.cs b/CefGlue.Common.Shared/RendererProcessCommunication/CefListExtensions.cs
new file mode 100644
index 00000000..cba2add3
--- /dev/null
+++ b/CefGlue.Common.Shared/RendererProcessCommunication/CefListExtensions.cs
@@ -0,0 +1,40 @@
+namespace Xilium.CefGlue.Common.Shared.RendererProcessCommunication;
+
+public static class CefListExtensions
+{
+ public static bool SetNullableBinary(this ICefListValue valueList, int index, byte[] bytes)
+ {
+ if (bytes != null && bytes.Length > 0)
+ {
+ return valueList.SetBinary(index, CefBinaryValue.Create(bytes));
+ }
+
+ return valueList.SetNull(index);
+ }
+
+ public static byte[] GetNullableBinary(this ICefListValue valueList, int index)
+ {
+ CefValueType valueType = valueList.GetValueType(index);
+ return valueType == CefValueType.Null
+ ? []
+ : valueList.GetBinary(index).ToArray();
+ }
+
+ public static bool SetNullableString(this ICefListValue valueList, int index, string @string)
+ {
+ if (!string.IsNullOrEmpty(@string))
+ {
+ return valueList.SetString(index, @string);
+ }
+
+ return valueList.SetNull(index);
+ }
+
+ public static string GetNullableString(this ICefListValue valueList, int index)
+ {
+ CefValueType valueType = valueList.GetValueType(index);
+ return valueType == CefValueType.Null
+ ? default
+ : valueList.GetString(index);
+ }
+}
diff --git a/CefGlue.Common.Shared/RendererProcessCommunication/Messages.cs b/CefGlue.Common.Shared/RendererProcessCommunication/Messages.cs
index 820a62af..f27237a0 100644
--- a/CefGlue.Common.Shared/RendererProcessCommunication/Messages.cs
+++ b/CefGlue.Common.Shared/RendererProcessCommunication/Messages.cs
@@ -1,4 +1,5 @@
-using System;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Xilium.CefGlue.Common.Shared.Serialization;
@@ -49,7 +50,7 @@ public struct JsEvaluationResult
public int TaskId;
public bool Success;
- public string ResultAsJson;
+ public byte[] Result;
public string Exception;
public CefProcessMessage ToCefProcessMessage()
@@ -59,7 +60,7 @@ public CefProcessMessage ToCefProcessMessage()
{
arguments.SetInt(0, TaskId);
arguments.SetBool(1, Success);
- arguments.SetString(2, ResultAsJson);
+ arguments.SetNullableBinary(2, Result);
arguments.SetString(3, Exception);
}
return message;
@@ -73,7 +74,7 @@ public static JsEvaluationResult FromCefMessage(CefProcessMessage message)
{
TaskId = arguments.GetInt(0),
Success = arguments.GetBool(1),
- ResultAsJson = arguments.GetString(2),
+ Result = arguments.GetNullableBinary(2),
Exception = arguments.GetString(3)
};
}
@@ -84,17 +85,27 @@ public struct NativeObjectRegistrationRequest
{
public const string Name = nameof(NativeObjectRegistrationRequest);
- public string ObjectName;
- public string[] MethodsNames;
+ public ObjectInfo ObjectInfo;
+ public string Messaging;
public CefProcessMessage ToCefProcessMessage()
{
- var message = CefProcessMessage.Create(Name);
- using (var arguments = message.Arguments)
+ using var methodList = CefListValue.Create();
+ var methods = ObjectInfo.Methods;
+ for (int index = 0; index < methods.Length; index++)
{
- arguments.SetString(0, ObjectName);
- arguments.SetString(1, Serializer.Serialize(MethodsNames));
+ using var value = CefListValue.Create();
+ var method = methods[index];
+ value.SetString(0, method.Name);
+ value.SetInt(1, method.ParameterCount);
+ methodList.SetList(index, value);
}
+
+ var message = CefProcessMessage.Create(Name);
+ using var arguments = message.Arguments;
+ arguments.SetString(0, ObjectInfo.Name);
+ arguments.SetList(1, methodList);
+ arguments.SetNullableString(2, Messaging);
return message;
}
@@ -102,11 +113,20 @@ public static NativeObjectRegistrationRequest FromCefMessage(CefProcessMessage m
{
using (var arguments = message.Arguments)
{
- var methodsNamesAsJson = arguments.GetString(1);
- return new NativeObjectRegistrationRequest()
+ var methods = new List();
+
+ string objectName = arguments.GetString(0);
+ var methodList = arguments.GetList(1);
+ for (int index = 0; index < methodList.Count; index++)
{
- ObjectName = arguments.GetString(0),
- MethodsNames = Deserializer.Deserialize(methodsNamesAsJson)
+ using var value = methodList.GetList(index);
+ methods.Add(new MethodInfo(value.GetString(0), value.GetInt(1)));
+ }
+
+ string messaging = arguments.GetNullableString(2);
+ return new NativeObjectRegistrationRequest
+ {
+ ObjectInfo = new ObjectInfo(objectName, methods.ToArray()), Messaging = messaging,
};
}
}
@@ -128,11 +148,11 @@ public CefProcessMessage ToCefProcessMessage()
return message;
}
- public static NativeObjectRegistrationRequest FromCefMessage(CefProcessMessage message)
+ public static NativeObjectUnregistrationRequest FromCefMessage(CefProcessMessage message)
{
using (var arguments = message.Arguments)
{
- return new NativeObjectRegistrationRequest()
+ return new NativeObjectUnregistrationRequest()
{
ObjectName = arguments.GetString(0),
};
@@ -147,18 +167,16 @@ public struct NativeObjectCallRequest
public int CallId;
public string ObjectName;
public string MemberName;
- public string ArgumentsAsJson;
+ public byte[] Arguments;
public CefProcessMessage ToCefProcessMessage()
{
var message = CefProcessMessage.Create(Name);
- using (var arguments = message.Arguments)
- {
- arguments.SetInt(0, CallId);
- arguments.SetString(1, ObjectName);
- arguments.SetString(2, MemberName);
- arguments.SetString(3, ArgumentsAsJson);
- }
+ var arguments = message.Arguments;
+ arguments.SetInt(0, CallId);
+ arguments.SetString(1, ObjectName);
+ arguments.SetString(2, MemberName);
+ arguments.SetNullableBinary(3, Arguments);
return message;
}
@@ -171,7 +189,7 @@ public static NativeObjectCallRequest FromCefMessage(CefProcessMessage message)
CallId = arguments.GetInt(0),
ObjectName = arguments.GetString(1),
MemberName = arguments.GetString(2),
- ArgumentsAsJson = arguments.GetString(3),
+ Arguments = arguments.GetNullableBinary(3),
};
}
}
@@ -183,7 +201,7 @@ public struct NativeObjectCallResult
public int CallId;
public bool Success;
- public string ResultAsJson;
+ public byte[] Result;
public string Exception;
public CefProcessMessage ToCefProcessMessage()
@@ -194,8 +212,8 @@ public CefProcessMessage ToCefProcessMessage()
{
arguments.SetInt(0, CallId);
arguments.SetBool(1, Success);
- arguments.SetString(2, ResultAsJson);
- arguments.SetString(3, Exception);
+ arguments.SetNullableBinary(2, Result);
+ arguments.SetNullableString(3, Exception);
}
return message;
}
@@ -208,8 +226,8 @@ public static NativeObjectCallResult FromCefMessage(CefProcessMessage message)
{
CallId = arguments.GetInt(0),
Success = arguments.GetBool(1),
- ResultAsJson = arguments.GetString(2),
- Exception = arguments.GetString(3)
+ Result = arguments.GetNullableBinary(2),
+ Exception = arguments.GetNullableString(3)
};
}
}
diff --git a/CefGlue.Common.Shared/RendererProcessCommunication/Messaging.cs b/CefGlue.Common.Shared/RendererProcessCommunication/Messaging.cs
new file mode 100644
index 00000000..c4184f3d
--- /dev/null
+++ b/CefGlue.Common.Shared/RendererProcessCommunication/Messaging.cs
@@ -0,0 +1,32 @@
+using System;
+
+using Xilium.CefGlue.Common.Shared.Serialization;
+using Xilium.CefGlue.Common.Shared.Serialization.Json;
+using Xilium.CefGlue.Common.Shared.Serialization.MsgPack;
+
+namespace Xilium.CefGlue.Common.Shared.RendererProcessCommunication;
+
+public class Messaging
+{
+ public static readonly Messaging Json = new Messaging("Json", new CefJsonSerializer(), new CefJsonDeserializer());
+ public static readonly Messaging MsgPack = new Messaging("MsgPack", new CefMsgPackSerializer(), new CefMsgPackDeserializer());
+
+ public string Id { get; }
+
+ public ISerializer Serializer { get; }
+
+ public IDeserializer Deserializer { get; }
+
+ public Messaging(string id, ISerializer serializer, IDeserializer deserializer)
+ {
+ Id = id;
+ Serializer = serializer;
+ Deserializer = deserializer;
+ }
+
+ public object[] Deserialize(byte[] bytes, params Type[] targetTypes) => Deserializer.Deserialize(bytes, targetTypes);
+
+ public TargetType Deserialize(byte[] bytes) => Deserializer.Deserialize(bytes);
+
+ public byte[] Serialize(object value) => Serializer.Serialize(value);
+}
diff --git a/CefGlue.Common.Shared/RendererProcessCommunication/ObjectInfo.cs b/CefGlue.Common.Shared/RendererProcessCommunication/ObjectInfo.cs
new file mode 100644
index 00000000..a3d0adc3
--- /dev/null
+++ b/CefGlue.Common.Shared/RendererProcessCommunication/ObjectInfo.cs
@@ -0,0 +1,5 @@
+namespace Xilium.CefGlue.Common.Shared.RendererProcessCommunication;
+
+public record ObjectInfo(string Name, MethodInfo[] Methods);
+
+public record struct MethodInfo(string Name, int ParameterCount);
\ No newline at end of file
diff --git a/CefGlue.Common.Shared/Serialization/IDeserializer.cs b/CefGlue.Common.Shared/Serialization/IDeserializer.cs
new file mode 100644
index 00000000..98cc4045
--- /dev/null
+++ b/CefGlue.Common.Shared/Serialization/IDeserializer.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Xilium.CefGlue.Common.Shared.Serialization;
+
+public interface IDeserializer
+{
+ object[] Deserialize(byte[] bytes, params Type[] targetTypes);
+
+ TargetType Deserialize(byte[] bytes);
+}
diff --git a/CefGlue.Common.Shared/Serialization/ISerializer.cs b/CefGlue.Common.Shared/Serialization/ISerializer.cs
new file mode 100644
index 00000000..0de8331c
--- /dev/null
+++ b/CefGlue.Common.Shared/Serialization/ISerializer.cs
@@ -0,0 +1,6 @@
+namespace Xilium.CefGlue.Common.Shared.Serialization;
+
+public interface ISerializer
+{
+ byte[] Serialize(object value);
+}
\ No newline at end of file
diff --git a/CefGlue.Common.Shared/Serialization/Deserializer.cs b/CefGlue.Common.Shared/Serialization/Json/CefJsonDeserializer.cs
similarity index 84%
rename from CefGlue.Common.Shared/Serialization/Deserializer.cs
rename to CefGlue.Common.Shared/Serialization/Json/CefJsonDeserializer.cs
index e170827e..f47e8977 100644
--- a/CefGlue.Common.Shared/Serialization/Deserializer.cs
+++ b/CefGlue.Common.Shared/Serialization/Json/CefJsonDeserializer.cs
@@ -3,32 +3,32 @@
using System.Linq;
using System.Text;
using System.Text.Json;
-using Xilium.CefGlue.Common.Shared.Serialization.State;
+using Xilium.CefGlue.Common.Shared.Serialization.Json.State;
-namespace Xilium.CefGlue.Common.Shared.Serialization
+namespace Xilium.CefGlue.Common.Shared.Serialization.Json
{
- internal static class Deserializer
+ internal class CefJsonDeserializer : IDeserializer
{
private const int DeserializerMaxDepth = int.MaxValue;
- private static readonly IDeserializerState ListWrapperMarker = new ReadonlyDeserializerState(value: default);
+ private readonly IDeserializerState ListWrapperMarker = new ReadonlyDeserializerState(value: default);
///
/// Deserializes the passed jsonString argument to an instance of the TargetType.
///
///
- ///
+ ///
/// When deserializing an argumentsArray string, it's possible to specify the specific typeInfo of each of the arguments.
///
///
- public static TargetType Deserialize(string jsonString)
+ public TargetType Deserialize(byte[] bytes)
{
- if (string.IsNullOrEmpty(jsonString?.Trim()))
+ var reader = CreateJsonReader(bytes);
+ if (reader.HasNoContent())
{
return default;
}
- var reader = CreateJsonReader(jsonString);
var rootState = new RootObjectDeserializerState(typeof(TargetType));
Deserialize(reader, rootState);
return (TargetType)rootState.Value;
@@ -38,24 +38,24 @@ public static TargetType Deserialize(string jsonString)
/// Deserializes the passed jsonString argument to an instance of object[].
///
///
- ///
+ ///
///
///
/// When targetTypes is null or empty
///
- public static object[] Deserialize(string jsonString, params Type[] targetTypes)
+ public object[] Deserialize(byte[] bytes, params Type[] targetTypes)
{
if (targetTypes == null || targetTypes.Length == 0)
{
- throw new ArgumentException("At least one target type must be specified.", nameof(jsonString));
+ throw new ArgumentException("At least one target type must be specified.", nameof(bytes));
}
- if (string.IsNullOrEmpty(jsonString?.Trim()))
+ var reader = CreateJsonReader(bytes);
+ if (reader.HasNoContent())
{
return Array.Empty
+
none
diff --git a/CefGlue/Classes.Handlers/CefV8ArrayBufferReleaseCallback.cs b/CefGlue/Classes.Handlers/CefV8ArrayBufferReleaseCallback.cs
index b8ca998b..98b7c68a 100644
--- a/CefGlue/Classes.Handlers/CefV8ArrayBufferReleaseCallback.cs
+++ b/CefGlue/Classes.Handlers/CefV8ArrayBufferReleaseCallback.cs
@@ -25,4 +25,9 @@ private void release_buffer(cef_v8array_buffer_release_callback_t* self, void* b
///
protected abstract void ReleaseBuffer(IntPtr buffer);
}
+
+ public class GlobalHeapArrayBufferReleaseCallback : CefV8ArrayBufferReleaseCallback
+ {
+ protected override void ReleaseBuffer(IntPtr buffer) => Marshal.FreeHGlobal(buffer);
+ }
}
diff --git a/CefGlue/Classes.Proxies/CefV8Value.cs b/CefGlue/Classes.Proxies/CefV8Value.cs
index c2f2c8a7..8378455e 100644
--- a/CefGlue/Classes.Proxies/CefV8Value.cs
+++ b/CefGlue/Classes.Proxies/CefV8Value.cs
@@ -158,6 +158,13 @@ public static CefV8Value CreateArrayBuffer(IntPtr buffer, ulong length, CefV8Arr
return CefV8Value.FromNative(n_value);
}
+ public static CefV8Value CreateArrayBuffer(byte[] bytes)
+ {
+ IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
+ Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
+ return CefV8Value.CreateArrayBuffer(unmanagedPointer, (ulong)bytes.Length, new GlobalHeapArrayBufferReleaseCallback());
+ }
+
///
/// Create a new CefV8Value object of type function. This method should only
/// be called from within the scope of a CefRenderProcessHandler, CefV8Handler
@@ -656,6 +663,19 @@ public IntPtr GetArrayBufferData()
return (IntPtr)cef_v8value_t.get_array_buffer_data(_self);
}
+ public byte[] GetArrayBuffer()
+ {
+ int length = (int)GetArrayBufferByteLength();
+ if (length == 0)
+ {
+ return [];
+ }
+ nint buffer = GetArrayBufferData();
+ byte[] array = new byte[length];
+ Marshal.Copy(buffer, array, 0, length);
+ return array;
+ }
+
// FUNCTION METHODS - These methods are only available on functions.
///
diff --git a/Directory.Packages.props b/Directory.Packages.props
index a19c466a..d0144f44 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -19,7 +19,8 @@
-
+
+
@@ -30,7 +31,7 @@
-
+
@@ -45,4 +46,4 @@
-
+
\ No newline at end of file