Let's talk
monitor

The Monitor

Live supply-chain watchboard — critical npm & PyPI packages, watched for compromise.

65
watched
26
nominal
0
watch
0
active alerts
39
incidents on record
updated…
npm — by dependents
axios npm
1.19.0 23d ago incident on record
DELETION ×2BURST ×4
latest 1.19.0 versions 143 maintainers 1
0.31.0
1.15.1
0.31.1
1.15.2
1.16.0
0.32.0
1.16.1
1.17.0
0.33.0
1.18.0
1.18.1
1.19.0
DELETION
1.14.1 published then removed
high · registry-verified · 2026-03-31 · 4mo ago
DELETION
0.30.4 published then removed
high · registry-verified · 2026-03-31 · 4mo ago
BURST
2 releases in 60m: 1.1.1, 1.1.2
info · registry-verified · 2022-10-07 · 3y ago
BURST
2 releases in 39m: 1.14.1, 0.30.4
info · registry-verified · 2026-03-31 · 4mo ago
BURST
2 releases in 4m: 1.15.1, 0.31.1
info · registry-verified · 2026-04-19 · 4mo ago
BURST
2 releases in 0m: 0.33.0, 1.18.0
info · registry-verified · 2026-06-14 · 2mo ago
release diff 1.18.1 → 1.19.0
+2 added · -0 removed · ~30 modified
+1 more files not shown
dist/axios.js +354 lines · 1 flagged
--- +++ @@ -1,2 +1,2 @@-/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */+/*! Axios v1.19.0 Copyright (c) 2026 Matt Zabriskie and contributors */ (function (global, factory) {@@ -827,2 +827,3 @@   var isFileList = kindOfTest('FileList');+  var isSet = kindOfTest('Set'); @@ -1356,7 +1357,25 @@           visited.add(source);-          var target = isArray(source) ? [] : {};-          forEach(source, function (value, key) {-            var reducedValue = _visit(value);-            !isUndefined(reducedValue) && (target[key] = reducedValue);-          });+          var target;+          if (isSet(source)) {+            target = [];+            var _iterator2 = _createForOfIteratorHelper(source),+              _step;+            try {+              for (_iterator2.s(); !(_step = _iterator2.n()).done;) {+                var value = _step.value;+                var reducedValue = _visit(value);+                !isUndefined(reducedValue) && target.push(reducedValue);+              }+            } catch (err) {+              _iterator2.e(err);+            } finally {+              _iterator2.f();+            }+          } else {+            target = isArray(source) ? [] : {};+            forEach(source, function (value, key) {+              var reducedValue = _visit(value);+              !isUndefined(reducedValue) && (target[key] = reducedValue);+            });+          }           visited["delete"](source);@@ -1541,3 +1560,4 @@       val = line.substring(i + 1).trim();-      if (!key || parsed[key] && ignoreDuplicateOf[key]) {+      var hasKey = utils$1.hasOwnProp(parsed, key);+      if (!key || hasKey && utils$1.hasOwnProp(ignoreDuplicateOf, key)) {         return;@@ -1545,3 +1565,3 @@       if (key === 'set-cookie') {-        if (parsed[key]) {+        if (hasKey) {           parsed[key].push(val);@@ -1551,3 +1571,3 @@       } else {-        parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;+        parsed[key] = hasKey ? parsed[key] + ', ' + val : val;       }@@ -1622,2 +1642,86 @@     return tokens;+  }+  var parameterNameRE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;+  function trimOWS(value) {+    var start = 0;+    var end = value.length;+    while (start < end) {+      var code = value.charCodeAt(start);+      if (code !== 0x09 && code !== 0x20) {+        break;+      }+      start += 1;+    }+    while (end > start) {+      var _code = value.charCodeAt(end - 1);+      if (_code !== 0x09 && _code !== 0x20) {+        break;+      }+      end -= 1;+    }+    return start === 0 && end === value.length ? value : value.slice(start, end);+  }+  function decodeQuotedString(value) {+    var last = value.length - 1;+    if (last < 1 || value.charCodeAt(0) !== 0x22 || value.charCodeAt(last) !== 0x22) {+      return value;+    }+    var decoded = '';+    for (var i = 1; i < last; i++) {+      var code = value.charCodeAt(i);+      if (code === 0x22) {+        return value;+      }+      if (code === 0x5c) {+        i += 1;+        if (i >= last) {+          return value;+        }+      }+      decoded += value[i];+    }+    return decoded;+  }+  function _parseParameters(value) {+    var parameters = Object.create(null);+    var str = String(value);+    var start = 0;+    var quoted = false;+    var escaped = false;+    function parseParameter(end) {+      var part = trimOWS(str.slice(start, end));+      var equals = part.indexOf('=');+      if (equals < 1) {+        return;+      }+      var name = trimOWS(part.slice(0, equals));+      if (!parameterNameRE.test(name)) {+        return;+      }+      var normalizedName = name.toLowerCase();+      if (normalizedName === '__proto__' || normalizedName === 'constructor' || normalizedName === 'prototype') {+        return;+      }+      var parameterValue = trimOWS(part.slice(equals + 1));+      parameters[normalizedName] = decodeQuotedString(parameterValue);+    }+    for (var i = 0; i < str.length; i++) {+      var code = str.charCodeAt(i);+      if (quoted) {+        if (escaped) {+          escaped = false;+        } else if (code === 0x5c) {+          escaped = true;+        } else if (code === 0x22) {+          quoted = false;+        }+      } else if (code === 0x22) {+        quoted = true;+      } else if (code === 0x2c || code === 0x3b) {+        parseParameter(i);+        start = i + 1;+      }+    }+    parseParameter(str.length);+    return parameters;   }@@ -1847,3 +1951,4 @@       value: function getSetCookie() {-        return this.get('set-cookie') || [];+        var value = this.get('set-cookie');+        return utils$1.isArray(value) ? value : value == null || value === false ? [] : [value];       }@@ -1858,2 +1963,7 @@         return thing instanceof this ? thing : new this(thing);+      }+    }, {+      key: "parseParameters",+      value: function parseParameters(value) {+        return _parseParameters(value);       }@@ -1968,2 +2078,19 @@     return _visit(config);+  }+  function stringifySafely$1(value) {+    try {+      return String(value);+    } catch (err) {+      return '';+    }+  }+  function aggregateErrorMessage(error) {+    var message = error.errors.map(function (entry) {+      try {+        return entry && entry.message ? stringifySafely$1(entry.message) : stringifySafely$1(entry);+      } catch (err) {+        return '';+      }+    }).filter(Boolean).join('; ');+    return message || error.name || 'AggregateError';   }@@ -2041,3 +2168,10 @@       value: function from(error, code, config, request, response, customProps) {-        var axiosError = new AxiosError(error.message, code || error.code, config, request, response);+        // `AggregateError` (thrown by Node on dual-stack/Happy-Eyeballs connection+        // failures) has an empty `message`; its detail lives in `errors[]`. Without+        // this, the wrapped error surfaces with a blank message (see #6721).+        var message = error.message;+        if (!message && utils$1.isArray(error.errors) && error.errors.length) {+          message = aggregateErrorMessage(error);+        }+        var axiosError = new AxiosError(message, code || error.code, config, request, response);         // Match native `Error` `cause` semantics: non-enumerable. The wrapped@@ -2209,5 +2343,2 @@         }-        if (typeof Buffer !== 'undefined') {-          return Buffer.from(value);-        }         throw new AxiosError('Blob is not supported. Use a Buffer instead.', AxiosError.ERR_NOT_SUPPORT);@@ -2583,8 +2714,14 @@   function parsePropPath(name) {-    // foo[x][y][z]-    // foo.x.y.z-    // foo-x-y-z-    // foo x y z+    // foo[x][y][z] -> ['foo', 'x', 'y', 'z']+    // foo.x.y.z    -> ['foo', 'x', 'y', 'z']+    // A path is split on `.` and on `[...]` groups. A segment — whether written+    // in dot notation or captured inside brackets — may contain any character+    // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept+    // literal instead of being split (#5402). `.`, `[` and `]` keep their existing+    // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.+    // Excluding `[` from the bracket group also makes the match fail fast at the+    // next `[`, so a malformed name cannot rescan to the end of the string from+    // every unmatched `[` — parsing stays linear in the length of the name.     var path = [];-    var pattern = /\w+|\[(\w*)]/g;+    var pattern = /[^.[\]]+|\[([^.[\]]*)]/g;     var match;@@ -2945,3 +3082,3 @@       var total = e.lengthComputable ? e.total : undefined;-      var loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;+      var loaded = Math.max(0, total != null ? Math.min(rawLoaded, total) : rawLoaded);       var progressBytes = Math.max(0, loaded - bytesNotified);@@ -2973,2 +3110,3 @@   var asyncDecorator = function asyncDecorator(fn) {+    var scheduler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : utils$1.asap;     return function () {@@ -2977,3 +3115,3 @@       }-      return utils$1.asap(function () {+      return scheduler(function () {         return fn.apply(void 0, args);@@ -3075,3 +3213,10 @@   function combineURLs(baseURL, relativeURL) {-    return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;+    if (!relativeURL) {+      return baseURL;+    }+    var end = baseURL.length;+    while (end > 0 && baseURL.charCodeAt(end - 1) === 47) {+      end--;+    }+    return baseURL.slice(0, end) + '/' + relativeURL.replace(/^\/+/, '');   }@@ -3090,5 +3235,36 @@   }++  // Redact the parts of a URL that can carry secrets before it is embedded in an+  // error message. AxiosError.toJSON() serializes `message` verbatim and errors+  // are commonly logged, while the opt-in `config.redact` model only cleans+  // config keys — it cannot reach the message. Redact only the genuinely+  // sensitive substrings — userinfo (credentials), query parameter values and
… 303 more lines (truncated)
dist/browser/axios.cjs +423 lines · 1 flagged
--- +++ @@ -1,2 +1,2 @@-/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */+/*! Axios v1.19.0 Copyright (c) 2026 Matt Zabriskie and contributors */ 'use strict';@@ -296,2 +296,3 @@ const isFileList = kindOfTest('FileList');+const isSet = kindOfTest('Set'); @@ -861,8 +862,19 @@         visited.add(source);-        const target = isArray(source) ? [] : {};--        forEach(source, (value, key) => {-          const reducedValue = visit(value);-          !isUndefined(reducedValue) && (target[key] = reducedValue);-        });++        let target;++        if (isSet(source)) {+          target = [];+          for (const value of source) {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && target.push(reducedValue);+          }+        } else {+          target = isArray(source) ? [] : {};++          forEach(source, (value, key) => {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && (target[key] = reducedValue);+          });+        } @@ -1078,3 +1090,5 @@ -      if (!key || (parsed[key] && ignoreDuplicateOf[key])) {+      const hasKey = utils$1.hasOwnProp(parsed, key);++      if (!key || (hasKey && utils$1.hasOwnProp(ignoreDuplicateOf, key))) {         return;@@ -1083,3 +1097,3 @@       if (key === 'set-cookie') {-        if (parsed[key]) {+        if (hasKey) {           parsed[key].push(val);@@ -1089,3 +1103,3 @@       } else {-        parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;+        parsed[key] = hasKey ? parsed[key] + ', ' + val : val;       }@@ -1177,2 +1191,120 @@   return tokens;+}++const parameterNameRE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;++function trimOWS(value) {+  let start = 0;+  let end = value.length;++  while (start < end) {+    const code = value.charCodeAt(start);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    start += 1;+  }++  while (end > start) {+    const code = value.charCodeAt(end - 1);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    end -= 1;+  }++  return start === 0 && end === value.length ? value : value.slice(start, end);+}++function decodeQuotedString(value) {+  const last = value.length - 1;++  if (last < 1 || value.charCodeAt(0) !== 0x22 || value.charCodeAt(last) !== 0x22) {+    return value;+  }++  let decoded = '';++  for (let i = 1; i < last; i++) {+    const code = value.charCodeAt(i);++    if (code === 0x22) {+      return value;+    }++    if (code === 0x5c) {+      i += 1;++      if (i >= last) {+        return value;+      }+    }++    decoded += value[i];+  }++  return decoded;+}++function parseParameters(value) {+  const parameters = Object.create(null);+  const str = String(value);+  let start = 0;+  let quoted = false;+  let escaped = false;++  function parseParameter(end) {+    const part = trimOWS(str.slice(start, end));+    const equals = part.indexOf('=');++    if (equals < 1) {+      return;+    }++    const name = trimOWS(part.slice(0, equals));++    if (!parameterNameRE.test(name)) {+      return;+    }++    const normalizedName = name.toLowerCase();++    if (+      normalizedName === '__proto__' ||+      normalizedName === 'constructor' ||+      normalizedName === 'prototype'+    ) {+      return;+    }++    const parameterValue = trimOWS(part.slice(equals + 1));+    parameters[normalizedName] = decodeQuotedString(parameterValue);+  }++  for (let i = 0; i < str.length; i++) {+    const code = str.charCodeAt(i);++    if (quoted) {+      if (escaped) {+        escaped = false;+      } else if (code === 0x5c) {+        escaped = true;+      } else if (code === 0x22) {+        quoted = false;+      }+    } else if (code === 0x22) {+      quoted = true;+    } else if (code === 0x2c || code === 0x3b) {+      parseParameter(i);+      start = i + 1;+    }+  }++  parseParameter(str.length);++  return parameters; }@@ -1430,3 +1562,4 @@   getSetCookie() {-    return this.get('set-cookie') || [];+    const value = this.get('set-cookie');+    return utils$1.isArray(value) ? value : value == null || value === false ? [] : [value];   }@@ -1439,2 +1572,6 @@     return thing instanceof this ? thing : new this(thing);+  }++  static parseParameters(value) {+    return parseParameters(value);   }@@ -1566,5 +1703,36 @@ +function stringifySafely$1(value) {+  try {+    return String(value);+  } catch (err) {+    return '';+  }+}++function aggregateErrorMessage(error) {+  const message = error.errors+    .map((entry) => {+      try {+        return entry && entry.message ? stringifySafely$1(entry.message) : stringifySafely$1(entry);+      } catch (err) {+        return '';+      }+    })+    .filter(Boolean)+    .join('; ');++  return message || error.name || 'AggregateError';+}+ class AxiosError extends Error {   static from(error, code, config, request, response, customProps) {-    const axiosError = new AxiosError(error.message, code || error.code, config, request, response);+    // `AggregateError` (thrown by Node on dual-stack/Happy-Eyeballs connection+    // failures) has an empty `message`; its detail lives in `errors[]`. Without+    // this, the wrapped error surfaces with a blank message (see #6721).+    let message = error.message;+    if (!message && utils$1.isArray(error.errors) && error.errors.length) {+      message = aggregateErrorMessage(error);+    }++    const axiosError = new AxiosError(message, code || error.code, config, request, response);     // Match native `Error` `cause` semantics: non-enumerable. The wrapped@@ -1823,5 +1991,2 @@       }-      if (typeof Buffer !== 'undefined') {-        return Buffer.from(value);-      }       throw new AxiosError('Blob is not supported. Use a Buffer instead.', AxiosError.ERR_NOT_SUPPORT);@@ -2262,8 +2427,14 @@ function parsePropPath(name) {-  // foo[x][y][z]-  // foo.x.y.z-  // foo-x-y-z-  // foo x y z+  // foo[x][y][z] -> ['foo', 'x', 'y', 'z']+  // foo.x.y.z    -> ['foo', 'x', 'y', 'z']+  // A path is split on `.` and on `[...]` groups. A segment — whether written+  // in dot notation or captured inside brackets — may contain any character+  // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept+  // literal instead of being split (#5402). `.`, `[` and `]` keep their existing+  // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.+  // Excluding `[` from the bracket group also makes the match fail fast at the+  // next `[`, so a malformed name cannot rescan to the end of the string from+  // every unmatched `[` — parsing stays linear in the length of the name.   const path = [];-  const pattern = /\w+|\[(\w*)]/g;+  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
… 369 more lines (truncated)
dist/esm/axios.js +423 lines · 1 flagged
--- +++ @@ -1,2 +1,2 @@-/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */+/*! Axios v1.19.0 Copyright (c) 2026 Matt Zabriskie and contributors */ /**@@ -294,2 +294,3 @@ const isFileList = kindOfTest('FileList');+const isSet = kindOfTest('Set'); @@ -859,8 +860,19 @@         visited.add(source);-        const target = isArray(source) ? [] : {};--        forEach(source, (value, key) => {-          const reducedValue = visit(value);-          !isUndefined(reducedValue) && (target[key] = reducedValue);-        });++        let target;++        if (isSet(source)) {+          target = [];+          for (const value of source) {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && target.push(reducedValue);+          }+        } else {+          target = isArray(source) ? [] : {};++          forEach(source, (value, key) => {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && (target[key] = reducedValue);+          });+        } @@ -1076,3 +1088,5 @@ -      if (!key || (parsed[key] && ignoreDuplicateOf[key])) {+      const hasKey = utils$1.hasOwnProp(parsed, key);++      if (!key || (hasKey && utils$1.hasOwnProp(ignoreDuplicateOf, key))) {         return;@@ -1081,3 +1095,3 @@       if (key === 'set-cookie') {-        if (parsed[key]) {+        if (hasKey) {           parsed[key].push(val);@@ -1087,3 +1101,3 @@       } else {-        parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;+        parsed[key] = hasKey ? parsed[key] + ', ' + val : val;       }@@ -1175,2 +1189,120 @@   return tokens;+}++const parameterNameRE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;++function trimOWS(value) {+  let start = 0;+  let end = value.length;++  while (start < end) {+    const code = value.charCodeAt(start);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    start += 1;+  }++  while (end > start) {+    const code = value.charCodeAt(end - 1);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    end -= 1;+  }++  return start === 0 && end === value.length ? value : value.slice(start, end);+}++function decodeQuotedString(value) {+  const last = value.length - 1;++  if (last < 1 || value.charCodeAt(0) !== 0x22 || value.charCodeAt(last) !== 0x22) {+    return value;+  }++  let decoded = '';++  for (let i = 1; i < last; i++) {+    const code = value.charCodeAt(i);++    if (code === 0x22) {+      return value;+    }++    if (code === 0x5c) {+      i += 1;++      if (i >= last) {+        return value;+      }+    }++    decoded += value[i];+  }++  return decoded;+}++function parseParameters(value) {+  const parameters = Object.create(null);+  const str = String(value);+  let start = 0;+  let quoted = false;+  let escaped = false;++  function parseParameter(end) {+    const part = trimOWS(str.slice(start, end));+    const equals = part.indexOf('=');++    if (equals < 1) {+      return;+    }++    const name = trimOWS(part.slice(0, equals));++    if (!parameterNameRE.test(name)) {+      return;+    }++    const normalizedName = name.toLowerCase();++    if (+      normalizedName === '__proto__' ||+      normalizedName === 'constructor' ||+      normalizedName === 'prototype'+    ) {+      return;+    }++    const parameterValue = trimOWS(part.slice(equals + 1));+    parameters[normalizedName] = decodeQuotedString(parameterValue);+  }++  for (let i = 0; i < str.length; i++) {+    const code = str.charCodeAt(i);++    if (quoted) {+      if (escaped) {+        escaped = false;+      } else if (code === 0x5c) {+        escaped = true;+      } else if (code === 0x22) {+        quoted = false;+      }+    } else if (code === 0x22) {+      quoted = true;+    } else if (code === 0x2c || code === 0x3b) {+      parseParameter(i);+      start = i + 1;+    }+  }++  parseParameter(str.length);++  return parameters; }@@ -1428,3 +1560,4 @@   getSetCookie() {-    return this.get('set-cookie') || [];+    const value = this.get('set-cookie');+    return utils$1.isArray(value) ? value : value == null || value === false ? [] : [value];   }@@ -1437,2 +1570,6 @@     return thing instanceof this ? thing : new this(thing);+  }++  static parseParameters(value) {+    return parseParameters(value);   }@@ -1564,5 +1701,36 @@ +function stringifySafely$1(value) {+  try {+    return String(value);+  } catch (err) {+    return '';+  }+}++function aggregateErrorMessage(error) {+  const message = error.errors+    .map((entry) => {+      try {+        return entry && entry.message ? stringifySafely$1(entry.message) : stringifySafely$1(entry);+      } catch (err) {+        return '';+      }+    })+    .filter(Boolean)+    .join('; ');++  return message || error.name || 'AggregateError';+}+ let AxiosError$1 = class AxiosError extends Error {   static from(error, code, config, request, response, customProps) {-    const axiosError = new AxiosError(error.message, code || error.code, config, request, response);+    // `AggregateError` (thrown by Node on dual-stack/Happy-Eyeballs connection+    // failures) has an empty `message`; its detail lives in `errors[]`. Without+    // this, the wrapped error surfaces with a blank message (see #6721).+    let message = error.message;+    if (!message && utils$1.isArray(error.errors) && error.errors.length) {+      message = aggregateErrorMessage(error);+    }++    const axiosError = new AxiosError(message, code || error.code, config, request, response);     // Match native `Error` `cause` semantics: non-enumerable. The wrapped@@ -1821,5 +1989,2 @@       }-      if (typeof Buffer !== 'undefined') {-        return Buffer.from(value);-      }       throw new AxiosError$1('Blob is not supported. Use a Buffer instead.', AxiosError$1.ERR_NOT_SUPPORT);@@ -2260,8 +2425,14 @@ function parsePropPath(name) {-  // foo[x][y][z]-  // foo.x.y.z-  // foo-x-y-z-  // foo x y z+  // foo[x][y][z] -> ['foo', 'x', 'y', 'z']+  // foo.x.y.z    -> ['foo', 'x', 'y', 'z']+  // A path is split on `.` and on `[...]` groups. A segment — whether written+  // in dot notation or captured inside brackets — may contain any character+  // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept+  // literal instead of being split (#5402). `.`, `[` and `]` keep their existing+  // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.+  // Excluding `[` from the bracket group also makes the match fail fast at the+  // next `[`, so a malformed name cannot rescan to the end of the string from+  // every unmatched `[` — parsing stays linear in the length of the name.   const path = [];-  const pattern = /\w+|\[(\w*)]/g;+  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
… 369 more lines (truncated)
dist/node/axios.cjs +476 lines · 1 flagged
--- +++ @@ -1,2 +1,2 @@-/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */+/*! Axios v1.19.0 Copyright (c) 2026 Matt Zabriskie and contributors */ 'use strict';@@ -297,2 +297,3 @@ const isFileList = kindOfTest('FileList');+const isSet = kindOfTest('Set'); @@ -819,7 +820,16 @@         visited.add(source);-        const target = isArray(source) ? [] : {};-        forEach(source, (value, key) => {-          const reducedValue = visit(value);-          !isUndefined(reducedValue) && (target[key] = reducedValue);-        });+        let target;+        if (isSet(source)) {+          target = [];+          for (const value of source) {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && target.push(reducedValue);+          }+        } else {+          target = isArray(source) ? [] : {};+          forEach(source, (value, key) => {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && (target[key] = reducedValue);+          });+        }         visited.delete(source);@@ -997,3 +1007,4 @@     val = line.substring(i + 1).trim();-    if (!key || parsed[key] && ignoreDuplicateOf[key]) {+    const hasKey = utils$1.hasOwnProp(parsed, key);+    if (!key || hasKey && utils$1.hasOwnProp(ignoreDuplicateOf, key)) {       return;@@ -1001,3 +1012,3 @@     if (key === 'set-cookie') {-      if (parsed[key]) {+      if (hasKey) {         parsed[key].push(val);@@ -1007,3 +1018,3 @@     } else {-      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;+      parsed[key] = hasKey ? parsed[key] + ', ' + val : val;     }@@ -1072,2 +1083,86 @@   return tokens;+}+const parameterNameRE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;+function trimOWS(value) {+  let start = 0;+  let end = value.length;+  while (start < end) {+    const code = value.charCodeAt(start);+    if (code !== 0x09 && code !== 0x20) {+      break;+    }+    start += 1;+  }+  while (end > start) {+    const code = value.charCodeAt(end - 1);+    if (code !== 0x09 && code !== 0x20) {+      break;+    }+    end -= 1;+  }+  return start === 0 && end === value.length ? value : value.slice(start, end);+}+function decodeQuotedString(value) {+  const last = value.length - 1;+  if (last < 1 || value.charCodeAt(0) !== 0x22 || value.charCodeAt(last) !== 0x22) {+    return value;+  }+  let decoded = '';+  for (let i = 1; i < last; i++) {+    const code = value.charCodeAt(i);+    if (code === 0x22) {+      return value;+    }+    if (code === 0x5c) {+      i += 1;+      if (i >= last) {+        return value;+      }+    }+    decoded += value[i];+  }+  return decoded;+}+function parseParameters(value) {+  const parameters = Object.create(null);+  const str = String(value);+  let start = 0;+  let quoted = false;+  let escaped = false;+  function parseParameter(end) {+    const part = trimOWS(str.slice(start, end));+    const equals = part.indexOf('=');+    if (equals < 1) {+      return;+    }+    const name = trimOWS(part.slice(0, equals));+    if (!parameterNameRE.test(name)) {+      return;+    }+    const normalizedName = name.toLowerCase();+    if (normalizedName === '__proto__' || normalizedName === 'constructor' || normalizedName === 'prototype') {+      return;+    }+    const parameterValue = trimOWS(part.slice(equals + 1));+    parameters[normalizedName] = decodeQuotedString(parameterValue);+  }+  for (let i = 0; i < str.length; i++) {+    const code = str.charCodeAt(i);+    if (quoted) {+      if (escaped) {+        escaped = false;+      } else if (code === 0x5c) {+        escaped = true;+      } else if (code === 0x22) {+        quoted = false;+      }+    } else if (code === 0x22) {+      quoted = true;+    } else if (code === 0x2c || code === 0x3b) {+      parseParameter(i);+      start = i + 1;+    }+  }+  parseParameter(str.length);+  return parameters; }@@ -1250,3 +1345,4 @@   getSetCookie() {-    return this.get('set-cookie') || [];+    const value = this.get('set-cookie');+    return utils$1.isArray(value) ? value : value == null || value === false ? [] : [value];   }@@ -1257,2 +1353,5 @@     return thing instanceof this ? thing : new this(thing);+  }+  static parseParameters(value) {+    return parseParameters(value);   }@@ -1352,5 +1451,29 @@ }+function stringifySafely$1(value) {+  try {+    return String(value);+  } catch (err) {+    return '';+  }+}+function aggregateErrorMessage(error) {+  const message = error.errors.map(entry => {+    try {+      return entry && entry.message ? stringifySafely$1(entry.message) : stringifySafely$1(entry);+    } catch (err) {+      return '';+    }+  }).filter(Boolean).join('; ');+  return message || error.name || 'AggregateError';+} class AxiosError extends Error {   static from(error, code, config, request, response, customProps) {-    const axiosError = new AxiosError(error.message, code || error.code, config, request, response);+    // `AggregateError` (thrown by Node on dual-stack/Happy-Eyeballs connection+    // failures) has an empty `message`; its detail lives in `errors[]`. Without+    // this, the wrapped error surfaces with a blank message (see #6721).+    let message = error.message;+    if (!message && utils$1.isArray(error.errors) && error.errors.length) {+      message = aggregateErrorMessage(error);+    }+    const axiosError = new AxiosError(message, code || error.code, config, request, response);     // Match native `Error` `cause` semantics: non-enumerable. The wrapped@@ -1458,2 +1581,11 @@ +var PlatformBuffer = {+  isBufferAvailable() {+    return typeof Buffer !== 'undefined';+  },+  from(value) {+    return Buffer.from(value);+  }+};+ // Default nesting limit shared with the inverse transform (formDataToJSON) so@@ -1583,4 +1715,4 @@       }-      if (typeof Buffer !== 'undefined') {-        return Buffer.from(value);+      if (PlatformBuffer && PlatformBuffer.isBufferAvailable()) {+        return PlatformBuffer.from(value);       }@@ -1964,8 +2096,14 @@ function parsePropPath(name) {-  // foo[x][y][z]-  // foo.x.y.z-  // foo-x-y-z-  // foo x y z+  // foo[x][y][z] -> ['foo', 'x', 'y', 'z']+  // foo.x.y.z    -> ['foo', 'x', 'y', 'z']+  // A path is split on `.` and on `[...]` groups. A segment — whether written+  // in dot notation or captured inside brackets — may contain any character+  // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept+  // literal instead of being split (#5402). `.`, `[` and `]` keep their existing+  // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.+  // Excluding `[` from the bracket group also makes the match fail fast at the+  // next `[`, so a malformed name cannot rescan to the end of the string from+  // every unmatched `[` — parsing stays linear in the length of the name.   const path = [];-  const pattern = /\w+|\[(\w*)]/g;+  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;   let match;@@ -2245,3 +2383,10 @@ function combineURLs(baseURL, relativeURL) {-  return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;+  if (!relativeURL) {+    return baseURL;+  }+  let end = baseURL.length;+  while (end > 0 && baseURL.charCodeAt(end - 1) === 47) {+    end--;+  }+  return baseURL.slice(0, end) + '/' + relativeURL.replace(/^\/+/, ''); }@@ -2260,5 +2405,35 @@ }++// Redact the parts of a URL that can carry secrets before it is embedded in an+// error message. AxiosError.toJSON() serializes `message` verbatim and errors+// are commonly logged, while the opt-in `config.redact` model only cleans+// config keys — it cannot reach the message. Redact only the genuinely+// sensitive substrings — userinfo (credentials), query parameter values and+// fragment contents — with the same REDACTED marker the config redaction uses,+// while keeping the scheme, host, path and parameter names so the offending+// request stays accurately identifiable.+function redactFragment(fragment) {+  if (!fragment) {+    return fragment;+  }+  return fragment.replace(/(^|&)([^=&]*=)?[^&]+/g, (match, separator, parameterName = '') => {+    return `${separator}${parameterName}${REDACTED}`;+  });+}+function redactSensitiveURLParts(url) {+  const redactedURL = url.replace(/^(https?:\/{0,2})[^/?#]*@/i, `$1${REDACTED}@`);
… 464 more lines (truncated)
lib/helpers/estimateDataURLDecodedBytes.js +115 lines · 1 flagged
--- +++ @@ -1,9 +1,7 @@ /**- * Estimate decoded byte length of a data:// URL *without* allocating large buffers.- * - For base64: compute exact decoded size using length and padding;- *               handle %XX at the character-count level (no string allocation).- * - For non-base64: compute the exact percent-decoded UTF-8 byte length.- *- * @param {string} url- * @returns {number}+ * Estimate data: URL byte lengths *without* allocating large buffers.+ * - Fetch percent-decodes a base64 body before decoding it.+ * - Node's Buffer.from(body, 'base64') sizes its backing allocation from the+ *   raw body, including ignored characters and content after padding.+ * - Non-base64 data is percent-decoded and then encoded as UTF-8.  */@@ -17,3 +15,85 @@ -export default function estimateDataURLDecodedBytes(url) {+const hexValue = (charCode) => (charCode <= 57 ? charCode - 48 : (charCode & 0xdf) - 55);++const isBase64Char = (charCode) =>+  (charCode >= 65 && charCode <= 90) || // A-Z+  (charCode >= 97 && charCode <= 122) || // a-z+  (charCode >= 48 && charCode <= 57) || // 0-9+  charCode === 43 || // ++  charCode === 47 || // /+  charCode === 45 || // - (base64url)+  charCode === 95; // _ (base64url)++const isBase64Whitespace = (charCode) =>+  charCode === 9 || charCode === 10 || charCode === 12 || charCode === 13 || charCode === 32;++const base64Bytes = (significant) => {+  const groups = Math.floor(significant / 4);+  const remainder = significant % 4;+  return groups * 3 + (remainder === 2 ? 1 : remainder === 3 ? 2 : 0);+};++// Buffer.byteLength(body, 'base64') uses the raw string length as an allocation+// upper bound even when Buffer.from later ignores characters or stops at '='.+const estimateBase64BufferAllocation = (body) => {+  const len = body.length;+  let padding = 0;++  if (len > 0 && body.charCodeAt(len - 1) === 61 /* '=' */) {+    padding++;++    if (len > 1 && body.charCodeAt(len - 2) === 61 /* '=' */) {+      padding++;+    }+  }++  return Math.floor(((len - padding) * 3) / 4);+};++const estimatePercentDecodedBase64Bytes = (body) => {+  const len = body.length;+  let significant = 0;+  let padding = 0;+  let invalid = false;++  for (let i = 0; i < len; i++) {+    let code = body.charCodeAt(i);++    if (code === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {+      code = hexValue(body.charCodeAt(i + 1)) * 16 + hexValue(body.charCodeAt(i + 2));+      i += 2;+    }++    if (isBase64Whitespace(code)) {+      continue;+    }++    if (code === 61 /* '=' */) {+      padding++;+      continue;+    }++    if (!isBase64Char(code) || padding > 0) {+      invalid = true;+      continue;+    }++    significant++;+  }++  // Fetch rejects malformed forgiving-base64 input. Returning the raw-size+  // allocation bound keeps that invalid input from becoming a pre-check bypass.+  if (+    invalid ||+    padding > 2 ||+    (padding > 0 && (significant + padding) % 4 !== 0) ||+    significant % 4 === 1+  ) {+    return estimateBase64BufferAllocation(body);+  }++  return base64Bytes(significant);+};++const estimateDataURLBytes = (url, estimateBase64) => {   if (!url || typeof url !== 'string') return 0;@@ -29,48 +109,3 @@   if (isBase64) {-    let effectiveLen = body.length;-    const len = body.length; // cache length--    for (let i = 0; i < len; i++) {-      if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {-        const a = body.charCodeAt(i + 1);-        const b = body.charCodeAt(i + 2);-        const isHex = isHexDigit(a) && isHexDigit(b);--        if (isHex) {-          effectiveLen -= 2;-          i += 2;-        }-      }-    }--    let pad = 0;-    let idx = len - 1;--    const tailIsPct3D = (j) =>-      j >= 2 &&-      body.charCodeAt(j - 2) === 37 && // '%'-      body.charCodeAt(j - 1) === 51 && // '3'-      (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd'--    if (idx >= 0) {-      if (body.charCodeAt(idx) === 61 /* '=' */) {-        pad++;-        idx--;-      } else if (tailIsPct3D(idx)) {-        pad++;-        idx -= 3;-      }-    }--    if (pad === 1 && idx >= 0) {-      if (body.charCodeAt(idx) === 61 /* '=' */) {-        pad++;-      } else if (tailIsPct3D(idx)) {-        pad++;-      }-    }--    const groups = Math.floor(effectiveLen / 4);-    const bytes = groups * 3 - (pad || 0);-    return bytes > 0 ? bytes : 0;+    return estimateBase64(body);   }@@ -104,2 +139,28 @@   return bytes;+};++/**+ * Estimate the percent-decoded payload size used by Fetch data: URLs.+ *+ * @param {string} url+ * @returns {number}+ */+export default function estimateDataURLDecodedBytes(url) {+  // Fetch removes URL fragments before processing a data: URL.+  const fragmentIndex = typeof url === 'string' ? url.indexOf('#') : -1;++  return estimateDataURLBytes(+    fragmentIndex === -1 ? url : url.slice(0, fragmentIndex),+    estimatePercentDecodedBase64Bytes+  ); }++/**+ * Estimate the Buffer backing allocation used by Node's raw base64 decoder.+ *+ * @param {string} url+ * @returns {number}+ */+export function estimateDataURLBufferAllocation(url) {+  return estimateDataURLBytes(url, estimateBase64BufferAllocation);+}
index.d.ts +103 lines
--- +++ @@ -4,2 +4,4 @@ export type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null;++export type AxiosHeaderParameters = Record<string, string>; @@ -35,2 +37,3 @@ +  get(headerName: string, parser: typeof AxiosHeaders.parseParameters): AxiosHeaderParameters;   get(headerName: string, parser: RegExp): RegExpExecArray | null;@@ -55,2 +58,4 @@   static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;++  static parseParameters(value: AxiosHeaderValue): AxiosHeaderParameters; @@ -238,2 +243,3 @@   NetworkAuthenticationRequired = 511,+  WebServerReturnsAnUnknownError = 520,   WebServerIsDown = 521,@@ -337,9 +343,9 @@ -export interface CustomParamsSerializer {-  (params: Record<string, any>, options?: ParamsSerializerOptions): string;-}--export interface ParamsSerializerOptions extends SerializerOptions {+export interface CustomParamsSerializer<P = Record<string, any>> {+  (params: P, options?: ParamsSerializerOptions<P>): string;+}++export interface ParamsSerializerOptions<P = Record<string, any>> extends SerializerOptions {   encode?: ParamEncoder;-  serialize?: CustomParamsSerializer;+  serialize?: CustomParamsSerializer<P>; }@@ -380,3 +386,3 @@ -export interface AxiosRequestConfig<D = any> {+export interface AxiosRequestConfig<D = any, P = any> {   url?: string;@@ -388,4 +394,6 @@   headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;-  params?: any;-  paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer;+  params?: P;+  paramsSerializer?:+    | ParamsSerializerOptions<unknown extends P ? Record<string, any> : P>+    | CustomParamsSerializer<unknown extends P ? Record<string, any> : P>;   data?: D;@@ -457,3 +465,3 @@       >);-  withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);+  withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig<D, P>) => boolean | undefined);   parseReviver?: (this: any, key: string, value: any, context?: { source?: string }) => any;@@ -470,5 +478,5 @@ // Alias-export type RawAxiosRequestConfig<D = any> = AxiosRequestConfig<D>;--export interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {+export type RawAxiosRequestConfig<D = any, P = any> = AxiosRequestConfig<D, P>;++export interface InternalAxiosRequestConfig<D = any, P = any> extends AxiosRequestConfig<D, P> {   headers: AxiosRequestHeaders;@@ -491,3 +499,3 @@ -export interface AxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {+export interface AxiosDefaults<D = any, P = any> extends Omit<AxiosRequestConfig<D, P>, 'headers'> {   headers: HeadersDefaults;@@ -495,3 +503,6 @@ -export interface CreateAxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {+export interface CreateAxiosDefaults<D = any, P = any> extends Omit<+  AxiosRequestConfig<D, P>,+  'headers'+> {   headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;@@ -499,3 +510,3 @@ -export interface AxiosResponse<T = any, D = any, H = {}> {+export interface AxiosResponse<T = any, D = any, H = {}, P = any> {   data: T;@@ -504,3 +515,3 @@   headers: (H & RawAxiosResponseHeaders) | AxiosResponseHeaders;-  config: InternalAxiosRequestConfig<D>;+  config: InternalAxiosRequestConfig<D, P>;   request?: any;@@ -508,3 +519,3 @@ -export class AxiosError<T = unknown, D = any> extends Error {+export class AxiosError<T = unknown, D = any, P = any> extends Error {   constructor(@@ -512,11 +523,11 @@     code?: string,-    config?: InternalAxiosRequestConfig<D>,+    config?: InternalAxiosRequestConfig<D, P>,     request?: any,-    response?: AxiosResponse<T, D>+    response?: AxiosResponse<T, D, {}, P>   ); -  config?: InternalAxiosRequestConfig<D>;+  config?: InternalAxiosRequestConfig<D, P>;   code?: string;   request?: any;-  response?: AxiosResponse<T, D>;+  response?: AxiosResponse<T, D, {}, P>;   isAxiosError: boolean;@@ -526,10 +537,10 @@   event?: BrowserProgressEvent;-  static from<T = unknown, D = any>(+  static from<T = unknown, D = any, P = any>(     error: Error | unknown,     code?: string,-    config?: InternalAxiosRequestConfig<D>,+    config?: InternalAxiosRequestConfig<D, P>,     request?: any,-    response?: AxiosResponse<T, D>,+    response?: AxiosResponse<T, D, {}, P>,     customProps?: object-  ): AxiosError<T, D>;+  ): AxiosError<T, D, P>;   static readonly ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS';@@ -550,4 +561,4 @@ -export class CanceledError<T> extends AxiosError<T> {-  constructor(message?: string, config?: InternalAxiosRequestConfig, request?: any);+export class CanceledError<T, D = any, P = any> extends AxiosError<T, D, P> {+  constructor(message?: string, config?: InternalAxiosRequestConfig<D, P>, request?: any);   readonly name: 'CanceledError';@@ -556,3 +567,11 @@ -export type AxiosPromise<T = any> = Promise<AxiosResponse<T>>;+declare const axiosResponseDefault: unique symbol;++type AxiosResponseDefault = typeof axiosResponseDefault;++type AxiosResponseResult<T, R, D, P> = R extends AxiosResponseDefault+  ? AxiosResponse<T, D, {}, P>+  : R;++export type AxiosPromise<T = any, D = any, P = any> = Promise<AxiosResponse<T, D, {}, P>>; @@ -630,54 +649,56 @@   getUri(config?: AxiosRequestConfig): string;-  request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;-  get<T = any, R = AxiosResponse<T>, D = any>(-    url: string,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  delete<T = any, R = AxiosResponse<T>, D = any>(-    url: string,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  head<T = any, R = AxiosResponse<T>, D = any>(-    url: string,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  options<T = any, R = AxiosResponse<T>, D = any>(-    url: string,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  post<T = any, R = AxiosResponse<T>, D = any>(+  request<T = any, R = AxiosResponseDefault, D = any, P = any>(+    config: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  get<T = any, R = AxiosResponseDefault, D = any, P = any>(+    url: string,+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  delete<T = any, R = AxiosResponseDefault, D = any, P = any>(+    url: string,+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  head<T = any, R = AxiosResponseDefault, D = any, P = any>(+    url: string,+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  options<T = any, R = AxiosResponseDefault, D = any, P = any>(+    url: string,+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  post<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  put<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  put<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  patch<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  patch<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  postForm<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  postForm<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  putForm<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  putForm<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  patchForm<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  patchForm<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;-  query<T = any, R = AxiosResponse<T>, D = any>(+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  query<T = any, R = AxiosResponseDefault, D = any, P = any>(     url: string,     data?: D,-    config?: AxiosRequestConfig<D>-  ): Promise<R>;+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>; }@@ -685,4 +706,9 @@ export interface AxiosInstance extends Axios {-  <T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;-  <T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;+  <T = any, R = AxiosResponseDefault, D = any, P = any>(+    config: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>;+  <T = any, R = AxiosResponseDefault, D = any, P = any>(+    url: string,+    config?: AxiosRequestConfig<D, P>+  ): Promise<AxiosResponseResult<T, R, D, P>>; 
… 23 more lines (truncated)
lib/adapters/http.js +7 lines
--- +++ @@ -21,2 +21,3 @@ import AxiosHeaders from '../core/AxiosHeaders.js';+import setFormDataHeaders from '../core/setFormDataHeaders.js'; import AxiosTransformStream from '../helpers/AxiosTransformStream.js';@@ -35,3 +36,3 @@ } from '../helpers/progressEventReducer.js';-import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';+import { estimateDataURLBufferAllocation } from '../helpers/estimateDataURLDecodedBytes.js'; @@ -56,2 +57,4 @@ const ACCEPT_ENCODING_WITH_ZSTD = ACCEPT_ENCODING + (isZstdSupported ? ', zstd' : '');+const scheduleProgress =+  typeof process !== 'undefined' && process.nextTick ? process.nextTick.bind(process) : utils.asap; @@ -60,16 +63,2 @@ const isHttps = /https:?/;-const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length'];--function setFormDataHeaders(headers, formHeaders, policy) {-  if (policy !== 'content-only') {-    headers.set(formHeaders);-    return;-  }--  Object.entries(formHeaders).forEach(([key, val]) => {-    if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {-      headers.set(key, val);-    }-  });-} @@ -677,3 +666,3 @@           const dataUrl = String(own('url') || fullPath || '');-          const estimated = estimateDataURLDecodedBytes(dataUrl);+          const estimated = estimateDataURLBufferAllocation(dataUrl); @@ -844,3 +833,3 @@                 contentLength,-                progressEventReducer(asyncDecorator(onUploadProgress), false, 3)+                progressEventReducer(asyncDecorator(onUploadProgress, scheduleProgress), false, 3)               )@@ -1082,3 +1071,3 @@                   responseLength,-                  progressEventReducer(asyncDecorator(onDownloadProgress), true, 3)+                  progressEventReducer(asyncDecorator(onDownloadProgress, scheduleProgress), true, 3)                 )
lib/core/Axios.js +24 lines
--- +++ @@ -211,5 +211,21 @@       try {-        newConfig = onFulfilled(newConfig);+        newConfig = onFulfilled ? onFulfilled(newConfig) : newConfig;       } catch (error) {-        onRejected.call(this, error);+        if (!onRejected) {+          promise = Promise.reject(error);+          break;+        }++        try {+          const rejectedResult = onRejected.call(this, error);++          if (utils.isThenable(rejectedResult)) {+            promise = Promise.resolve(rejectedResult).then(() =>+              dispatchRequest.call(this, newConfig)+            );+          }+        } catch (rejectedError) {+          promise = Promise.reject(rejectedError);+        }+         break;@@ -218,6 +234,8 @@ -    try {-      promise = dispatchRequest.call(this, newConfig);-    } catch (error) {-      return Promise.reject(error);+    if (!promise) {+      try {+        promise = dispatchRequest.call(this, newConfig);+      } catch (error) {+        promise = Promise.reject(error);+      }     }
lib/core/AxiosError.js +33 lines
--- +++ @@ -5,3 +5,3 @@ -const REDACTED = '[REDACTED ****]';+export const REDACTED = '[REDACTED ****]'; @@ -74,5 +74,36 @@ +function stringifySafely(value) {+  try {+    return String(value);+  } catch (err) {+    return '';+  }+}++function aggregateErrorMessage(error) {+  const message = error.errors+    .map((entry) => {+      try {+        return entry && entry.message ? stringifySafely(entry.message) : stringifySafely(entry);+      } catch (err) {+        return '';+      }+    })+    .filter(Boolean)+    .join('; ');++  return message || error.name || 'AggregateError';+}+ class AxiosError extends Error {   static from(error, code, config, request, response, customProps) {-    const axiosError = new AxiosError(error.message, code || error.code, config, request, response);+    // `AggregateError` (thrown by Node on dual-stack/Happy-Eyeballs connection+    // failures) has an empty `message`; its detail lives in `errors[]`. Without+    // this, the wrapped error surfaces with a blank message (see #6721).+    let message = error.message;+    if (!message && utils.isArray(error.errors) && error.errors.length) {+      message = aggregateErrorMessage(error);+    }++    const axiosError = new AxiosError(message, code || error.code, config, request, response);     // Match native `Error` `cause` semantics: non-enumerable. The wrapped
lib/core/AxiosHeaders.js +124 lines
--- +++ @@ -30,2 +30,120 @@   return tokens;+}++const parameterNameRE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;++function trimOWS(value) {+  let start = 0;+  let end = value.length;++  while (start < end) {+    const code = value.charCodeAt(start);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    start += 1;+  }++  while (end > start) {+    const code = value.charCodeAt(end - 1);++    if (code !== 0x09 && code !== 0x20) {+      break;+    }++    end -= 1;+  }++  return start === 0 && end === value.length ? value : value.slice(start, end);+}++function decodeQuotedString(value) {+  const last = value.length - 1;++  if (last < 1 || value.charCodeAt(0) !== 0x22 || value.charCodeAt(last) !== 0x22) {+    return value;+  }++  let decoded = '';++  for (let i = 1; i < last; i++) {+    const code = value.charCodeAt(i);++    if (code === 0x22) {+      return value;+    }++    if (code === 0x5c) {+      i += 1;++      if (i >= last) {+        return value;+      }+    }++    decoded += value[i];+  }++  return decoded;+}++function parseParameters(value) {+  const parameters = Object.create(null);+  const str = String(value);+  let start = 0;+  let quoted = false;+  let escaped = false;++  function parseParameter(end) {+    const part = trimOWS(str.slice(start, end));+    const equals = part.indexOf('=');++    if (equals < 1) {+      return;+    }++    const name = trimOWS(part.slice(0, equals));++    if (!parameterNameRE.test(name)) {+      return;+    }++    const normalizedName = name.toLowerCase();++    if (+      normalizedName === '__proto__' ||+      normalizedName === 'constructor' ||+      normalizedName === 'prototype'+    ) {+      return;+    }++    const parameterValue = trimOWS(part.slice(equals + 1));+    parameters[normalizedName] = decodeQuotedString(parameterValue);+  }++  for (let i = 0; i < str.length; i++) {+    const code = str.charCodeAt(i);++    if (quoted) {+      if (escaped) {+        escaped = false;+      } else if (code === 0x5c) {+        escaped = true;+      } else if (code === 0x22) {+        quoted = false;+      }+    } else if (code === 0x22) {+      quoted = true;+    } else if (code === 0x2c || code === 0x3b) {+      parseParameter(i);+      start = i + 1;+    }+  }++  parseParameter(str.length);++  return parameters; }@@ -283,3 +401,4 @@   getSetCookie() {-    return this.get('set-cookie') || [];+    const value = this.get('set-cookie');+    return utils.isArray(value) ? value : value == null || value === false ? [] : [value];   }@@ -292,2 +411,6 @@     return thing instanceof this ? thing : new this(thing);+  }++  static parseParameters(value) {+    return parseParameters(value);   }
lib/core/buildFullPath.js +45 lines
--- +++ @@ -2,3 +2,3 @@ -import AxiosError from './AxiosError.js';+import AxiosError, { REDACTED } from './AxiosError.js'; import isAbsoluteURL from '../helpers/isAbsoluteURL.js';@@ -21,9 +21,47 @@ +// Redact the parts of a URL that can carry secrets before it is embedded in an+// error message. AxiosError.toJSON() serializes `message` verbatim and errors+// are commonly logged, while the opt-in `config.redact` model only cleans+// config keys — it cannot reach the message. Redact only the genuinely+// sensitive substrings — userinfo (credentials), query parameter values and+// fragment contents — with the same REDACTED marker the config redaction uses,+// while keeping the scheme, host, path and parameter names so the offending+// request stays accurately identifiable.+function redactFragment(fragment) {+  if (!fragment) {+    return fragment;+  }++  return fragment.replace(/(^|&)([^=&]*=)?[^&]+/g, (match, separator, parameterName = '') => {+    return `${separator}${parameterName}${REDACTED}`;+  });+}++function redactSensitiveURLParts(url) {+  const redactedURL = url.replace(/^(https?:\/{0,2})[^/?#]*@/i, `$1${REDACTED}@`);+  const fragmentIndex = redactedURL.indexOf('#');+  const urlWithoutFragment =+    fragmentIndex === -1 ? redactedURL : redactedURL.slice(0, fragmentIndex);+  const redactedURLWithoutFragment = urlWithoutFragment.replace(+    /([?&][^=&#]*=)[^&#]*/g,+    `$1${REDACTED}`+  );++  if (fragmentIndex === -1) {+    return redactedURLWithoutFragment;+  }++  return `${redactedURLWithoutFragment}#${redactFragment(redactedURL.slice(fragmentIndex + 1))}`;+}+ function assertValidHttpProtocolURL(url, config) {-  if (typeof url === 'string' && malformedHttpProtocol.test(normalizeURLForProtocolCheck(url))) {-    throw new AxiosError(-      'Invalid URL: missing "//" after protocol',-      AxiosError.ERR_INVALID_URL,-      config-    );+  if (typeof url === 'string') {+    const normalizedURL = normalizeURLForProtocolCheck(url);+    if (malformedHttpProtocol.test(normalizedURL)) {+      throw new AxiosError(+        `Invalid URL ${JSON.stringify(redactSensitiveURLParts(normalizedURL))}: missing "//" after protocol`,+        AxiosError.ERR_INVALID_URL,+        config+      );+    }   }
lib/core/mergeConfig.js +18 lines
--- +++ @@ -6,2 +6,13 @@ const headersToObject = (thing) => (thing instanceof AxiosHeaders ? { ...thing } : thing);++const ownEnumerableKeys = (thing) => {+  if (Object.getOwnPropertySymbols && Object.getOwnPropertyDescriptor) {+    return Object.keys(thing).concat(+      Object.getOwnPropertySymbols(thing).filter(+        (symbol) => Object.getOwnPropertyDescriptor(thing, symbol).enumerable+      )+    );+  }+  return Object.keys(thing);+}; @@ -72,3 +83,5 @@   function getMergedTransitionalOption(prop) {-    const transitional2 = utils.hasOwnProp(config2, 'transitional') ? config2.transitional : undefined;+    const transitional2 = utils.hasOwnProp(config2, 'transitional')+      ? config2.transitional+      : undefined; @@ -84,3 +97,5 @@ -    const transitional1 = utils.hasOwnProp(config1, 'transitional') ? config1.transitional : undefined;+    const transitional1 = utils.hasOwnProp(config1, 'transitional')+      ? config1.transitional+      : undefined; @@ -136,3 +151,3 @@ -  utils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {+  utils.forEach(ownEnumerableKeys({ ...config1, ...config2 }), function computeConfigValue(prop) {     if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') return;
lib/core/setFormDataHeaders.js +27 lines
--- +++ @@ -0,0 +1,27 @@+'use strict';++const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length'];++/**+ * Apply the headers generated by a FormData implementation to the request headers,+ * honoring the `formDataHeaderPolicy` option: with 'content-only', copy only the+ * content-* headers; otherwise merge all of them.+ *+ * @param {AxiosHeaders} headers - the request headers to mutate+ * @param {Object | null | undefined} formHeaders - headers produced by the FormData implementation+ * @param {String} [policy] - the resolved `formDataHeaderPolicy` config value+ *+ * @returns {void}+ */+export default function setFormDataHeaders(headers, formHeaders, policy) {+  if (policy !== 'content-only') {+    headers.set(formHeaders);+    return;+  }++  Object.entries(formHeaders || {}).forEach(([key, val]) => {+    if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {+      headers.set(key, val);+    }+  });+}
lib/env/data.js +1 lines
--- +++ @@ -1 +1 @@-export const VERSION = "1.18.1";+export const VERSION = "1.19.0";
lib/helpers/HttpStatusCode.js +1 lines
--- +++ @@ -64,2 +64,3 @@   NetworkAuthenticationRequired: 511,+  WebServerReturnsAnUnknownError: 520,   WebServerIsDown: 521,
lib/helpers/combineURLs.js +11 lines
--- +++ @@ -11,5 +11,13 @@ export default function combineURLs(baseURL, relativeURL) {-  return relativeURL-    ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '')-    : baseURL;+  if (!relativeURL) {+    return baseURL;+  }++  let end = baseURL.length;++  while (end > 0 && baseURL.charCodeAt(end - 1) === 47) {+    end--;+  }++  return baseURL.slice(0, end) + '/' + relativeURL.replace(/^\/+/, ''); }
lib/helpers/composeSignals.js +12 lines
--- +++ @@ -47,3 +47,14 @@ -  signals.forEach((signal) => signal.addEventListener('abort', onabort, { once: true }));+  signals.forEach((signal) => {+    if (aborted) {+      return;+    }++    if (signal.aborted) {+      onabort.call(signal);+      return;+    }++    signal.addEventListener('abort', onabort, { once: true });+  }); 
lib/helpers/formDataToJSON.js +11 lines
--- +++ @@ -25,8 +25,14 @@ function parsePropPath(name) {-  // foo[x][y][z]-  // foo.x.y.z-  // foo-x-y-z-  // foo x y z+  // foo[x][y][z] -> ['foo', 'x', 'y', 'z']+  // foo.x.y.z    -> ['foo', 'x', 'y', 'z']+  // A path is split on `.` and on `[...]` groups. A segment — whether written+  // in dot notation or captured inside brackets — may contain any character+  // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept+  // literal instead of being split (#5402). `.`, `[` and `]` keep their existing+  // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.+  // Excluding `[` from the bracket group also makes the match fail fast at the+  // next `[`, so a malformed name cannot rescan to the end of the string from+  // every unmatched `[` — parsing stays linear in the length of the name.   const path = [];-  const pattern = /\w+|\[(\w*)]/g;+  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;   let match;
lib/helpers/parseHeaders.js +5 lines
--- +++ @@ -52,3 +52,5 @@ -      if (!key || (parsed[key] && ignoreDuplicateOf[key])) {+      const hasKey = utils.hasOwnProp(parsed, key);++      if (!key || (hasKey && utils.hasOwnProp(ignoreDuplicateOf, key))) {         return;@@ -57,3 +59,3 @@       if (key === 'set-cookie') {-        if (parsed[key]) {+        if (hasKey) {           parsed[key].push(val);@@ -63,3 +65,3 @@       } else {-        parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;+        parsed[key] = hasKey ? parsed[key] + ', ' + val : val;       }
lib/helpers/progressEventReducer.js +3 lines
--- +++ @@ -14,3 +14,3 @@     const total = e.lengthComputable ? e.total : undefined;-    const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;+    const loaded = Math.max(0, total != null ? Math.min(rawLoaded, total) : rawLoaded);     const progressBytes = Math.max(0, loaded - bytesNotified);@@ -51,4 +51,4 @@ export const asyncDecorator =-  (fn) =>+  (fn, scheduler = utils.asap) =>   (...args) =>-    utils.asap(() => fn(...args));+    scheduler(() => fn(...args));
lib/helpers/resolveConfig.js +1 lines
--- +++ @@ -8,18 +8,4 @@ import AxiosHeaders from '../core/AxiosHeaders.js';+import setFormDataHeaders from '../core/setFormDataHeaders.js'; import buildURL from './buildURL.js';--const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length'];--function setFormDataHeaders(headers, formHeaders, policy) {-  if (policy !== 'content-only') {-    headers.set(formHeaders);-    return;-  }--  Object.entries(formHeaders || {}).forEach(([key, val]) => {-    if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {-      headers.set(key, val);-    }-  });-} 
lib/helpers/shouldBypassProxy.js +120 lines
--- +++ @@ -7,2 +7,108 @@   return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);+};++/**+ * Canonicalize an IPv4 address written in shorthand, octal, or hex form into+ * dotted-decimal. IPv6 addresses and non-IP strings are returned unchanged so+ * the existing IPv4-mapped IPv6 unmap path and the isLoopback path can still+ * see them.+ *+ * Shorthand expansion mirrors Node's URL parser: literal parts fill from the+ * left, the final part fills the remaining octets from the right with+ * zero-padding on the left.+ *   127.1     -> 127.0.0.1+ *   127.0.1   -> 127.0.0.1+ *   1.2.3     -> 1.2.0.3+ *+ * Each octet is parsed with an explicit base: 16 for `0x`/`0X` prefix, 8 for+ * zero-prefixed multi-digit all-`0-7` parts, 10 otherwise. Zero-prefixed+ * decimal-looking parts that contain `8` or `9` are rejected to match Node's+ * URL parser, and the comparison layer falls through to non-bypass if either+ * side rejects the form (fail-safe).+ *+ * Returns the input unchanged on any parse failure, out-of-range octet, or+ * unusual shape (1-part, 5+ parts) so the comparison layer fails closed.+ */+const parseIPv4Octet = (text) => {+  if (/^0[xX][0-9a-fA-F]+$/.test(text)) {+    const n = parseInt(text.slice(2), 16);+    return Number.isFinite(n) ? n : null;+  }+  if (text.length > 1 && /^0[0-7]+$/.test(text)) {+    const n = parseInt(text, 8);+    return Number.isFinite(n) ? n : null;+  }+  if (text.length > 1 && /^0[0-9]+$/.test(text)) {+    return null;+  }+  if (/^[0-9]+$/.test(text)) {+    const n = parseInt(text, 10);+    return Number.isFinite(n) ? n : null;+  }+  return null;+};++const normalizeIPAddress = (host) => {+  if (typeof host !== 'string' || !host || host.indexOf(':') !== -1) {+    return host;+  }++  let h = host;+  if (h.charAt(0) === '[' && h.charAt(h.length - 1) === ']') {+    h = h.slice(1, -1);+  }+  h = h.replace(/\.+$/, '');++  // Allowed characters for any IPv4 shape: digits, dot, 'x', 'X', hex digits.+  if (!/^[0-9.xXa-fA-F]+$/.test(h)) return host;++  const parts = h.split('.');++  // No part may be empty (e.g. "127..0.1" or "127.0.0."). Trailing dots are+  // already stripped above; this guards against the empty-middle case.+  if (parts.some((p) => p === '')) return host;++  if (parts.length === 4) {+    // Full IPv4 form: each part is an octet.+    const octets = parts.map(parseIPv4Octet);+    if (octets.some((n) => n === null || n < 0 || n > 255)) return host;+    return octets.join('.');+  }++  if (parts.length > 4) {+    return host;+  }++  // Shorthand: 1..3 parts. Node's URL parser treats a 1-part input as a 32-bit+  // integer split into octets, which has surprising semantics (e.g. "127" ->+  // "0.0.0.127"). Reject 1-part inputs to keep the helper predictable: the+  // fail-safe returns the input unchanged and the comparison layer falls+  // through to non-bypass.+  if (parts.length === 1) return host;++  // 2..3 parts: literal parts fill from the left, tail fills remaining octets+  // from the right with zero-padding.+  const literalOctets = parts.slice(0, -1);+  const tail = parts[parts.length - 1];+  const tailSlots = 4 - literalOctets.length;++  // Tail is parsed as a full IPv4 number (hex/octal/decimal) and packed+  // low-byte-right into the remaining octets, matching Node's URL parser.+  // e.g. 127.65535 (tail 0xFFFF into 3 slots) -> 127.0.255.255;+  //      127.0x00ff (tail 0xFF into 3 slots) -> 127.0.0.255;+  //      127.0.65535 (tail 0xFFFF into 2 slots) -> 127.0.255.255.+  const tailValue = parseIPv4Octet(tail);+  if (tailValue === null) return host;+  const maxTail = (1 << (8 * tailSlots)) - 1;+  if (tailValue < 0 || tailValue > maxTail) return host;++  const tailOctets = new Array(tailSlots).fill(0);+  for (let i = tailSlots - 1, v = tailValue; i >= 0; i--, v >>= 8) {+    tailOctets[i] = v & 0xff;+  }++  const literal = literalOctets.map(parseIPv4Octet);+  if (literal.some((n) => n === null || n < 0 || n > 255)) return host;++  return [...literal, ...tailOctets].join('.'); };@@ -155,3 +261,12 @@ -  return unmapIPv4MappedIPv6(hostname.replace(/\.+$/, ''));+  const trimmed = hostname.replace(/\.+$/, '');++  // IPv4 shorthand/octal/hex → dotted-decimal; helper is a no-op for inputs+  // containing ':' (IPv6 and IPv4-mapped IPv6) so we fall through to unmap.+  const ipv4 = normalizeIPAddress(trimmed);+  if (ipv4 !== trimmed) {+    return ipv4;+  }++  return unmapIPv4MappedIPv6(trimmed); };@@ -187,2 +302,6 @@ +    if (entry === '*') {+      return true;+    }+     let [entryHost, entryPort] = parseNoProxyEntry(entry);
lib/helpers/toFormData.js +3 lines
--- +++ @@ -6,2 +6,3 @@ import PlatformFormData from '../platform/node/classes/FormData.js';+import PlatformBuffer from '../platform/node/classes/Buffer.js'; @@ -148,4 +149,4 @@       }-      if (typeof Buffer !== 'undefined') {-        return Buffer.from(value);+      if (PlatformBuffer && PlatformBuffer.isBufferAvailable()) {+        return PlatformBuffer.from(value);       }
lib/platform/node/classes/Buffer.js +11 lines
--- +++ @@ -0,0 +1,11 @@+'use strict';++export default {+  isBufferAvailable() {+    return typeof Buffer !== 'undefined';+  },++  from(value) {+    return Buffer.from(value);+  }+};
lib/utils.js +18 lines
--- +++ @@ -284,2 +284,3 @@ const isFileList = kindOfTest('FileList');+const isSet = kindOfTest('Set'); @@ -849,8 +850,19 @@         visited.add(source);-        const target = isArray(source) ? [] : {};--        forEach(source, (value, key) => {-          const reducedValue = visit(value);-          !isUndefined(reducedValue) && (target[key] = reducedValue);-        });++        let target;++        if (isSet(source)) {+          target = [];+          for (const value of source) {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && target.push(reducedValue);+          }+        } else {+          target = isArray(source) ? [] : {};++          forEach(source, (value, key) => {+            const reducedValue = visit(value);+            !isUndefined(reducedValue) && (target[key] = reducedValue);+          });+        } 
babel-core npm
6.26.3 8y ago incident on record
DELETION ×6BURST ×36
latest 6.26.3 versions 257 maintainers 3
6.20.0
6.21.0
6.22.0
6.22.1
6.23.0
6.23.1
6.24.0
6.24.1
6.25.0
6.26.0
6.26.2
6.26.3
DELETION
5.6.0 published then removed
high · registry-verified · 2015-06-20 · 11y ago
DELETION
5.6.8 published then removed
high · registry-verified · 2015-06-25 · 11y ago
DELETION
5.6.9 published then removed
high · registry-verified · 2015-06-25 · 11y ago
DELETION
5.6.17 published then removed
high · registry-verified · 2015-07-09 · 11y ago
DELETION
5.8.4 published then removed
high · registry-verified · 2015-07-24 · 11y ago
DELETION
6.18.1 published then removed
high · registry-verified · 2016-11-01 · 9y ago
BURST
2 releases in 9m: 4.2.0, 4.2.1
info · registry-verified · 2015-02-18 · 11y ago
BURST
2 releases in 8m: 4.4.1, 4.4.2
info · registry-verified · 2015-02-21 · 11y ago
BURST
2 releases in 36m: 4.4.4, 4.4.5
info · registry-verified · 2015-02-22 · 11y ago
BURST
2 releases in 54m: 4.5.0, 4.5.1
info · registry-verified · 2015-02-25 · 11y ago
BURST
3 releases in 18m: 4.5.2, 4.5.3, 4.5.4
info · registry-verified · 2015-02-25 · 11y ago
BURST
2 releases in 53m: 4.7.0, 4.7.1
info · registry-verified · 2015-03-06 · 11y ago
BURST
3 releases in 40m: 4.7.10, 4.7.11, 4.7.12
info · registry-verified · 2015-03-13 · 11y ago
BURST
2 releases in 5m: 4.7.14, 4.7.15
info · registry-verified · 2015-03-18 · 11y ago
BURST
2 releases in 15m: 5.0.0, 5.0.1
info · registry-verified · 2015-04-02 · 11y ago
BURST
2 releases in 6m: 5.0.3, 5.0.4
info · registry-verified · 2015-04-03 · 11y ago
BURST
2 releases in 31m: 5.0.5, 5.0.6
info · registry-verified · 2015-04-03 · 11y ago
BURST
2 releases in 41m: 5.0.11, 5.0.12
info · registry-verified · 2015-04-08 · 11y ago
BURST
2 releases in 8m: 5.0.13, 5.1.0
info · registry-verified · 2015-04-13 · 11y ago
BURST
2 releases in 39m: 5.1.1, 5.1.2
info · registry-verified · 2015-04-13 · 11y ago
BURST
2 releases in 12m: 5.1.3, 5.1.4
info · registry-verified · 2015-04-13 · 11y ago
BURST
2 releases in 32m: 5.1.6, 5.1.7
info · registry-verified · 2015-04-13 · 11y ago
BURST
2 releases in 11m: 5.1.12, 5.1.13
info · registry-verified · 2015-04-25 · 11y ago
BURST
2 releases in 13m: 5.2.1, 5.2.2
info · registry-verified · 2015-04-30 · 11y ago
BURST
2 releases in 12m: 5.2.4, 5.2.5
info · registry-verified · 2015-05-01 · 11y ago
BURST
2 releases in 9m: 5.2.10, 5.2.11
info · registry-verified · 2015-05-04 · 11y ago
BURST
2 releases in 29m: 5.2.14, 5.2.15
info · registry-verified · 2015-05-05 · 11y ago
BURST
2 releases in 35m: 5.4.1, 5.4.2
info · registry-verified · 2015-05-15 · 11y ago
BURST
2 releases in 13m: 5.4.6, 5.4.7
info · registry-verified · 2015-05-21 · 11y ago
BURST
2 releases in 17m: 5.5.2, 5.5.3
info · registry-verified · 2015-06-05 · 11y ago
BURST
2 releases in 29m: 5.6.0, 5.6.1
info · registry-verified · 2015-06-20 · 11y ago
BURST
2 releases in 24m: 5.6.8, 5.6.9
info · registry-verified · 2015-06-25 · 11y ago
BURST
3 releases in 22m: 5.8.1, 5.8.2, 5.8.3
info · registry-verified · 2015-07-21 · 11y ago
BURST
2 releases in 28m: 5.8.4, 5.8.5
info · registry-verified · 2015-07-24 · 11y ago
BURST
2 releases in 16m: 5.8.6, 5.8.8
info · registry-verified · 2015-07-26 · 11y ago
BURST
2 releases in 18m: 5.8.31, 5.8.32
info · registry-verified · 2015-10-28 · 10y ago
BURST
3 releases in 15m: 6.0.0, 6.0.1, 6.0.2
info · registry-verified · 2015-10-29 · 10y ago
BURST
2 releases in 21m: 5.8.34, 6.1.5
info · registry-verified · 2015-11-12 · 10y ago
BURST
6 releases in 26m: 6.1.6, 6.1.7, 6.1.8, 6.1.9, 6.1.10, 6.1.11
info · registry-verified · 2015-11-12 · 10y ago
BURST
3 releases in 21m: 6.1.13, 6.1.14, 6.1.15
info · registry-verified · 2015-11-12 · 10y ago
BURST
4 releases in 45m: 6.1.16, 6.1.17, 6.1.18, 6.1.19
info · registry-verified · 2015-11-12 · 10y ago
BURST
2 releases in 14m: 6.18.1, 6.18.2
info · registry-verified · 2016-11-01 · 9y ago
release diff 6.26.2 → 6.26.3
+0 added · -0 removed · ~2 modified
lib/transformation/file/merge-map.js +58 lines
--- +++ @@ -35,7 +35,2 @@   var output = buildMappingData(map);--  if (output.sources.length !== 1) {-    throw new Error("Assertion failure - expected a single output file");-  }-  var defaultSource = output.sources[0]; @@ -62,59 +57,62 @@ -  var insertedMappings = new _map2.default();--  eachInputGeneratedRange(input, function (generated, original, source) {-    eachOverlappingGeneratedOutputRange(defaultSource, generated, function (item) {-      var key = makeMappingKey(item);-      if (insertedMappings.has(key)) return;-      insertedMappings.set(key, item);--      mergedGenerator.addMapping({-        source: source.path,-        original: {-          line: original.line,-          column: original.columnStart-        },-        generated: {-          line: item.line,-          column: item.columnStart-        },-        name: original.name+  if (output.sources.length === 1) {+    var defaultSource = output.sources[0];+    var insertedMappings = new _map2.default();++    eachInputGeneratedRange(input, function (generated, original, source) {+      eachOverlappingGeneratedOutputRange(defaultSource, generated, function (item) {+        var key = makeMappingKey(item);+        if (insertedMappings.has(key)) return;+        insertedMappings.set(key, item);++        mergedGenerator.addMapping({+          source: source.path,+          original: {+            line: original.line,+            column: original.columnStart+          },+          generated: {+            line: item.line,+            column: item.columnStart+          },+          name: original.name+        });       });     });-  });--  for (var _iterator2 = insertedMappings.values(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, _getIterator3.default)(_iterator2);;) {-    var _ref3;--    if (_isArray2) {-      if (_i2 >= _iterator2.length) break;-      _ref3 = _iterator2[_i2++];-    } else {-      _i2 = _iterator2.next();-      if (_i2.done) break;-      _ref3 = _i2.value;-    }--    var item = _ref3;--    if (item.columnEnd === Infinity) {-      continue;-    }--    var clearItem = {-      line: item.line,-      columnStart: item.columnEnd-    };--    var key = makeMappingKey(clearItem);-    if (insertedMappings.has(key)) {-      continue;-    }--    mergedGenerator.addMapping({-      generated: {-        line: clearItem.line,-        column: clearItem.columnStart-      }-    });++    for (var _iterator2 = insertedMappings.values(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, _getIterator3.default)(_iterator2);;) {+      var _ref3;++      if (_isArray2) {+        if (_i2 >= _iterator2.length) break;+        _ref3 = _iterator2[_i2++];+      } else {+        _i2 = _iterator2.next();+        if (_i2.done) break;+        _ref3 = _i2.value;+      }++      var item = _ref3;++      if (item.columnEnd === Infinity) {+        continue;+      }++      var clearItem = {+        line: item.line,+        columnStart: item.columnEnd+      };++      var key = makeMappingKey(clearItem);+      if (insertedMappings.has(key)) {+        continue;+      }++      mergedGenerator.addMapping({+        generated: {+          line: clearItem.line,+          column: clearItem.columnStart+        }+      });+    }   }
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "babel-core",-  "version": "6.26.2",+  "version": "6.26.3",   "description": "Babel compiler core.",
babel-eslint npm
10.1.0 6y ago incident on record
DELETIONBURST ×12
latest 10.1.0 versions 135 maintainers 6
8.2.1
8.2.2
8.2.3
8.2.4
8.2.5
8.2.6
9.0.0
10.0.0
10.0.1
10.0.2
10.0.3
10.1.0
DELETION
3.1.2 published then removed
high · registry-verified · 2015-05-14 · 11y ago
BURST
3 releases in 21m: 1.0.1, 1.0.2, 1.0.3
info · registry-verified · 2015-02-27 · 11y ago
BURST
3 releases in 18m: 1.0.7, 1.0.8, 1.0.9
info · registry-verified · 2015-02-28 · 11y ago
BURST
2 releases in 34m: 1.0.10, 1.0.11
info · registry-verified · 2015-02-28 · 11y ago
BURST
2 releases in 54m: 3.0.0, 3.0.1
info · registry-verified · 2015-04-14 · 11y ago
BURST
2 releases in 32m: 3.1.12, 3.1.13
info · registry-verified · 2015-06-05 · 11y ago
BURST
2 releases in 15m: 3.1.27, 4.0.0
info · registry-verified · 2015-07-25 · 11y ago
BURST
5 releases in 38m: 4.0.1, 4.0.2, 3.1.28, 4.0.3, 3.1.29
info · registry-verified · 2015-07-27 · 11y ago
BURST
3 releases in 16m: 4.0.4, 3.1.30, 4.0.5
info · registry-verified · 2015-07-27 · 11y ago
BURST
2 releases in 16m: 4.0.9, 4.0.10
info · registry-verified · 2015-08-17 · 11y ago
BURST
2 releases in 6m: 5.0.1, 6.0.0
info · registry-verified · 2016-03-26 · 10y ago
BURST
2 releases in 1m: 5.0.3, 6.0.1
info · registry-verified · 2016-03-31 · 10y ago
BURST
2 releases in 3m: 6.0.2, 5.0.4
info · registry-verified · 2016-03-31 · 10y ago
release diff 10.0.3 → 10.1.0
+0 added · -0 removed · ~3 modified
lib/analyze-scope.js +4 lines
--- +++ @@ -149,2 +149,6 @@     }+  }++  EnumDeclaration(node) {+    this._createScopeVariable(node, node.id);   }
lib/parse.js +1 lines
--- +++ @@ -21,3 +21,3 @@     plugins: [-      ["flow", { all: true }],+      ["flow", { all: true, enums: true }],       "jsx",
package.json +4 lines
--- +++ @@ -2,3 +2,3 @@   "name": "babel-eslint",-  "version": "10.0.3",+  "version": "10.1.0",   "description": "Custom parser for ESLint",@@ -14,5 +14,5 @@     "@babel/code-frame": "^7.0.0",-    "@babel/parser": "^7.0.0",-    "@babel/traverse": "^7.0.0",-    "@babel/types": "^7.0.0",+    "@babel/parser": "^7.7.0",+    "@babel/traverse": "^7.7.0",+    "@babel/types": "^7.7.0",     "eslint-visitor-keys": "^1.0.0",
chalk npm
6.0.0 26d ago incident on record
DELETIONBURST ×2
latest 6.0.0 versions 44 maintainers 1
5.1.0
5.1.1
5.1.2
5.2.0
5.3.0
5.4.0
5.4.1
5.5.0
5.6.0
5.6.1
5.6.2
6.0.0
DELETION
5.6.1 published then removed
high · registry-verified · 2025-09-08 · 11mo ago
BURST
2 releases in 45m: 1.1.2, 1.1.3
info · registry-verified · 2016-03-28 · 10y ago
BURST
2 releases in 52m: 2.2.2, 2.3.0
info · registry-verified · 2017-10-24 · 8y ago
release diff 5.6.2 → 6.0.0
+0 added · -0 removed · ~9 modified
source/vendor/ansi-styles/index.js +51 lines · 1 flagged
--- +++ @@ -1,8 +1,12 @@ const ANSI_BACKGROUND_OFFSET = 10;--const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;--const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;--const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;+const ANSI_UNDERLINE_OFFSET = 20;++const wrapAnsi16 = (offset = 0) => code => `\u{1B}[${code + offset}m`;++const wrapAnsi256 = (offset = 0) => code => `\u{1B}[${38 + offset};5;${code}m`;++const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u{1B}[${38 + offset};2;${red};${green};${blue}m`;++// `SGR 58` has no basic 16-color form, so the basic color code is mapped to its palette index instead.+const wrapUnderlineAnsi = code => `\u{1B}[58;5;${code < 90 ? code - 30 : code - 90 + 8}m`; @@ -16,2 +20,7 @@ 		underline: [4, 24],+		// Extended underline styles (`SGR 4:x` sub-parameters). Not in upstream `ansi-styles`.+		underlineDouble: ['4:2', 24],+		underlineCurly: ['4:3', 24],+		underlineDotted: ['4:4', 24],+		underlineDashed: ['4:5', 24], 		overline: [53, 55],@@ -65,2 +74,25 @@ 	},+	// Underline color (`SGR 58`/`59`). Not in upstream `ansi-styles`.+	underlineColor: {+		underlineBlack: ['58;5;0', 59],+		underlineRed: ['58;5;1', 59],+		underlineGreen: ['58;5;2', 59],+		underlineYellow: ['58;5;3', 59],+		underlineBlue: ['58;5;4', 59],+		underlineMagenta: ['58;5;5', 59],+		underlineCyan: ['58;5;6', 59],+		underlineWhite: ['58;5;7', 59],++		// Bright color+		underlineBlackBright: ['58;5;8', 59],+		underlineGray: ['58;5;8', 59], // Alias of `underlineBlackBright`+		underlineGrey: ['58;5;8', 59], // Alias of `underlineBlackBright`+		underlineRedBright: ['58;5;9', 59],+		underlineGreenBright: ['58;5;10', 59],+		underlineYellowBright: ['58;5;11', 59],+		underlineBlueBright: ['58;5;12', 59],+		underlineMagentaBright: ['58;5;13', 59],+		underlineCyanBright: ['58;5;14', 59],+		underlineWhiteBright: ['58;5;15', 59],+	}, };@@ -70,2 +102,3 @@ export const backgroundColorNames = Object.keys(styles.bgColor);+export const underlineColorNames = Object.keys(styles.underlineColor); export const colorNames = [...foregroundColorNames, ...backgroundColorNames];@@ -78,4 +111,4 @@ 			styles[styleName] = {-				open: `\u001B[${style[0]}m`,-				close: `\u001B[${style[1]}m`,+				open: `\u{1B}[${style[0]}m`,+				close: `\u{1B}[${style[1]}m`, 			};@@ -84,3 +117,4 @@ -			codes.set(style[0], style[1]);+			// Only the leading SGR parameter identifies a style, so `4:3` and `58;5;1` are keyed as `4` and `58`.+			codes.set(Number.parseInt(style[0], 10), style[1]); 		}@@ -98,4 +132,5 @@ -	styles.color.close = '\u001B[39m';-	styles.bgColor.close = '\u001B[49m';+	styles.color.close = '\u{1B}[39m';+	styles.bgColor.close = '\u{1B}[49m';+	styles.underlineColor.close = '\u{1B}[59m'; @@ -107,2 +142,5 @@ 	styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);+	styles.underlineColor.ansi = wrapUnderlineAnsi;+	styles.underlineColor.ansi256 = wrapAnsi256(ANSI_UNDERLINE_OFFSET);+	styles.underlineColor.ansi16m = wrapAnsi16m(ANSI_UNDERLINE_OFFSET); @@ -135,3 +173,3 @@ 			value(hex) {-				const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));+				const matches = /[\da-f]{6}|[\da-f]{3}/i.exec(hex.toString(16)); 				if (!matches) {@@ -149,3 +187,3 @@ 				return [-					/* eslint-disable no-bitwise */+					/* eslint-disable no-bitwise -- We need the speed */ 					(integer >> 16) & 0xFF,
package.json +33 lines
--- +++ @@ -2,3 +2,3 @@ 	"name": "chalk",-	"version": "5.6.2",+	"version": "6.0.0", 	"description": "Terminal string styling done right",@@ -8,4 +8,6 @@ 	"type": "module",-	"main": "./source/index.js",-	"exports": "./source/index.js",+	"exports": {+		"types": "./source/index.d.ts",+		"default": "./source/index.js"+	}, 	"imports": {@@ -17,9 +19,8 @@ 	},-	"types": "./source/index.d.ts", 	"sideEffects": false, 	"engines": {-		"node": "^12.17.0 || ^14.13 || >=16.0.0"+		"node": ">=22" 	}, 	"scripts": {-		"test": "xo && c8 ava && tsd",+		"test": "xo && c8 ava && tsc --noEmit --types node source/index.d.ts", 		"bench": "matcha benchmark.js"@@ -27,4 +28,3 @@ 	"files": [-		"source",-		"!source/index.test-d.ts"+		"source" 	],@@ -53,22 +53,31 @@ 	"devDependencies": {-		"@types/node": "^16.11.10",-		"ava": "^3.15.0",-		"c8": "^7.10.0",-		"color-convert": "^2.0.1",-		"execa": "^6.0.0",-		"log-update": "^5.0.0",+		"@types/node": "^26.1.1",+		"ansi-styles": "^6.2.3",+		"ava": "^8.0.1",+		"c8": "^12.0.0",+		"color-convert": "^3.1.3",+		"execa": "^10.0.0",+		"log-update": "^8.0.0", 		"matcha": "^0.7.0",-		"tsd": "^0.19.0",-		"xo": "^0.57.0",+		"typescript": "^6.0.3",+		"xo": "^4.0.0", 		"yoctodelay": "^2.0.0" 	},-	"xo": {-		"rules": {-			"unicorn/prefer-string-slice": "off",-			"@typescript-eslint/consistent-type-imports": "off",-			"@typescript-eslint/consistent-type-exports": "off",-			"@typescript-eslint/consistent-type-definitions": "off",-			"unicorn/expiring-todo-comments": "off"+	"xo": [+		{+			"ignores": [+				"source/vendor"+			]+		},+		{+			"rules": {+				"unicorn/prefer-string-slice": "off",+				"@typescript-eslint/consistent-type-imports": "off",+				"@typescript-eslint/consistent-type-exports": "off",+				"@typescript-eslint/consistent-type-definitions": "off",+				"unicorn/expiring-todo-comments": "off",+				"no-warning-comments": "off"+			} 		}-	},+	], 	"c8": {
source/index.d.ts +126 lines
--- +++ @@ -1,2 +1,2 @@-// TODO: Make it this when TS suports that.+// TODO: Make it this when TS supports that. // import {ModifierName, ForegroundColor, BackgroundColor, ColorName} from '#ansi-styles';@@ -22,4 +22,8 @@ 	- `3` - Truecolor 16 million colors support.-	*/-	readonly level?: ColorSupportLevel;++	Omit this option, or pass `undefined`, to have the level detected instead.++	@throws If the value is neither `undefined` nor an integer from 0 to 3.+	*/+	readonly level?: ColorSupportLevel | undefined; }@@ -44,2 +48,4 @@ 	- `3` - Truecolor 16 million colors support.++	@throws If the assigned value is not an integer from 0 to 3. 	*/@@ -76,2 +82,4 @@ +	The value is downsampled to the 16-color palette on terminals that only support basic colors (level 1), so `chalk.ansi256(196)` becomes 91 (ANSI escape for bright red).+ 	@example@@ -112,3 +120,5 @@ 	/**-	Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.+	Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.++	The value is downsampled to the 16-color palette on terminals that only support basic colors (level 1), so `chalk.bgAnsi256(196)` becomes 101 (ANSI escape for bright red background). @@ -124,2 +134,48 @@ 	/**+	Use RGB values to set underline color.++	The underline color is only visible when an underline style is also applied.++	@example+	```+	import chalk from 'chalk';++	chalk.underlineRgb(222, 173, 237).underlineCurly('Hello, world!');+	```+	*/+	underlineRgb: (red: number, green: number, blue: number) => this;++	/**+	Use HEX value to set underline color.++	The underline color is only visible when an underline style is also applied.++	@param color - Hexadecimal value representing the desired color.++	@example+	```+	import chalk from 'chalk';++	chalk.underlineHex('#DEADED').underlineCurly('Hello, world!');+	```+	*/+	underlineHex: (color: string) => this;++	/**+	Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set underline color.++	The underline color is only visible when an underline style is also applied.++	The value is downsampled to the first 16 palette entries on terminals that only support basic colors (level 1), so `chalk.underlineAnsi256(196)` becomes 9 (the palette index for bright red).++	@example+	```+	import chalk from 'chalk';++	chalk.underlineAnsi256(201).underlineCurly('Hello, world!');+	```+	*/+	underlineAnsi256: (index: number) => this;++	/** 	Modifier: Reset the current style.@@ -147,2 +203,22 @@ 	readonly underline: this;++	/**+	Modifier: Put a double horizontal line below the text. *(Not widely supported)*+	*/+	readonly underlineDouble: this;++	/**+	Modifier: Put a curly horizontal line below the text. *(Not widely supported)*+	*/+	readonly underlineCurly: this;++	/**+	Modifier: Put a dotted horizontal line below the text. *(Not widely supported)*+	*/+	readonly underlineDotted: this;++	/**+	Modifier: Put a dashed horizontal line below the text. *(Not widely supported)*+	*/+	readonly underlineDashed: this; @@ -184,3 +260,3 @@ -	/*+	/** 	Alias for `blackBright`.@@ -189,3 +265,3 @@ -	/*+	/** 	Alias for `blackBright`.@@ -212,3 +288,3 @@ -	/*+	/** 	Alias for `bgBlackBright`.@@ -217,3 +293,3 @@ -	/*+	/** 	Alias for `bgBlackBright`.@@ -230,2 +306,30 @@ 	readonly bgWhiteBright: this;++	readonly underlineBlack: this;+	readonly underlineRed: this;+	readonly underlineGreen: this;+	readonly underlineYellow: this;+	readonly underlineBlue: this;+	readonly underlineMagenta: this;+	readonly underlineCyan: this;+	readonly underlineWhite: this;++	/**+	Alias for `underlineBlackBright`.+	*/+	readonly underlineGray: this;++	/**+	Alias for `underlineBlackBright`.+	*/+	readonly underlineGrey: this;++	readonly underlineBlackBright: this;+	readonly underlineRedBright: this;+	readonly underlineGreenBright: this;+	readonly underlineYellowBright: this;+	readonly underlineBlueBright: this;+	readonly underlineMagentaBright: this;+	readonly underlineCyanBright: this;+	readonly underlineWhiteBright: this; }@@ -249,4 +353,12 @@ export {-	ModifierName, ForegroundColorName, BackgroundColorName, ColorName,-	modifierNames, foregroundColorNames, backgroundColorNames, colorNames,+	ModifierName,+	ForegroundColorName,+	BackgroundColorName,+	UnderlineColorName,+	ColorName,+	modifierNames,+	foregroundColorNames,+	backgroundColorNames,+	underlineColorNames,+	colorNames, // } from '#ansi-styles';@@ -301,3 +413,3 @@ */-export const modifiers: readonly Modifiers[];+export const modifiers: readonly ModifierName[]; @@ -308,3 +420,3 @@ */-export const foregroundColors: readonly ForegroundColor[];+export const foregroundColors: readonly ForegroundColorName[]; @@ -315,3 +427,3 @@ */-export const backgroundColors: readonly BackgroundColor[];+export const backgroundColors: readonly BackgroundColorName[]; @@ -322,3 +434,3 @@ */-export const colors: readonly Color[];+export const colors: readonly ColorName[]; 
source/index.js +106 lines
--- +++ @@ -1,4 +1,2 @@-import ansiStyles from '#ansi-styles';-import supportsColor from '#supports-color';-import { // eslint-disable-line import/order+import { 	stringReplaceAll,@@ -6,2 +4,4 @@ } from './utilities.js';+import ansiStyles from '#ansi-styles';+import supportsColor from '#supports-color'; @@ -12,10 +12,3 @@ const IS_EMPTY = Symbol('IS_EMPTY');--// `supportsColor.level` → `ansiStyles.color[name]` mapping-const levelMapping = [-	'ansi',-	'ansi',-	'ansi256',-	'ansi16m',-];+const LEVEL = Symbol('LEVEL'); @@ -23,10 +16,28 @@ +const assertValidLevel = level => {+	if (!Number.isSafeInteger(level) || level < 0 || level > 3) {+		throw new Error('The `level` should be an integer from 0 to 3');+	}+};++// The level is stored under a symbol so the hot path can read it as a plain property, while `level` itself is an accessor that rejects values the rest of the code could not handle.+const levelDescriptor = {+	enumerable: true,+	get() {+		return this[LEVEL];+	},+	set(level) {+		assertValidLevel(level);+		this[LEVEL] = level;+	},+};+ const applyOptions = (object, options = {}) => {-	if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {-		throw new Error('The `level` option should be an integer from 0 to 3');-	}--	// Detect level if not set manually+	if (options.level !== undefined) {+		assertValidLevel(options.level);+	}++	// Detect level if not set manually. Written under the symbol rather than through `level`, as the prototype carrying that accessor is not installed until after this runs. 	const colorLevel = stdoutColor ? stdoutColor.level : 0;-	object.level = options.level === undefined ? colorLevel : options.level;+	object[LEVEL] = options.level === undefined ? colorLevel : options.level; };@@ -53,2 +64,3 @@ +// eslint-disable-next-line unicorn/no-top-level-side-effects -- The prototype chain must be set up at module load. Object.setPrototypeOf(createChalk.prototype, Function.prototype);@@ -73,13 +85,10 @@ -const getModelAnsi = (model, level, type, ...arguments_) => {+// Resolve a color model to one converter per `level`, so that a call only has to look up the converter for the current level instead of re-deciding the model and level every time.+const createModelConverters = (model, type) => {+	const style = ansiStyles[type];+ 	if (model === 'rgb') {-		if (level === 'ansi16m') {-			return ansiStyles[type].ansi16m(...arguments_);-		}--		if (level === 'ansi256') {-			return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));-		}--		return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));+		const ansi = (red, green, blue) => style.ansi(ansiStyles.rgbToAnsi(red, green, blue));+		const ansi256 = (red, green, blue) => style.ansi256(ansiStyles.rgbToAnsi256(red, green, blue));+		return [ansi, ansi, ansi256, style.ansi16m]; 	}@@ -87,6 +96,10 @@ 	if (model === 'hex') {-		return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));-	}--	return ansiStyles[type][model](...arguments_);+		const ansi = hex => style.ansi(ansiStyles.hexToAnsi(hex));+		const ansi256 = hex => style.ansi256(ansiStyles.hexToAnsi256(hex));+		return [ansi, ansi, ansi256, hex => style.ansi16m(...ansiStyles.hexToRgb(hex))];+	}++	// `ansi256` is already the native form, so only the 16-color levels need converting.+	const ansi = code => style.ansi(ansiStyles.ansi256ToAnsi(code));+	return [ansi, ansi, style.ansi256, style.ansi256]; };@@ -96,36 +109,43 @@ for (const model of usedModels) {-	styles[model] = {-		get() {-			const {level} = this;-			return function (...arguments_) {-				const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);-				return createBuilder(this, styler, this[IS_EMPTY]);-			};+	const capitalizedModel = model[0].toUpperCase() + model.slice(1);++	for (const [styleName, type] of [+		[model, 'color'],+		['bg' + capitalizedModel, 'bgColor'],+		['underline' + capitalizedModel, 'underlineColor'],+	]) {+		const {close} = ansiStyles[type];+		const converters = createModelConverters(model, type);++		styles[styleName] = {+			get() {+				// The level is read on call rather than captured here so the function can be cached on the instance instead of being reallocated on every property access.+				// `rgb` is the widest model, so naming the three parameters avoids a rest array.+				const styleFunction = function (first, second, third) {+					const open = converters[this.level](first, second, third);+					return createBuilder(this, createStyler(open, close, this[STYLER]), this[IS_EMPTY]);+				};++				Object.defineProperty(this, styleName, {value: styleFunction});+				return styleFunction;+			},+		};+	}+}++const proto = Object.defineProperties(+	() => {},+	{+		...styles,+		level: {+			enumerable: true,+			get() {+				return this[GENERATOR].level;+			},+			set(level) {+				this[GENERATOR].level = level;+			}, 		},-	};--	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);-	styles[bgModel] = {-		get() {-			const {level} = this;-			return function (...arguments_) {-				const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);-				return createBuilder(this, styler, this[IS_EMPTY]);-			};-		},-	};-}--const proto = Object.defineProperties(() => {}, {-	...styles,-	level: {-		enumerable: true,-		get() {-			return this[GENERATOR].level;-		},-		set(level) {-			this[GENERATOR].level = level;-		},-	},-});+	},+); @@ -153,4 +173,14 @@ 	// Single argument is hot path, implicit coercion is faster than anything-	// eslint-disable-next-line no-implicit-coercion-	const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));+	const builder = (...arguments_) => {+		if (arguments_.length === 1) {+			// eslint-disable-next-line no-implicit-coercion+			return applyStyle(builder, '' + arguments_[0]);+		}++		if (arguments_.length === 2) {+			return applyStyle(builder, arguments_[0] + ' ' + arguments_[1]);+		}++		return applyStyle(builder, arguments_.join(' '));+	}; @@ -160,3 +190,4 @@ -	builder[GENERATOR] = self;+	// Point every builder at the root generator instead of its immediate parent, so reading the level costs one property load rather than walking a `level` getter per link of the chain.+	builder[GENERATOR] = self[GENERATOR] ?? self; 	builder[STYLER] = _styler;@@ -168,3 +199,5 @@ const applyStyle = (self, string) => {-	if (self.level <= 0 || !string) {+	// Read the level directly off the generator to skip the `level` getter dispatch on this hot path+	if (self[GENERATOR][LEVEL] <= 0 || !string) {+		// eslint-disable-next-line unicorn/no-computed-property-existence-check -- Reads the boolean value, not a property existence check. 		return self[IS_EMPTY] ? '' : string;@@ -179,3 +212,3 @@ 	const {openAll, closeAll} = styler;-	if (string.includes('\u001B')) {+	if (string.includes('\u{1B}')) { 		while (styler !== undefined) {@@ -201,3 +234,5 @@ -Object.defineProperties(createChalk.prototype, styles);+// `level` lives on the prototype rather than on each instance, so it costs nothing to construct an instance and matches how builders already expose it. It is inherited rather than own, so it does not show up in `Object.keys()`, same as for a builder.+// eslint-disable-next-line unicorn/no-top-level-side-effects -- The style getters must be installed at module load.+Object.defineProperties(createChalk.prototype, {...styles, level: levelDescriptor}); @@ -210,2 +245,3 @@ 	backgroundColorNames,+	underlineColorNames, 	colorNames,
source/utilities.js +5 lines
--- +++ @@ -1,3 +1,3 @@-// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.-export function stringReplaceAll(string, substring, replacer) {+// Note: Each match is kept and `postfix` is inserted after it. `String#replaceAll(substring, substring + postfix)` does the same, but it has to scan the replacement for `$` patterns and it is several times slower on the no-match path that most calls take.+export function stringReplaceAll(string, substring, postfix) { 	let index = string.indexOf(substring);@@ -11,3 +11,3 @@ 	do {-		returnValue += string.slice(endIndex, index) + substring + replacer;+		returnValue += string.slice(endIndex, index) + substring + postfix; 		endIndex = index + substringLength;@@ -24,4 +24,4 @@ 	do {-		const gotCR = string[index - 1] === '\r';-		returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;+		const isGotCR = string[index - 1] === '\r';+		returnValue += string.slice(endIndex, (isGotCR ? index - 1 : index)) + prefix + (isGotCR ? '\r\n' : '\n') + postfix; 		endIndex = index + 1;
source/vendor/ansi-styles/index.d.ts +84 lines
--- +++ @@ -1,2 +1,2 @@-export interface CSPair { // eslint-disable-line @typescript-eslint/naming-convention+export type CSPair = { // eslint-disable-line @typescript-eslint/naming-convention 	/**@@ -10,5 +10,5 @@ 	readonly close: string;-}--export interface ColorBase {+};++export type ColorBase = { 	/**@@ -23,5 +23,5 @@ 	ansi16m(red: number, green: number, blue: number): string;-}--export interface Modifier {+};++export type Modifier = { 	/**@@ -47,3 +47,3 @@ 	/**-	Make text underline. (Not widely supported)+	Put a horizontal line below the text. (Not widely supported) 	*/@@ -52,3 +52,23 @@ 	/**-	Make text overline.+	Put a double horizontal line below the text. (Not widely supported)+	*/+	readonly underlineDouble: CSPair;++	/**+	Put a curly horizontal line below the text. (Not widely supported)+	*/+	readonly underlineCurly: CSPair;++	/**+	Put a dotted horizontal line below the text. (Not widely supported)+	*/+	readonly underlineDotted: CSPair;++	/**+	Put a dashed horizontal line below the text. (Not widely supported)+	*/+	readonly underlineDashed: CSPair;++	/**+	Put a horizontal line above the text. @@ -72,5 +92,5 @@ 	readonly strikethrough: CSPair;-}--export interface ForegroundColor {+};++export type ForegroundColor = { 	readonly black: CSPair;@@ -102,5 +122,5 @@ 	readonly whiteBright: CSPair;-}--export interface BackgroundColor {+};++export type BackgroundColor = { 	readonly bgBlack: CSPair;@@ -132,5 +152,35 @@ 	readonly bgWhiteBright: CSPair;-}--export interface ConvertColor {+};++export type UnderlineColor = {+	readonly underlineBlack: CSPair;+	readonly underlineRed: CSPair;+	readonly underlineGreen: CSPair;+	readonly underlineYellow: CSPair;+	readonly underlineBlue: CSPair;+	readonly underlineCyan: CSPair;+	readonly underlineMagenta: CSPair;+	readonly underlineWhite: CSPair;++	/**+	Alias for `underlineBlackBright`.+	*/+	readonly underlineGray: CSPair;++	/**+	Alias for `underlineBlackBright`.+	*/+	readonly underlineGrey: CSPair;++	readonly underlineBlackBright: CSPair;+	readonly underlineRedBright: CSPair;+	readonly underlineGreenBright: CSPair;+	readonly underlineYellowBright: CSPair;+	readonly underlineBlueBright: CSPair;+	readonly underlineCyanBright: CSPair;+	readonly underlineMagentaBright: CSPair;+	readonly underlineWhiteBright: CSPair;+};++export type ConvertColor = { 	/**@@ -180,3 +230,3 @@ 	hexToAnsi(hex: string): number;-}+}; @@ -202,2 +252,9 @@ /**+Basic underline color names.++[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)+*/+export type UnderlineColorName = keyof UnderlineColor;++/** Basic color names. The combination of foreground and background color names.@@ -223,3 +280,8 @@ -/*+/**+Basic underline color names.+*/+export const underlineColorNames: readonly UnderlineColorName[];++/** Basic color names. The combination of foreground and background color names.@@ -232,4 +294,5 @@ 	readonly bgColor: ColorBase & BackgroundColor;+	readonly underlineColor: ColorBase & UnderlineColor; 	readonly codes: ReadonlyMap<number, number>;-} & ForegroundColor & BackgroundColor & Modifier & ConvertColor;+} & ForegroundColor & BackgroundColor & UnderlineColor & Modifier & ConvertColor; 
source/vendor/supports-color/browser.js +3 lines
--- +++ @@ -1,3 +1 @@-/* eslint-env browser */- const level = (() => {@@ -8,4 +6,4 @@ 	if (globalThis.navigator.userAgentData) {-		const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium');-		if (brand && brand.version > 93) {+		const brand = globalThis.navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium');+		if (brand?.version > 93) { 			return 3;@@ -14,3 +12,3 @@ -	if (/\b(Chrome|Chromium)\//.test(globalThis.navigator.userAgent)) {+	if (/\b(?:Chrome|Chromium)\//.test(globalThis.navigator.userAgent)) { 		return 1;
source/vendor/supports-color/index.js +30 lines
--- +++ @@ -32,14 +32,25 @@ +// Whether `FORCE_COLOR` names a level. Shared with the exact-level check below so that the two cannot disagree on what counts as numeric.+function hasNumericForceColor() {+	return /^\d+$/.test(env.FORCE_COLOR);+}+ function envForceColor() {-	if ('FORCE_COLOR' in env) {-		if (env.FORCE_COLOR === 'true') {-			return 1;-		}--		if (env.FORCE_COLOR === 'false') {-			return 0;-		}--		return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);-	}+	if (!('FORCE_COLOR' in env)) {+		return;+	}++	if (env.FORCE_COLOR === 'false') {+		return 0;+	}++	if (env.FORCE_COLOR === 'true' || env.FORCE_COLOR.length === 0) {+		return 1;+	}++	if (!hasNumericForceColor()) {+		return;+	}++	return Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); }@@ -81,2 +92,7 @@ 		}+	}++	// A numeric `FORCE_COLOR` requests an exact level, while `FORCE_COLOR=true` and `FORCE_COLOR=` only enable color and let the level be detected.+	if (forceColor !== undefined && hasNumericForceColor()) {+		return forceColor; 	}@@ -126,3 +142,3 @@ 	if ('TEAMCITY_VERSION' in env) {-		return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;+		return /^(?:9\.0*[1-9]\d*\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; 	}@@ -146,3 +162,3 @@ 	if ('TERM_PROGRAM' in env) {-		const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);+		const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.', 1)[0], 10); @@ -160,3 +176,3 @@ -	if (/-256(color)?$/i.test(env.TERM)) {+	if (/-256(?:color)?$/i.test(env.TERM)) { 		return 2;
@ctrl/tinycolor npm
4.2.0 11mo ago incident on record
DELETION ×2BURST ×3
latest 4.2.0 versions 49 maintainers 1
3.5.1
3.6.0
3.6.1
4.0.0
4.0.1
4.0.2
4.0.3
4.0.4
4.1.0
4.1.1
4.1.2
4.2.0
DELETION
4.1.1 published then removed
high · registry-verified · 2025-09-15 · 11mo ago
DELETION
4.1.2 published then removed
high · registry-verified · 2025-09-15 · 11mo ago
BURST
3 releases in 29m: 3.0.0, 3.0.1, 3.0.2
info · registry-verified · 2020-04-22 · 6y ago
BURST
2 releases in 50m: 3.6.1, 4.0.0
info · registry-verified · 2023-08-23 · 2y ago
BURST
2 releases in 21m: 4.1.1, 4.1.2
info · registry-verified · 2025-09-15 · 11mo ago
release diff 4.1.0 → 4.2.0
+0 added · -0 removed · ~2 modified
package.json +3 lines
--- +++ @@ -2,3 +2,3 @@   "name": "@ctrl/tinycolor",-  "version": "4.1.0",+  "version": "4.2.0",   "description": "Fast, small color manipulation and conversion for JavaScript",@@ -6,3 +6,4 @@   "publishConfig": {-    "access": "public"+    "access": "public",+    "provenance": true   },
eslint npm
10.9.0 19h ago incident on record
critical-tier DELETIONBURST ×5
latest 10.9.0 versions 427 maintainers 2 critical-tier (snapshotted)
10.2.0
10.2.1
10.3.0
10.4.0
10.4.1
10.5.0
10.6.0
9.39.5
10.7.0
10.8.0
10.8.1
10.9.0
DELETION
0.7.0 published then removed
high · registry-verified · 2014-05-23 · 12y ago
BURST
2 releases in 10m: 0.6.0, 0.6.1
info · registry-verified · 2014-05-17 · 12y ago
BURST
2 releases in 4m: 0.7.0, 0.6.2
info · registry-verified · 2014-05-23 · 12y ago
BURST
2 releases in 36m: 2.5.2, 2.5.3
info · registry-verified · 2016-03-28 · 10y ago
BURST
2 releases in 41m: 3.2.1, 3.2.2
info · registry-verified · 2016-08-01 · 10y ago
BURST
2 releases in 41m: 9.39.5, 10.7.0 · ACTIVE
info · registry-verified · 2026-07-10 · 1mo ago
release diff 10.8.1 → 10.9.0
+0 added · -0 removed · ~13 modified
lib/config/config-loader.js +2 lines
--- +++ @@ -318,3 +318,3 @@ 	 * as override config file is not explicitly set to `false`, it will search-	 * upwards from `fromDirectory` for a file named `eslint.config.js`.+	 * upwards from `fromDirectory` for an `eslint.config.*` file. 	 * @param {string} fromDirectory The directory from which to start searching.@@ -516,3 +516,3 @@ 	 * as override config file is not explicitly set to `false`, it will search-	 * upwards from `fromDirectory` for a file named `eslint.config.js`.+	 * upwards from `fromDirectory` for an `eslint.config.*` file. 	 * This method is exposed internally for testing purposes.
lib/eslint/eslint.js +1 lines
--- +++ @@ -232,3 +232,3 @@  * as override config file is not explicitly set to `false`, it will search- * upwards from the cwd for a file named `eslint.config.js`.+ * upwards from the cwd for an `eslint.config.*` file.  *
lib/options.js +2 lines
--- +++ @@ -92,3 +92,3 @@ 				default: "true",-				description: "Disable look up for eslint.config.js",+				description: "Disable look up for eslint.config.*", 			},@@ -99,3 +99,3 @@ 				description:-					"Use this configuration instead of eslint.config.js, eslint.config.mjs, or eslint.config.cjs",+					"Use this configuration instead of eslint.config.* look up", 			},
lib/rules/no-loss-of-precision.js +6 lines
--- +++ @@ -185,2 +185,7 @@ 	);++	if (node.value === 0) {+		return !/^0+$/u.test(normalizedRawNumber.coefficient);+	}+ 	const requestedPrecision = normalizedRawNumber.coefficient.length;@@ -238,3 +243,3 @@ 			Literal(node) {-				if (node.value && isNumber(node) && losesPrecision(node)) {+				if (isNumber(node) && losesPrecision(node)) { 					context.report({
lib/rules/no-unmodified-loop-condition.js +21 lines
--- +++ @@ -28,3 +28,2 @@ const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/u; // for-in/of statements don't have `test` property.-const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/u; const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/u;@@ -192,3 +191,15 @@ -		schema: [],+		schema: [+			{+				type: "object",+				properties: {+					checkConditionalExpressions: {+						type: "boolean",+					},+				},+				additionalProperties: false,+			},+		],++		defaultOptions: [{ checkConditionalExpressions: false }], @@ -201,2 +212,3 @@ 	create(context) {+		const [{ checkConditionalExpressions }] = context.options; 		const sourceCode = context.sourceCode;@@ -307,6 +319,10 @@ 				/*-				 * If it's inside of a group, OK if either operand is modified.-				 * So stores the group this reference belongs to.+				 * If it's inside of a group, OK if any reference in that group is+				 * modified. So stores the group this reference belongs to. 				 */-				if (GROUP_PATTERN.test(node.type)) {+				if (+					node.type === "BinaryExpression" ||+					(!checkConditionalExpressions &&+						node.type === "ConditionalExpression")+				) { 					// If this expression is dynamic, no need to check.
lib/rules/no-useless-escape.js +2 lines
--- +++ @@ -375,4 +375,4 @@ 				/*-				 * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/.-				 * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25.+				 * JSXAttribute doesn't have any escape sequence: https://react.github.io/jsx/.+				 * In addition, backticks are not supported by JSX yet: https://github.com/react/jsx/issues/25. 				 */
lib/rules/no-var.js +87 lines
--- +++ @@ -223,2 +223,76 @@ +/**+ * Checks whether a given variable is referenced inside a hoisted function+ * declaration that is called before the variable's declaration.+ * @param {Variable} variable The variable to check.+ * @returns {boolean} `true` if the variable is referenced from a hoisted+ *      function called before its declaration.+ */+function hasUnsafeHoistedFunctionReference(variable) {+	const declarationNode = variable.defs[0].node;+	const declarationStart = declarationNode.range[0];++	for (const reference of variable.references) {+		if (reference.init) {+			continue;+		}++		if (reference.identifier.range[0] < declarationStart) {+			continue;+		}++		let currentScope = reference.from.variableScope;++		while (currentScope !== variable.scope) {+			if (+				currentScope.block.type === "FunctionDeclaration" &&+				currentScope.block.id+			) {+				const funcName = currentScope.block.id.name;+				const funcVariable = currentScope.upper.set.get(funcName);++				for (const funcRef of funcVariable.references) {+					const refId = funcRef.identifier;++					if (+						refId.parent.type === "CallExpression" &&+						refId.parent.callee === refId &&+						refId.range[0] < declarationStart+					) {+						return true;+					}+				}+			}++			currentScope = currentScope.upper.variableScope;+		}+	}++	return false;+}++/**+ * Checks whether a given variable is shadowed by the parameter of an enclosing+ * `catch` clause.+ *+ * Scope analysis does not report this as a redeclaration, because the catch+ * parameter and the `var` are distinct variables living in distinct scopes, so+ * neither one has more than one definition.+ *+ * Resolving the name from the scope of the declaration is enough to detect it.+ * A simple catch parameter is the only binding a `var` is allowed to shadow:+ * any other block-scoped declaration of the same name makes the `var` itself a+ * syntax error, and a function parameter shares its variable with the `var`, so+ * that case is reported by `isRedeclared` instead.+ * @param {ASTNode} node A `VariableDeclaration` node to check.+ * @param {SourceCode} sourceCode The source code object.+ * @returns {Function} The predicate function which checks whether a given+ *      variable is shadowed by a `catch` clause parameter.+ */+function isShadowedByCatchParameter(node, sourceCode) {+	return variable =>+		astUtils.getVariableByName(sourceCode.getScope(node), variable.name) !==+		variable;+}+ //------------------------------------------------------------------------------@@ -278,2 +352,3 @@ 		 * - A variable has name that is disallowed for `let` declarations.+		 * - A variable is shadowed by a `catch` clause parameter. 		 *@@ -314,2 +389,11 @@ 		 * initializer.+		 *+		 * ## A variable is shadowed by a `catch` clause parameter.+		 *+		 * A `var` declaration may reuse the name of a simple catch clause+		 * parameter, but the equivalent `let` declaration may not. Directly+		 * inside the catch block, `let` would be a syntax error. In a nested+		 * block, `let` is valid but changes behavior: the `var` assigns to the+		 * catch parameter, while the `let` introduces a separate binding and+		 * leaves the catch parameter untouched. 		 * @param {ASTNode} node A variable declaration node to check.@@ -332,3 +416,5 @@ 				variables.some(hasNameDisallowedForLetDeclarations) ||-				variables.some(hasReferenceBeforeDeclaration)+				variables.some(hasReferenceBeforeDeclaration) ||+				variables.some(hasUnsafeHoistedFunctionReference) ||+				variables.some(isShadowedByCatchParameter(node, sourceCode)) 			) {
lib/rules/prefer-template.js +7 lines
--- +++ @@ -301,5 +301,11 @@ +			const prefix =+				astUtils.isStartOfExpressionStatement(topBinaryExpr) &&+				astUtils.needsPrecedingSemicolon(sourceCode, topBinaryExpr)+					? ";"+					: "";+ 			return fixer.replaceText( 				topBinaryExpr,-				getTemplateLiteral(topBinaryExpr, null, null),+				`${prefix}${getTemplateLiteral(topBinaryExpr, null, null)}`, 			);
lib/types/index.d.ts +1 lines
--- +++ @@ -970,3 +970,3 @@ 					/**-					 * Enable [JSX](https://facebook.github.io/jsx/).+					 * Enable [JSX](https://react.github.io/jsx/). 					 *
lib/types/rules.d.ts +10 lines
--- +++ @@ -4042,3 +4042,12 @@ 	 */-	"no-unmodified-loop-condition": Linter.RuleEntry<[]>;+	"no-unmodified-loop-condition": Linter.RuleEntry<+		[+			Partial<{+				/**+				 * @default false+				 */+				checkConditionalExpressions: boolean;+			}>,+		]+	>; 
messages/config-file-missing.js +2 lines
--- +++ @@ -4,5 +4,5 @@ 	return `-ESLint couldn't find an eslint.config.(js|mjs|cjs) file.+ESLint couldn't find an eslint.config.* file. -From ESLint v9.0.0, the default configuration file is now eslint.config.js.+From ESLint v9.0.0, the default configuration file is now eslint.config.*. If you are using a .eslintrc.* file, please follow the migration guide
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "eslint",-  "version": "10.8.1",+  "version": "10.9.0",   "author": "Nicholas C. Zakas <[email protected]>",
eslint-config-prettier npm
10.1.8 1y ago incident on record
DELETION ×4BURST ×7
latest 10.1.8 versions 85 maintainers 3
10.1.1
10.1.2
10.1.3
10.1.4
10.1.5
9.1.1
8.10.1
10.1.6
10.1.7
10.1.8
8.10.2
9.1.2
DELETION
9.1.1 published then removed
high · registry-verified · 2025-07-18 · 1y ago
DELETION
8.10.1 published then removed
high · registry-verified · 2025-07-18 · 1y ago
DELETION
10.1.6 published then removed
high · registry-verified · 2025-07-18 · 1y ago
DELETION
10.1.7 published then removed
high · registry-verified · 2025-07-18 · 1y ago
BURST
2 releases in 5m: 1.0.0, 1.0.1
info · registry-verified · 2017-01-29 · 9y ago
BURST
2 releases in 28m: 3.0.0, 3.0.1
info · registry-verified · 2018-08-13 · 8y ago
BURST
2 releases in 2m: 10.0.0, 10.0.1
info · registry-verified · 2025-01-13 · 1y ago
BURST
2 releases in 22m: 10.0.3, 10.1.0
info · registry-verified · 2025-03-07 · 1y ago
BURST
2 releases in 24m: 10.1.4, 10.1.5
info · registry-verified · 2025-05-09 · 1y ago
BURST
4 releases in 22m: 9.1.1, 8.10.1, 10.1.6, 10.1.7
info · registry-verified · 2025-07-18 · 1y ago
BURST
3 releases in 39m: 10.1.8, 8.10.2, 9.1.2
info · registry-verified · 2025-07-18 · 1y ago
release diff 8.10.2 → 9.1.2
+0 added · -0 removed · ~4 modified
bin/cli.js +36 lines · 1 flagged
--- +++ @@ -10,5 +10,17 @@ // with no local eslint-config-prettier installation.-const { ESLint } = require(require.resolve("eslint", {-  paths: [process.cwd(), ...require.resolve.paths("eslint")],-}));+const localRequire = (request) =>+  require(+    require.resolve(request, {+      paths: [process.cwd(), ...require.resolve.paths("eslint")],+    })+  );++let experimentalApi = {};+try {+  experimentalApi = localRequire("eslint/use-at-your-own-risk");+  // eslint-disable-next-line unicorn/prefer-optional-catch-binding+} catch (_error) {}++const { ESLint, FlatESLint = experimentalApi.FlatESLint } =+  localRequire("eslint"); @@ -29,4 +41,23 @@   const eslint = new ESLint();--  Promise.all(args.map((file) => eslint.calculateConfigForFile(file)))+  const flatESLint = FlatESLint === undefined ? undefined : new FlatESLint();++  Promise.all(+    args.map((file) => {+      switch (process.env.ESLINT_USE_FLAT_CONFIG) {+        case "true": {+          return flatESLint.calculateConfigForFile(file);+        }+        case "false": {+          return eslint.calculateConfigForFile(file);+        }+        default: {+          // This turns synchronous errors (such as `.calculateConfigForFile` not existing)+          // and turns them into promise rejections.+          return Promise.resolve()+            .then(() => flatESLint.calculateConfigForFile(file))+            .catch(() => eslint.calculateConfigForFile(file));+        }+      }+    })+  )     .then((configs) => {
bin/validators.js +23 lines
--- +++ @@ -50,2 +50,25 @@ +  "unicorn/template-indent"({ options }) {+    if (options.length === 0) {+      return false;+    }++    const { comments = [], tags = [] } = options[0] || {};++    return (+      Array.isArray(comments) &&+      Array.isArray(tags) &&+      !(+        comments.includes("GraphQL") ||+        comments.includes("HTML") ||+        tags.includes("css") ||+        tags.includes("graphql") ||+        tags.includes("gql") ||+        tags.includes("html") ||+        tags.includes("markdown") ||+        tags.includes("md")+      )+    );+  },+   "vue/html-self-closing"({ options }) {
index.js +105 lines
--- +++ @@ -3,2 +3,4 @@ const includeDeprecated = !process.env.ESLINT_CONFIG_PRETTIER_NO_DEPRECATED;++const specialRule = 0; @@ -7,78 +9,15 @@     // The following rules can be used in some cases. See the README for more-    // information. (These are marked with `0` instead of `"off"` so that a-    // script can distinguish them.)-    "curly": 0,-    "lines-around-comment": 0,-    "max-len": 0,-    "no-confusing-arrow": 0,-    "no-mixed-operators": 0,-    "no-tabs": 0,-    "no-unexpected-multiline": 0,-    "quotes": 0,-    "@typescript-eslint/lines-around-comment": 0,-    "@typescript-eslint/quotes": 0,-    "babel/quotes": 0,-    "vue/html-self-closing": 0,-    "vue/max-len": 0,+    // information. These are marked with `0` instead of `"off"` so that a+    // script can distinguish them. Note that there are a few more of these+    // in the deprecated section below.+    "curly": specialRule,+    "no-unexpected-multiline": specialRule,+    "@typescript-eslint/lines-around-comment": specialRule,+    "@typescript-eslint/quotes": specialRule,+    "babel/quotes": specialRule,+    "unicorn/template-indent": specialRule,+    "vue/html-self-closing": specialRule,+    "vue/max-len": specialRule,      // The rest are rules that you never need to enable when using Prettier.-    "array-bracket-newline": "off",-    "array-bracket-spacing": "off",-    "array-element-newline": "off",-    "arrow-parens": "off",-    "arrow-spacing": "off",-    "block-spacing": "off",-    "brace-style": "off",-    "comma-dangle": "off",-    "comma-spacing": "off",-    "comma-style": "off",-    "computed-property-spacing": "off",-    "dot-location": "off",-    "eol-last": "off",-    "func-call-spacing": "off",-    "function-call-argument-newline": "off",-    "function-paren-newline": "off",-    "generator-star-spacing": "off",-    "implicit-arrow-linebreak": "off",-    "indent": "off",-    "jsx-quotes": "off",-    "key-spacing": "off",-    "keyword-spacing": "off",-    "linebreak-style": "off",-    "max-statements-per-line": "off",-    "multiline-ternary": "off",-    "newline-per-chained-call": "off",-    "new-parens": "off",-    "no-extra-parens": "off",-    "no-extra-semi": "off",-    "no-floating-decimal": "off",-    "no-mixed-spaces-and-tabs": "off",-    "no-multi-spaces": "off",-    "no-multiple-empty-lines": "off",-    "no-trailing-spaces": "off",-    "no-whitespace-before-property": "off",-    "nonblock-statement-body-position": "off",-    "object-curly-newline": "off",-    "object-curly-spacing": "off",-    "object-property-newline": "off",-    "one-var-declaration-per-line": "off",-    "operator-linebreak": "off",-    "padded-blocks": "off",-    "quote-props": "off",-    "rest-spread-spacing": "off",-    "semi": "off",-    "semi-spacing": "off",-    "semi-style": "off",-    "space-before-blocks": "off",-    "space-before-function-paren": "off",-    "space-in-parens": "off",-    "space-infix-ops": "off",-    "space-unary-ops": "off",-    "switch-colon-spacing": "off",-    "template-curly-spacing": "off",-    "template-tag-spacing": "off",-    "unicode-bom": "off",-    "wrap-iife": "off",-    "wrap-regex": "off",-    "yield-star-spacing": "off",     "@babel/object-curly-spacing": "off",@@ -175,5 +114,28 @@     ...(includeDeprecated && {+      // Removed in version 0.10.0.+      // https://eslint.org/docs/latest/rules/space-unary-word-ops+      "space-unary-word-ops": "off",+       // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/generator-star+      // https://github.com/eslint/eslint/issues/1898       "generator-star": "off",+      "no-comma-dangle": "off",+      "no-reserved-keys": "off",+      "no-space-before-semi": "off",+      "no-wrap-func": "off",+      "space-after-function-name": "off",+      "space-before-function-parentheses": "off",+      "space-in-brackets": "off",++      // Removed in version 2.0.0.+      // https://github.com/eslint/eslint/issues/5032+      "no-arrow-condition": "off",+      "space-after-keywords": "off",+      "space-before-keywords": "off",+      "space-return-throw-case": "off",++      // Deprecated since version 3.3.0.+      // https://eslint.org/docs/rules/no-spaced-func+      "no-spaced-func": "off",+       // Deprecated since version 4.0.0.@@ -181,41 +143,70 @@       "indent-legacy": "off",-      // Removed in version 2.0.0.-      // https://eslint.org/docs/latest/rules/no-arrow-condition-      "no-arrow-condition": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/no-comma-dangle-      "no-comma-dangle": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/no-reserved-keys-      "no-reserved-keys": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/no-space-before-semi-      "no-space-before-semi": "off",-      // Deprecated since version 3.3.0.-      // https://eslint.org/docs/rules/no-spaced-func-      "no-spaced-func": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/no-wrap-func-      "no-wrap-func": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/space-after-function-name-      "space-after-function-name": "off",-      // Removed in version 2.0.0.-      // https://eslint.org/docs/latest/rules/space-after-keywords-      "space-after-keywords": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/space-before-function-parentheses-      "space-before-function-parentheses": "off",-      // Removed in version 2.0.0.-      // https://eslint.org/docs/latest/rules/space-before-keywords-      "space-before-keywords": "off",-      // Removed in version 1.0.0.-      // https://eslint.org/docs/latest/rules/space-in-brackets-      "space-in-brackets": "off",-      // Removed in version 2.0.0.-      // https://eslint.org/docs/latest/rules/space-return-throw-case-      "space-return-throw-case": "off",-      // Removed in version 0.10.0.-      // https://eslint.org/docs/latest/rules/space-unary-word-ops-      "space-unary-word-ops": "off",++      // Deprecated since version 8.53.0.+      // https://eslint.org/blog/2023/10/deprecating-formatting-rules/+      "array-bracket-newline": "off",+      "array-bracket-spacing": "off",+      "array-element-newline": "off",+      "arrow-parens": "off",+      "arrow-spacing": "off",+      "block-spacing": "off",+      "brace-style": "off",+      "comma-dangle": "off",+      "comma-spacing": "off",+      "comma-style": "off",+      "computed-property-spacing": "off",+      "dot-location": "off",+      "eol-last": "off",+      "func-call-spacing": "off",+      "function-call-argument-newline": "off",+      "function-paren-newline": "off",+      "generator-star-spacing": "off",+      "implicit-arrow-linebreak": "off",+      "indent": "off",+      "jsx-quotes": "off",+      "key-spacing": "off",+      "keyword-spacing": "off",+      "linebreak-style": "off",+      "lines-around-comment": specialRule,+      "max-len": specialRule,+      "max-statements-per-line": "off",+      "multiline-ternary": "off",+      "new-parens": "off",+      "newline-per-chained-call": "off",+      "no-confusing-arrow": specialRule,+      "no-extra-parens": "off",+      "no-extra-semi": "off",+      "no-floating-decimal": "off",+      "no-mixed-operators": specialRule,+      "no-mixed-spaces-and-tabs": "off",+      "no-multi-spaces": "off",+      "no-multiple-empty-lines": "off",+      "no-tabs": specialRule,+      "no-trailing-spaces": "off",+      "no-whitespace-before-property": "off",+      "nonblock-statement-body-position": "off",+      "object-curly-newline": "off",+      "object-curly-spacing": "off",+      "object-property-newline": "off",+      "one-var-declaration-per-line": "off",+      "operator-linebreak": "off",+      "padded-blocks": "off",+      "quote-props": "off",+      "quotes": specialRule,+      "rest-spread-spacing": "off",+      "semi": "off",+      "semi-spacing": "off",+      "semi-style": "off",+      "space-before-blocks": "off",+      "space-before-function-paren": "off",+      "space-in-parens": "off",+      "space-infix-ops": "off",+      "space-unary-ops": "off",+      "switch-colon-spacing": "off",+      "template-curly-spacing": "off",+      "template-tag-spacing": "off",+      "wrap-iife": "off",+      "wrap-regex": "off",+      "yield-star-spacing": "off",+       // Deprecated since version 7.0.0.
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "eslint-config-prettier",-  "version": "8.10.2",+  "version": "9.1.2",   "license": "MIT",
eslint-plugin-import npm
2.32.0 1y ago incident on record
critical-tier DELETION ×4BURST ×6
latest 2.32.0 versions 132 maintainers 3 critical-tier (snapshotted)
2.27.1
2.27.2
2.27.3
2.27.4
2.27.5
2.28.0
2.28.1
2.29.0
2.29.1
2.30.0
2.31.0
2.32.0
DELETION
0.7.6 published then removed
high · registry-verified · 2015-07-29 · 11y ago
DELETION
0.12.2 published then removed
high · registry-verified · 2016-02-08 · 10y ago
DELETION
1.10.1 published then removed
high · registry-verified · 2016-07-03 · 10y ago
DELETION
2.4.0 published then removed
high · registry-verified · 2017-06-02 · 9y ago
BURST
2 releases in 28m: 0.3.4, 0.3.5
info · registry-verified · 2015-03-24 · 11y ago
BURST
3 releases in 27m: 0.3.8, 0.3.9, 0.3.10
info · registry-verified · 2015-03-25 · 11y ago
BURST
2 releases in 31m: 0.7.6, 0.7.7
info · registry-verified · 2015-07-29 · 11y ago
BURST
2 releases in 3m: 2.25.0, 2.25.1
info · registry-verified · 2021-10-12 · 4y ago
BURST
2 releases in 9m: 2.27.1, 2.27.2
info · registry-verified · 2023-01-12 · 3y ago
BURST
2 releases in 3m: 2.27.3, 2.27.4
info · registry-verified · 2023-01-12 · 3y ago
release diff 2.31.0 → 2.32.0
+3 added · -1 removed · ~12 modified
lib/rules/no-unused-modules.js +55 lines · 2 flagged
--- +++ @@ -16,3 +16,2 @@ -var _fsWalk = require('../core/fsWalk'); var _builder = require('../exportMap/builder');var _builder2 = _interopRequireDefault(_builder);@@ -53,3 +52,3 @@ /**-   *+   * Given a FileEnumerator class, instantiate and load the list of files.    * @param FileEnumerator the `FileEnumerator` class from `eslint`'s internal api@@ -60,3 +59,21 @@ function listFilesUsingFileEnumerator(FileEnumerator, src, extensions) {-  var e = new FileEnumerator({+  // We need to know whether this is being run with flat config in order to+  // determine how to report errors if FileEnumerator throws due to a lack of eslintrc.+  var+  ESLINT_USE_FLAT_CONFIG = process.env.ESLINT_USE_FLAT_CONFIG;++  // This condition is sufficient to test in v8, since the environment variable is necessary to turn on flat config+  var isUsingFlatConfig = ESLINT_USE_FLAT_CONFIG && process.env.ESLINT_USE_FLAT_CONFIG !== 'false';++  // In the case of using v9, we can check the `shouldUseFlatConfig` function+  // If this function is present, then we assume it's v9+  try {var _require3 =+    require('eslint/use-at-your-own-risk'),shouldUseFlatConfig = _require3.shouldUseFlatConfig;+    isUsingFlatConfig = shouldUseFlatConfig && ESLINT_USE_FLAT_CONFIG !== 'false';+  } catch (_) {+    // We don't want to throw here, since we only want to update the+    // boolean if the function is available.+  }++  var enumerator = new FileEnumerator({     extensions: extensions });@@ -64,6 +81,29 @@ -  return Array.from(-  e.iterateFiles(src),-  function (_ref) {var filePath = _ref.filePath,ignored = _ref.ignored;return { filename: filePath, ignored: ignored };});-+  try {+    return Array.from(+    enumerator.iterateFiles(src),+    function (_ref) {var filePath = _ref.filePath,ignored = _ref.ignored;return { filename: filePath, ignored: ignored };});++  } catch (e) {+    // If we're using flat config, and FileEnumerator throws due to a lack of eslintrc,+    // then we want to throw an error so that the user knows about this rule's reliance on+    // the legacy config.+    if (+    isUsingFlatConfig &&+    e.message.includes('No ESLint configuration found'))+    {+      throw new Error('\nDue to the exclusion of certain internal ESLint APIs when using flat config,\nthe import/no-unused-modules rule requires an .eslintrc file to know which\nfiles to ignore (even when using flat config).\nThe .eslintrc file only needs to contain "ignorePatterns", or can be empty if\nyou do not want to ignore any files.\n\nSee https://github.com/import-js/eslint-plugin-import/issues/3079\nfor additional context.\n');++++++++++    }+    // If this isn't the case, then we'll just let the error bubble up+    throw e;+  } }@@ -80,3 +120,3 @@     // eslint/lib/util/glob-util has been moved to eslint/lib/util/glob-utils with version 5.3-    var _require3 = require('eslint/lib/util/glob-utils'),originalListFilesToProcess = _require3.listFilesToProcess;+    var _require4 = require('eslint/lib/util/glob-utils'),originalListFilesToProcess = _require4.listFilesToProcess;     // Prevent passing invalid options (extensions array) to old versions of the function.@@ -95,5 +135,5 @@     // Last place to try (pre v5.3)-    var _require4 =--    require('eslint/lib/util/glob-util'),_originalListFilesToProcess = _require4.listFilesToProcess;+    var _require5 =++    require('eslint/lib/util/glob-util'),_originalListFilesToProcess = _require5.listFilesToProcess;     var patterns = src.concat(@@ -107,45 +147,2 @@   }-}--/**-   * Given a source root and list of supported extensions, use fsWalk and the-   * new `eslint` `context.session` api to build the list of files we want to operate on-   * @param {string[]} srcPaths array of source paths (for flat config this should just be a singular root (e.g. cwd))-   * @param {string[]} extensions list of supported extensions-   * @param {{ isDirectoryIgnored: (path: string) => boolean, isFileIgnored: (path: string) => boolean }} session eslint context session object-   * @returns {string[]} list of files to operate on-   */-function listFilesWithModernApi(srcPaths, extensions, session) {-  /** @type {string[]} */-  var files = [];var _loop = function _loop(--  i) {-    var src = srcPaths[i];-    // Use walkSync along with the new session api to gather the list of files-    var entries = (0, _fsWalk.walkSync)(src, {-      deepFilter: function () {function deepFilter(entry) {-          var fullEntryPath = (0, _path.resolve)(src, entry.path);--          // Include the directory if it's not marked as ignore by eslint-          return !session.isDirectoryIgnored(fullEntryPath);-        }return deepFilter;}(),-      entryFilter: function () {function entryFilter(entry) {-          var fullEntryPath = (0, _path.resolve)(src, entry.path);--          // Include the file if it's not marked as ignore by eslint and its extension is included in our list-          return (-            !session.isFileIgnored(fullEntryPath) &&-            extensions.find(function (extension) {return entry.path.endsWith(extension);}));--        }return entryFilter;}() });---    // Filter out directories and map entries to their paths-    files.push.apply(files, _toConsumableArray(-    entries.-    filter(function (entry) {return !entry.dirent.isDirectory();}).-    map(function (entry) {return entry.path;})));};for (var i = 0; i < srcPaths.length; i++) {_loop(i);--  }-  return files; }@@ -157,18 +154,5 @@    * @param {string[]} extensions - list of supported file extensions-   * @param {import('eslint').Rule.RuleContext} context - the eslint context object    * @returns {string[] | { filename: string, ignored: boolean }[]} the list of files that this rule will evaluate.    */-function listFilesToProcess(src, extensions, context) {-  // If the context object has the new session functions, then prefer those-  // Otherwise, fallback to using the deprecated `FileEnumerator` for legacy support.-  // https://github.com/eslint/eslint/issues/18087-  if (-  context.session &&-  context.session.isFileIgnored &&-  context.session.isDirectoryIgnored)-  {-    return listFilesWithModernApi(src, extensions, context.session);-  }--  // Fallback to og FileEnumerator+function listFilesToProcess(src, extensions) {   var FileEnumerator = requireFileEnumerator();@@ -297,6 +281,6 @@ -  var srcFileList = listFilesToProcess(src, extensions, context);+  var srcFileList = listFilesToProcess(src, extensions);    // prepare list of ignored files-  var ignoredFilesList = listFilesToProcess(ignoreExports, extensions, context);+  var ignoredFilesList = listFilesToProcess(ignoreExports, extensions); @@ -1087,2 +1071,2 @@     }return create;}() };-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby11bnVzZWQtbW9kdWxlcy5qcyJdLCJuYW1lcyI6WyJyZXF1aXJlRmlsZUVudW1lcmF0b3IiLCJGaWxlRW51bWVyYXRvciIsInJlcXVpcmUiLCJlIiwiY29kZSIsImxpc3RGaWxlc1VzaW5nRmlsZUVudW1lcmF0b3IiLCJzcmMiLCJleHRlbnNpb25zIiwiQXJyYXkiLCJmcm9tIiwiaXRlcmF0ZUZpbGVzIiwiZmlsZVBhdGgiLCJpZ25vcmVkIiwiZmlsZW5hbWUiLCJsaXN0RmlsZXNXaXRoTGVnYWN5RnVuY3Rpb25zIiwib3JpZ2luYWxMaXN0RmlsZXNUb1Byb2Nlc3MiLCJsaXN0RmlsZXNUb1Byb2Nlc3MiLCJwYXR0ZXJucyIsImNvbmNhdCIsInBhdHRlcm4iLCJtYXAiLCJleHRlbnNpb24iLCJ0ZXN0IiwibGlzdEZpbGVzV2l0aE1vZGVybkFwaSIsInNyY1BhdGhzIiwic2Vzc2lvbiIsImZpbGVzIiwiaSIsImVudHJpZXMiLCJkZWVwRmlsdGVyIiwiZW50cnkiLCJmdWxsRW50cnlQYXRoIiwicGF0aCIsImlzRGlyZWN0b3J5SWdub3JlZCIsImVudHJ5RmlsdGVyIiwiaXNGaWxlSWdub3JlZCIsImZpbmQiLCJlbmRzV2l0aCIsInB1c2giLCJmaWx0ZXIiLCJkaXJlbnQiLCJpc0RpcmVjdG9yeSIsImxlbmd0aCIsImNvbnRleHQiLCJFWFBPUlRfREVGQVVMVF9ERUNMQVJBVElPTiIsIkVYUE9SVF9OQU1FRF9ERUNMQVJBVElPTiIsIkVYUE9SVF9BTExfREVDTEFSQVRJT04iLCJJTVBPUlRfREVDTEFSQVRJT04iLCJJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiIsIklNUE9SVF9ERUZBVUxUX1NQRUNJRklFUiIsIlZBUklBQkxFX0RFQ0xBUkFUSU9OIiwiRlVOQ1RJT05fREVDTEFSQVRJT04iLCJDTEFTU19ERUNMQVJBVElPTiIsIklERU5USUZJRVIiLCJPQkpFQ1RfUEFUVEVSTiIsIkFSUkFZX1BBVFRFUk4iLCJUU19JTlRFUkZBQ0VfREVDTEFSQVRJT04iLCJUU19UWVBFX0FMSUFTX0RFQ0xBUkFUSU9OIiwiVFNfRU5VTV9ERUNMQVJBVElPTiIsIkRFRkFVTFQiLCJmb3JFYWNoRGVjbGFyYXRpb25JZGVudGlmaWVyIiwiZGVjbGFyYXRpb24iLCJjYiIsImlzVHlwZURlY2xhcmF0aW9uIiwidHlwZSIsImlkIiwibmFtZSIsImRlY2xhcmF0aW9ucyIsImZvckVhY2giLCJlbGVtZW50cyIsImltcG9ydExpc3QiLCJNYXAiLCJleHBvcnRMaXN0IiwidmlzaXRvcktleU1hcCIsImlnbm9yZWRGaWxlcyIsIlNldCIsImZpbGVzT3V0c2lkZVNyYyIsImlzTm9kZU1vZHVsZSIsInJlc29sdmVGaWxlcyIsImlnbm9yZUV4cG9ydHMiLCJzZXR0aW5ncyIsInNyY0ZpbGVMaXN0IiwiaWdub3JlZEZpbGVzTGlzdCIsImFkZCIsInJlc29sdmVkRmlsZXMiLCJwcmVwYXJlSW1wb3J0c0FuZEV4cG9ydHMiLCJzcmNGaWxlcyIsImV4cG9ydEFsbCIsImZpbGUiLCJleHBvcnRzIiwiaW1wb3J0cyIsImN1cnJlbnRFeHBvcnRzIiwiRXhwb3J0TWFwQnVpbGRlciIsImdldCIsImRlcGVuZGVuY2llcyIsInJlZXhwb3J0cyIsImxvY2FsSW1wb3J0TGlzdCIsIm5hbWVzcGFjZSIsInZpc2l0b3JLZXlzIiwic2V0IiwiY3VycmVudEV4cG9ydEFsbCIsImdldERlcGVuZGVuY3kiLCJkZXBlbmRlbmN5IiwidmFsdWUiLCJrZXkiLCJ3aGVyZVVzZWQiLCJyZWV4cG9ydCIsImdldEltcG9ydCIsImxvY2FsSW1wb3J0IiwiY3VycmVudFZhbHVlIiwibG9jYWwiLCJpbXBvcnRlZFNwZWNpZmllcnMiLCJzcGVjaWZpZXIiLCJoYXMiLCJ2YWwiLCJjdXJyZW50RXhwb3J0IiwiZGV0ZXJtaW5lVXNhZ2UiLCJsaXN0VmFsdWUiLCJsaXN0S2V5IiwiY3VycmVudEltcG9ydCIsImV4cG9ydFN0YXRlbWVudCIsImdldFNyYyIsInByb2Nlc3MiLCJjd2QiLCJsYXN0UHJlcGFyZUtleSIsImRvUHJlcGFyYXRpb24iLCJwcmVwYXJlS2V5IiwiSlNPTiIsInN0cmluZ2lmeSIsInNvcnQiLCJjbGVhciIsIm5ld05hbWVzcGFjZUltcG9ydEV4aXN0cyIsInNwZWNpZmllcnMiLCJzb21lIiwibmV3RGVmYXVsdEltcG9ydEV4aXN0cyIsImZpbGVJc0luUGtnIiwicGtnIiwiYmFzZVBhdGgiLCJjaGVja1BrZ0ZpZWxkU3RyaW5nIiwicGtnRmllbGQiLCJjaGVja1BrZ0ZpZWxkT2JqZWN0IiwicGtnRmllbGRGaWxlcyIsImNoZWNrUGtnRmllbGQiLCJiaW4iLCJicm93c2VyIiwibWFpbiIsIm1vZHVsZSIsIm1ldGEiLCJkb2NzIiwiY2F0ZWdvcnkiLCJkZXNjcmlwdGlvbiIsInVybCIsInNjaGVtYSIsInByb3BlcnRpZXMiLCJ1bmlxdWVJdGVtcyIsIml0ZW1zIiwibWluTGVuZ3RoIiwibWlzc2luZ0V4cG9ydHMiLCJ1bnVzZWRFeHBvcnRzIiwiaWdub3JlVW51c2VkVHlwZUV4cG9ydHMiLCJhbnlPZiIsIm1pbkl0ZW1zIiwicmVxdWlyZWQiLCJjcmVhdGUiLCJvcHRpb25zIiwiY2hlY2tFeHBvcnRQcmVzZW5jZSIsIm5vZGUiLCJleHBvcnRDb3VudCIsIm5hbWVzcGFjZUltcG9ydHMiLCJzaXplIiwicmVwb3J0IiwiYm9keSIsImNoZWNrVXNhZ2UiLCJleHBvcnRlZFZhbHVlIiwiaXNUeXBlRXhwb3J0IiwiY29uc29sZSIsImVycm9yIiwiZXhwb3J0c0tleSIsInVwZGF0ZUV4cG9ydFVzYWdlIiwibmV3RXhwb3J0cyIsIm5ld0V4cG9ydElkZW50aWZpZXJzIiwiZXhwb3J0ZWQiLCJ1cGRhdGVJbXBvcnRVc2FnZSIsIm9sZEltcG9ydFBhdGhzIiwib2xkTmFtZXNwYWNlSW1wb3J0cyIsIm5ld05hbWVzcGFjZUltcG9ydHMiLCJvbGRFeHBvcnRBbGwiLCJuZXdFeHBvcnRBbGwiLCJvbGREZWZhdWx0SW1wb3J0cyIsIm5ld0RlZmF1bHRJbXBvcnRzIiwib2xkSW1wb3J0cyIsIm5ld0ltcG9ydHMiLCJwcm9jZXNzRHluYW1pY0ltcG9ydCIsInNvdXJjZSIsInAiLCJJbXBvcnRFeHByZXNzaW9uIiwiY2hpbGQiLCJDYWxsRXhwcmVzc2lvbiIsImNhbGxlZSIsImFyZ3VtZW50cyIsImFzdE5vZGUiLCJyZXNvbHZlZFBhdGgiLCJyYXciLCJyZXBsYWNlIiwiaW1wb3J0ZWQiLCJFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24iLCJFeHBvcnROYW1lZERlY2xhcmF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFNQTtBQUNBO0FBQ0Esc0Q7QUFDQSxrRDtBQUNBO0FBQ0EsMkQ7QUFDQSx1QztBQUNBLCtDO0FBQ0EseUQ7O0FBRUE7QUFDQSwrQztBQUNBLDZEO0FBQ0EscUMsMlVBbkJBOzs7O29YQXFCQTs7Ozs7dVhBTUEsU0FBU0EscUJBQVQsR0FBaUMsQ0FDL0IsSUFBSUMsdUJBQUo7O0FBRUE7QUFDQSxNQUFJO0FBQ29CQyxZQUFRLDZCQUFSLENBRHBCLENBQ0NELGNBREQsWUFDQ0EsY0FERDtBQUVILEdBRkQsQ0FFRSxPQUFPRSxDQUFQLEVBQVU7QUFDVjtBQUNBLFFBQUlBLEVBQUVDLElBQUYsS0FBVyxrQkFBZixFQUFtQztBQUNqQyxZQUFNRCxDQUFOO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJO0FBQ29CRCxjQUFRLHVDQUFSLENBRHBCLENBQ0NELGNBREQsYUFDQ0EsY0FERDtBQUVILEtBRkQsQ0FFRSxPQUFPRSxDQUFQLEVBQVU7QUFDVjtBQUNBLFVBQUlBLEVBQUVDLElBQUYsS0FBVyxrQkFBZixFQUFtQztBQUNqQyxjQUFNRCxDQUFOO0FBQ0Q7QUFDRjtBQUNGO0FBQ0QsU0FBT0YsY0FBUDtBQUNEOztBQUVEOzs7Ozs7O0FBT0EsU0FBU0ksNEJBQVQsQ0FBc0NKLGNBQXRDLEVBQXNESyxHQUF0RCxFQUEyREMsVUFBM0QsRUFBdUU7QUFDckUsTUFBTUosSUFBSSxJQUFJRixjQUFKLENBQW1CO0FBQzNCTSwwQkFEMkIsRUFBbkIsQ0FBVjs7O0FBSUEsU0FBT0MsTUFBTUMsSUFBTjtBQUNMTixJQUFFTyxZQUFGLENBQWVKLEdBQWYsQ0FESztBQUVMLHVCQUFHSyxRQUFILFFBQUdBLFFBQUgsQ0FBYUMsT0FBYixRQUFhQSxPQUFiLFFBQTRCLEVBQUVDLFVBQVVGLFFBQVosRUFBc0JDLGdCQUF0QixFQUE1QixFQUZLLENBQVA7O0FBSUQ7O0FBRUQ7Ozs7Ozs7QUFPQSxTQUFTRSw0QkFBVCxDQUFzQ1IsR0FBdEMsRUFBMkNDLFVBQTNDLEVBQXVEO0FBQ3JELE1BQUk7QUFDRjtBQURFLG9CQUV5REwsUUFBUSw0QkFBUixDQUZ6RCxDQUUwQmEsMEJBRjFCLGFBRU1DLGtCQUZOO0FBR0Y7QUFDQTtBQUNBOztBQUVBLFdBQU9ELDJCQUEyQlQsR0FBM0IsRUFBZ0M7QUFDckNDLDRCQURxQyxFQUFoQyxDQUFQOztBQUdELEdBVkQsQ0FVRSxPQUFPSixDQUFQLEVBQVU7QUFDVjtBQUNBLFFBQUlBLEVBQUVDLElBQUYsS0FBVyxrQkFBZixFQUFtQztBQUNqQyxZQUFNRCxDQUFOO0FBQ0Q7O0FBRUQ7QUFOVTs7QUFTTkQsWUFBUSwyQkFBUixDQVRNLENBUVlhLDJCQVJaLGFBUVJDLGtCQVJRO0FBVVYsUUFBTUMsV0FBV1gsSUFBSVksTUFBSjtBQUNmO0FBQ0VaLE9BREY7QUFFRSxjQUFDYSxPQUFELFVBQWFaLFdBQVdhLEdBQVgsQ0FBZSxVQUFDQyxTQUFELFVBQWdCLFlBQUQsQ0FBY0MsSUFBZCxDQUFtQkgsT0FBbkIsSUFBOEJBLE9BQTlCLFVBQTJDQSxPQUEzQyxxQkFBMERFLFNBQTFELENBQWYsR0FBZixDQUFiLEVBRkYsQ0FEZSxDQUFqQjs7OztBQU9BLFdBQU9OLDRCQUEyQkUsUUFBM0IsQ0FBUDtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7O0FBUUEsU0FBU00sc0JBQVQsQ0FBZ0NDLFFBQWhDLEVBQTBDakIsVUFBMUMsRUFBc0RrQixPQUF0RCxFQUErRDtBQUM3RDtBQUNBLE1BQU1DLFFBQVEsRUFBZCxDQUY2RDs7QUFJcERDLEdBSm9EO0FBSzNELFFBQU1yQixNQUFNa0IsU0FBU0csQ0FBVCxDQUFaO0FBQ0E7QUFDQSxRQUFNQyxVQUFVLHNCQUFTdEIsR0FBVCxFQUFjO0FBQzVCdUIsZ0JBRDRCLG1DQUNqQkMsS0FEaUIsRUFDVjtBQUNoQixjQUFNQyxnQkFBZ0IsbUJBQVl6QixHQUFaLEVBQWlCd0IsTUFBTUUsSUFBdkIsQ0FBdEI7O0FBRUE7QUFDQSxpQkFBTyxDQUFDUCxRQUFRUSxrQkFBUixDQUEyQkYsYUFBM0IsQ0FBUjtBQUNELFNBTjJCO0FBTzVCRyxpQkFQNEIsb0NBT2hCSixLQVBnQixFQU9UO0FBQ2pCLGNBQU1DLGdCQUFnQixtQkFBWXpCLEdBQVosRUFBaUJ3QixNQUFNRSxJQUF2QixDQUF0Qjs7QUFFQTtBQUNBO0FBQ0UsYUFBQ1AsUUFBUVUsYUFBUixDQUFzQkosYUFBdEIsQ0FBRDtBQUNHeEIsdUJBQVc2QixJQUFYLENBQWdCLFVBQUNmLFNBQUQsVUFBZVMsTUFBTUUsSUFBTixDQUFXSyxRQUFYLENBQW9CaEIsU0FBcEIsQ0FBZixFQUFoQixDQUZMOztBQUlELFNBZjJCLHdCQUFkLENBQWhCOzs7QUFrQkE7QUFDQUssVUFBTVksSUFBTjtBQUNLVjtBQUNBVyxVQURBLENBQ08sVUFBQ1QsS0FBRCxVQUFXLENBQUNBLE1BQU1VLE1BQU4sQ0FBYUMsV0FBYixFQUFaLEVBRFA7QUFFQXJCLE9BRkEsQ0FFSSxVQUFDVSxLQUFELFVBQVdBLE1BQU1FLElBQWpCLEVBRkosQ0FETCxHQTFCMkQsRUFJN0QsS0FBSyxJQUFJTCxJQUFJLENBQWIsRUFBZ0JBLElBQUlILFNBQVNrQixNQUE3QixFQUFxQ2YsR0FBckMsRUFBMEMsT0FBakNBLENBQWlDOztBQTJCekM7QUFDRCxTQUFPRCxLQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozs7O0FBUUEsU0FBU1Ysa0JBQVQsQ0FBNEJWLEdBQTVCLEVBQWlDQyxVQUFqQyxFQUE2Q29DLE9BQTdDLEVBQXNEO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0VBLFVBQVFsQixPQUFSO0FBQ0drQixVQUFRbEIsT0FBUixDQUFnQlUsYUFEbkI7QUFFR1EsVUFBUWxCLE9BQVIsQ0FBZ0JRLGtCQUhyQjtBQUlFO0FBQ0EsV0FBT1YsdUJBQXVCakIsR0FBdkIsRUFBNEJDLFVBQTVCLEVBQXdDb0MsUUFBUWxCLE9BQWhELENBQVA7QUFDRDs7QUFFRDtBQUNBLE1BQU14QixpQkFBaUJELHVCQUF2Qjs7QUFFQTtBQUNBLE1BQUlDLGNBQUosRUFBb0I7QUFDbEIsV0FBT0ksNkJBQTZCSixjQUE3QixFQUE2Q0ssR0FBN0MsRUFBa0RDLFVBQWxELENBQVA7QUFDRDtBQUNEO0FBQ0EsU0FBT08sNkJBQTZCUixHQUE3QixFQUFrQ0MsVUFBbEMsQ0FBUDtBQUNEOztBQUVELElBQU1xQyw2QkFBNkIsMEJBQW5DO0FBQ0EsSUFBTUMsMkJBQTJCLHdCQUFqQztBQUNBLElBQU1DLHlCQUF5QixzQkFBL0I7QUFDQSxJQUFNQyxxQkFBcUIsbUJBQTNCO0FBQ0EsSUFBTUMsNkJBQTZCLDBCQUFuQztBQUNBLElBQU1DLDJCQUEyQix3QkFBakM7QUFDQSxJQUFNQyx1QkFBdUIscUJBQTdCO0FBQ0EsSUFBTUMsdUJBQXVCLHFCQUE3QjtBQUNBLElBQU1DLG9CQUFvQixrQkFBMUI7QUFDQSxJQUFNQyxhQUFhLFlBQW5CO0FBQ0EsSUFBTUMsaUJBQWlCLGVBQXZCO0FBQ0EsSUFBTUMsZ0JBQWdCLGNBQXRCO0FBQ0EsSUFBTUMsMkJBQTJCLHdCQUFqQztBQUNBLElBQU1DLDRCQUE0Qix3QkFBbEM7QUFDQSxJQUFNQyxzQkFBc0IsbUJBQTVCO0FBQ0EsSUFBTUMsVUFBVSxTQUFoQjs7QUFFQSxTQUFTQyw0QkFBVCxDQUFzQ0MsV0FBdEMsRUFBbURDLEVBQW5ELEVBQXVEO0FBQ3JELE1BQUlELFdBQUosRUFBaUI7QUFDZixRQUFNRSxvQkFBb0JGLFlBQVlHLElBQVosS0FBcUJSLHdCQUFyQjtBQUNyQkssZ0JBQVlHLElBQVosS0FBcUJQLHlCQURBO0FBRXJCSSxnQkFBWUcsSUFBWixLQUFxQk4sbUJBRjFCOztBQUlBO0FBQ0VHLGdCQUFZRyxJQUFaLEtBQXFCYixvQkFBckI7QUFDR1UsZ0JBQVlHLElBQVosS0FBcUJaLGlCQUR4QjtBQUVHVyxxQkFITDtBQUlFO0FBQ0FELFNBQUdELFlBQVlJLEVBQVosQ0FBZUMsSUFBbEIsRUFBd0JILGlCQUF4QjtBQUNELEtBTkQsTUFNTyxJQUFJRixZQUFZRyxJQUFaLEtBQXFCZCxvQkFBekIsRUFBK0M7QUFDcERXLGtCQUFZTSxZQUFaLENBQXlCQyxPQUF6QixDQUFpQyxpQkFBWSxLQUFUSCxFQUFTLFNBQVRBLEVBQVM7QUFDM0MsWUFBSUEsR0FBR0QsSUFBSCxLQUFZVixjQUFoQixFQUFnQztBQUM5QiwyQ0FBd0JXLEVBQXhCLEVBQTRCLFVBQUM5QyxPQUFELEVBQWE7QUFDdkMsZ0JBQUlBLFFBQVE2QyxJQUFSLEtBQWlCWCxVQUFyQixFQUFpQztBQUMvQlMsaUJBQUczQyxRQUFRK0MsSUFBWCxFQUFpQixLQUFqQjtBQUNEO0FBQ0YsV0FKRDtBQUtELFNBTkQsTUFNTyxJQUFJRCxHQUFHRCxJQUFILEtBQVlULGFBQWhCLEVBQStCO0FBQ3BDVSxhQUFHSSxRQUFILENBQVlELE9BQVosQ0FBb0IsaUJBQWMsS0FBWEYsSUFBVyxTQUFYQSxJQUFXO0FBQ2hDSixlQUFHSSxJQUFILEVBQVMsS0FBVDtBQUNELFdBRkQ7QUFHRCxTQUpNLE1BSUE7QUFDTEosYUFBR0csR0FBR0MsSUFBTixFQUFZLEtBQVo7QUFDRDtBQUNGLE9BZEQ7QUFlRDtBQUNGO0FBQ0Y7O0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsSUFBTUksYUFBYSxJQUFJQyxHQUFKLEVBQW5COztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeUJBLElBQU1DLGFBQWEsSUFBSUQsR0FBSixFQUFuQjs7QUFFQSxJQUFNRSxnQkFBZ0IsSUFBSUYsR0FBSixFQUF0Qjs7QUFFQTtBQUNBLElBQU1HLGVBQWUsSUFBSUMsR0FBSixFQUFyQjtBQUNBLElBQU1DLGtCQUFrQixJQUFJRCxHQUFKLEVBQXhCOztBQUVBLElBQU1FLGVBQWUsU0FBZkEsWUFBZSxDQUFDN0MsSUFBRCxVQUFXLHFCQUFELENBQXVCVixJQUF2QixDQUE0QlUsSUFBNUIsQ0FBVixHQUFyQjs7QUFFQTs7Ozs7O0FBTUEsU0FBUzhDLFlBQVQsQ0FBc0J4RSxHQUF0QixFQUEyQnlFLGFBQTNCLEVBQTBDcEMsT0FBMUMsRUFBbUQ7QUFDakQsTUFBTXBDLGFBQWFDLE1BQU1DLElBQU4sQ0FBVywrQkFBa0JrQyxRQUFRcUMsUUFBMUIsQ0FBWCxDQUFuQjs7QUFFQSxNQUFNQyxjQUFjakUsbUJBQW1CVixHQUFuQixFQUF3QkMsVUFBeEIsRUFBb0NvQyxPQUFwQyxDQUFwQjs7QUFFQTtBQUNBLE1BQU11QyxtQkFBbUJsRSxtQkFBbUIrRCxhQUFuQixFQUFrQ3hFLFVBQWxDLEVBQThDb0MsT0FBOUMsQ0FBekI7O0FBRUE7QUFDQSxNQUFJdUMsaUJBQWlCeEMsTUFBakIsSUFBMkIsT0FBT3dDLGlCQUFpQixDQUFqQixDQUFQLEtBQStCLFFBQTlELEVBQXdFO0FBQ3RFQSxxQkFBaUJkLE9BQWpCLENBQXlCLFVBQUN2RCxRQUFELFVBQWM2RCxhQUFhUyxHQUFiLENBQWlCdEUsUUFBakIsQ0FBZCxFQUF6QjtBQUNELEdBRkQsTUFFTztBQUNMcUUscUJBQWlCZCxPQUFqQixDQUF5QixzQkFBR3ZELFFBQUgsU0FBR0EsUUFBSCxRQUFrQjZELGFBQWFTLEdBQWIsQ0FBaUJ0RSxRQUFqQixDQUFsQixFQUF6QjtBQUNEOztBQUVEO0FBQ0EsTUFBTXVFLGdCQUFnQkgsWUFBWXZDLE1BQVosSUFBc0IsT0FBT3VDLFlBQVksQ0FBWixDQUFQLEtBQTBCLFFBQWhEO0FBQ2xCQSxjQUFZMUMsTUFBWixDQUFtQixVQUFDNUIsUUFBRCxVQUFjLENBQUNrRSxhQUFhbEUsUUFBYixDQUFmLEVBQW5CLENBRGtCO0FBRWxCLG1DQUFRc0UsV0FBUixFQUFxQixzQkFBR3BFLFFBQUgsU0FBR0EsUUFBSCxRQUFrQmdFLGFBQWFoRSxRQUFiLElBQXlCLEVBQXpCLEdBQThCQSxRQUFoRCxFQUFyQixDQUZKOztBQUlBLFNBQU8sSUFBSThELEdBQUosQ0FBUVMsYUFBUixDQUFQO0FBQ0Q7O0FBRUQ7OztBQUdBLElBQU1DLDJCQUEyQixTQUEzQkEsd0JBQTJCLENBQUNDLFFBQUQsRUFBVzNDLE9BQVgsRUFBdUI7QUFDdEQsTUFBTTRDLFlBQVksSUFBSWhCLEdBQUosRUFBbEI7QUFDQWUsV0FBU2xCLE9BQVQsQ0FBaUIsVUFBQ29CLElBQUQsRUFBVTtBQUN6QixRQUFNQyxVQUFVLElBQUlsQixHQUFKLEVBQWhCO0FBQ0EsUUFBTW1CLFVBQVUsSUFBSW5CLEdBQUosRUFBaEI7QUFDQSxRQUFNb0IsaUJBQWlCQyxxQkFBaUJDLEdBQWpCLENBQXFCTCxJQUFyQixFQUEyQjdDLE9BQTNCLENBQXZCO0FBQ0EsUUFBSWdELGNBQUosRUFBb0I7O0FBRWhCRyxrQkFGZ0I7Ozs7O0FBT2RILG9CQVBjLENBRWhCRyxZQUZnQixDQUdoQkMsU0FIZ0IsR0FPZEosY0FQYyxDQUdoQkksU0FIZ0IsQ0FJUEMsZUFKTyxHQU9kTCxjQVBjLENBSWhCRCxPQUpnQixDQUtoQk8sU0FMZ0IsR0FPZE4sY0FQYyxDQUtoQk0sU0FMZ0IsQ0FNaEJDLFdBTmdCLEdBT2RQLGNBUGMsQ0FNaEJPLFdBTmdCOztBQVNsQnpCLG9CQUFjMEIsR0FBZCxDQUFrQlgsSUFBbEIsRUFBd0JVLFdBQXhCO0FBQ0E7QUFDQSxVQUFNRSxtQkFBbUIsSUFBSXpCLEdBQUosRUFBekI7QUFDQW1CLG1CQUFhMUIsT0FBYixDQUFxQixVQUFDaUMsYUFBRCxFQUFtQjtBQUN0QyxZQUFNQyxhQUFhRCxlQUFuQjtBQUNBLFlBQUlDLGVBQWUsSUFBbkIsRUFBeUI7QUFDdkI7QUFDRDs7QUFFREYseUJBQWlCakIsR0FBakIsQ0FBcUJtQixXQUFXdEUsSUFBaEM7QUFDRCxPQVBEO0FBUUF1RCxnQkFBVVksR0FBVixDQUFjWCxJQUFkLEVBQW9CWSxnQkFBcEI7O0FBRUFMLGdCQUFVM0IsT0FBVixDQUFrQixVQUFDbUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2hDLFlBQUlBLFFBQVE3QyxPQUFaLEVBQXFCO0FBQ25COEIsa0JBQVFVLEdBQVIsQ0FBWWxELHdCQUFaLEVBQXNDLEVBQUV3RCxXQUFXLElBQUk5QixHQUFKLEVBQWIsRUFBdEM7QUFDRCxTQUZELE1BRU87QUFDTGMsa0JBQVFVLEdBQVIsQ0FBWUssR0FBWixFQUFpQixFQUFFQyxXQUFXLElBQUk5QixHQUFKLEVBQWIsRUFBakI7QUFDRDtBQUNELFlBQU0rQixXQUFXSCxNQUFNSSxTQUFOLEVBQWpCO0FBQ0EsWUFBSSxDQUFDRCxRQUFMLEVBQWU7QUFDYjtBQUNEO0FBQ0QsWUFBSUUsY0FBY2xCLFFBQVFHLEdBQVIsQ0FBWWEsU0FBUzFFLElBQXJCLENBQWxCO0FBQ0EsWUFBSTZFLHFCQUFKO0FBQ0EsWUFBSU4sTUFBTU8sS0FBTixLQUFnQm5ELE9BQXBCLEVBQTZCO0FBQzNCa0QseUJBQWU1RCx3QkFBZjtBQUNELFNBRkQsTUFFTztBQUNMNEQseUJBQWVOLE1BQU1PLEtBQXJCO0FBQ0Q7QUFDRCxZQUFJLE9BQU9GLFdBQVAsS0FBdUIsV0FBM0IsRUFBd0M7QUFDdENBLHdCQUFjLElBQUlqQyxHQUFKLDhCQUFZaUMsV0FBWixJQUF5QkMsWUFBekIsR0FBZDtBQUNELFNBRkQsTUFFTztBQUNMRCx3QkFBYyxJQUFJakMsR0FBSixDQUFRLENBQUNrQyxZQUFELENBQVIsQ0FBZDtBQUNEO0FBQ0RuQixnQkFBUVMsR0FBUixDQUFZTyxTQUFTMUUsSUFBckIsRUFBMkI0RSxXQUEzQjtBQUNELE9BdkJEOztBQXlCQVosc0JBQWdCNUIsT0FBaEIsQ0FBd0IsVUFBQ21DLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUN0QyxZQUFJM0IsYUFBYTJCLEdBQWIsQ0FBSixFQUF1QjtBQUNyQjtBQUNEO0FBQ0QsWUFBTUksY0FBY2xCLFFBQVFHLEdBQVIsQ0FBWVcsR0FBWixLQUFvQixJQUFJN0IsR0FBSixFQUF4QztBQUNBNEIsY0FBTXBDLFlBQU4sQ0FBbUJDLE9BQW5CLENBQTJCLGlCQUE0QixLQUF6QjJDLGtCQUF5QixTQUF6QkEsa0JBQXlCO0FBQ3JEQSw2QkFBbUIzQyxPQUFuQixDQUEyQixVQUFDNEMsU0FBRCxFQUFlO0FBQ3hDSix3QkFBWXpCLEdBQVosQ0FBZ0I2QixTQUFoQjtBQUNELFdBRkQ7QUFHRCxTQUpEO0FBS0F0QixnQkFBUVMsR0FBUixDQUFZSyxHQUFaLEVBQWlCSSxXQUFqQjtBQUNELE9BWEQ7QUFZQXRDLGlCQUFXNkIsR0FBWCxDQUFlWCxJQUFmLEVBQXFCRSxPQUFyQjs7QUFFQTtBQUNBLFVBQUloQixhQUFhdUMsR0FBYixDQUFpQnpCLElBQWpCLENBQUosRUFBNEI7QUFDMUI7QUFDRDtBQUNEUyxnQkFBVTdCLE9BQVYsQ0FBa0IsVUFBQ21DLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUNoQyxZQUFJQSxRQUFRN0MsT0FBWixFQUFxQjtBQUNuQjhCLGtCQUFRVSxHQUFSLENBQVlsRCx3QkFBWixFQUFzQyxFQUFFd0QsV0FBVyxJQUFJOUIsR0FBSixFQUFiLEVBQXRDO0FBQ0QsU0FGRCxNQUVPO0FBQ0xjLGtCQUFRVSxHQUFSLENBQVlLLEdBQVosRUFBaUIsRUFBRUMsV0FBVyxJQUFJOUIsR0FBSixFQUFiLEVBQWpCO0FBQ0Q7QUFDRixPQU5EO0FBT0Q7QUFDRGMsWUFBUVUsR0FBUixDQUFZckQsc0JBQVosRUFBb0MsRUFBRTJELFdBQVcsSUFBSTlCLEdBQUosRUFBYixFQUFwQztBQUNBYyxZQUFRVSxHQUFSLENBQVluRCwwQkFBWixFQUF3QyxFQUFFeUQsV0FBVyxJQUFJOUIsR0FBSixFQUFiLEVBQXhDO0FBQ0FILGVBQVcyQixHQUFYLENBQWVYLElBQWYsRUFBcUJDLE9BQXJCO0FBQ0QsR0FoRkQ7QUFpRkFGLFlBQVVuQixPQUFWLENBQWtCLFVBQUNtQyxLQUFELEVBQVFDLEdBQVIsRUFBZ0I7QUFDaENELFVBQU1uQyxPQUFOLENBQWMsVUFBQzhDLEdBQUQsRUFBUztBQUNyQixVQUFNdkIsaUJBQWlCbkIsV0FBV3FCLEdBQVgsQ0FBZXFCLEdBQWYsQ0FBdkI7QUFDQSxVQUFJdkIsY0FBSixFQUFvQjtBQUNsQixZQUFNd0IsZ0JBQWdCeEIsZUFBZUUsR0FBZixDQUFtQi9DLHNCQUFuQixDQUF0QjtBQUNBcUUsc0JBQWNWLFNBQWQsQ0FBd0J0QixHQUF4QixDQUE0QnFCLEdBQTVCO0FBQ0Q7QUFDRixLQU5EO0FBT0QsR0FSRDtBQVNELENBNUZEOztBQThGQTs7OztBQUlBLElBQU1ZLGlCQUFpQixTQUFqQkEsY0FBaUIsR0FBTTtBQUMzQjlDLGFBQVdGLE9BQVgsQ0FBbUIsVUFBQ2lELFNBQUQsRUFBWUMsT0FBWixFQUF3QjtBQUN6Q0QsY0FBVWpELE9BQVYsQ0FBa0IsVUFBQ21DLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUNoQyxVQUFNZixVQUFVakIsV0FBV3FCLEdBQVgsQ0FBZVcsR0FBZixDQUFoQjtBQUNBLFVBQUksT0FBT2YsT0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQ2MsY0FBTW5DLE9BQU4sQ0FBYyxVQUFDbUQsYUFBRCxFQUFtQjtBQUMvQixjQUFJUCxrQkFBSjtBQUNBLGNBQUlPLGtCQUFrQnZFLDBCQUF0QixFQUFrRDtBQUNoRGdFLHdCQUFZaEUsMEJBQVo7QUFDRCxXQUZELE1BRU8sSUFBSXVFLGtCQUFrQnRFLHdCQUF0QixFQUFnRDtBQUNyRCtELHdCQUFZL0Qsd0JBQVo7QUFDRCxXQUZNLE1BRUE7QUFDTCtELHdCQUFZTyxhQUFaO0FBQ0Q7QUFDRCxjQUFJLE9BQU9QLFNBQVAsS0FBcUIsV0FBekIsRUFBc0M7QUFDcEMsZ0JBQU1RLGtCQUFrQi9CLFFBQVFJLEdBQVIsQ0FBWW1CLFNBQVosQ0FBeEI7QUFDQSxnQkFBSSxPQUFPUSxlQUFQLEtBQTJCLFdBQS9CLEVBQTRDO0FBQ2xDZix1QkFEa0MsR0FDcEJlLGVBRG9CLENBQ2xDZixTQURrQztBQUUxQ0Esd0JBQVV0QixHQUFWLENBQWNtQyxPQUFkO0FBQ0E3QixzQkFBUVUsR0FBUixDQUFZYSxTQUFaLEVBQXVCLEVBQUVQLG9CQUFGLEVBQXZCO0FBQ0Q7QUFDRjtBQUNGLFNBakJEO0FBa0JEO0FBQ0YsS0F0QkQ7QUF1QkQsR0F4QkQ7QUF5QkQsQ0ExQkQ7O0FBNEJBLElBQU1nQixTQUFTLFNBQVRBLE1BQVMsQ0FBQ25ILEdBQUQsRUFBUztBQUN0QixNQUFJQSxHQUFKLEVBQVM7QUFDUCxXQUFPQSxHQUFQO0FBQ0Q7QUFDRCxTQUFPLENBQUNvSCxRQUFRQyxHQUFSLEVBQUQsQ0FBUDtBQUNELENBTEQ7O0FBT0E7Ozs7QUFJQTtBQUNBLElBQUlyQyxpQkFBSjtBQUNBLElBQUlzQyx1QkFBSjtBQUNBLElBQU1DLGdCQUFnQixTQUFoQkEsYUFBZ0IsQ0FBQ3ZILEdBQUQsRUFBTXlFLGFBQU4sRUFBcUJwQyxPQUFyQixFQUFpQztBQUNyRCxNQUFNbUYsYUFBYUMsS0FBS0MsU0FBTCxDQUFlO0FBQ2hDMUgsU0FBSyxDQUFDQSxPQUFPLEVBQVIsRUFBWTJILElBQVosRUFEMkI7QUFFaENsRCxtQkFBZSxDQUFDQSxpQkFBaUIsRUFBbEIsRUFBc0JrRCxJQUF0QixFQUZpQjtBQUdoQzFILGdCQUFZQyxNQUFNQyxJQUFOLENBQVcsK0JBQWtCa0MsUUFBUXFDLFFBQTFCLENBQVgsRUFBZ0RpRCxJQUFoRCxFQUhvQixFQUFmLENBQW5COztBQUtBLE1BQUlILGVBQWVGLGNBQW5CLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBRUR0RCxhQUFXNEQsS0FBWDtBQUNBMUQsYUFBVzBELEtBQVg7QUFDQXhELGVBQWF3RCxLQUFiO0FBQ0F0RCxrQkFBZ0JzRCxLQUFoQjs7QUFFQTVDLGFBQVdSLGFBQWEyQyxPQUFPbkgsR0FBUCxDQUFiLEVBQTBCeUUsYUFBMUIsRUFBeUNwQyxPQUF6QyxDQUFYO0FBQ0EwQywyQkFBeUJDLFFBQXpCLEVBQW1DM0MsT0FBbkM7QUFDQXlFO0FBQ0FRLG1CQUFpQkUsVUFBakI7QUFDRCxDQW5CRDs7QUFxQkEsSUFBTUssMkJBQTJCLFNBQTNCQSx3QkFBMkIsQ0FBQ0MsVUFBRCxVQUFnQkEsV0FBV0MsSUFBWCxDQUFnQixzQkFBR3JFLElBQUgsU0FBR0EsSUFBSCxRQUFjQSxTQUFTaEIsMEJBQXZCLEVBQWhCLENBQWhCLEVBQWpDOztBQUVBLElBQU1zRix5QkFBeUIsU0FBekJBLHNCQUF5QixDQUFDRixVQUFELFVBQWdCQSxXQUFXQyxJQUFYLENBQWdCLHNCQUFHckUsSUFBSCxTQUFHQSxJQUFILFFBQWNBLFNBQVNmLHdCQUF2QixFQUFoQixDQUFoQixFQUEvQjs7QUFFQSxJQUFNc0YsY0FBYyxTQUFkQSxXQUFjLENBQUMvQyxJQUFELEVBQVU7QUFDTiw4QkFBVSxFQUFFbUMsS0FBS25DLElBQVAsRUFBVixDQURNLENBQ3BCeEQsSUFEb0IsY0FDcEJBLElBRG9CLENBQ2R3RyxHQURjLGNBQ2RBLEdBRGM7QUFFNUIsTUFBTUMsV0FBVyxtQkFBUXpHLElBQVIsQ0FBakI7O0FBRUEsTUFBTTBHLHNCQUFzQixTQUF0QkEsbUJBQXNCLENBQUNDLFFBQUQsRUFBYztBQUN4QyxRQUFJLGdCQUFLRixRQUFMLEVBQWVFLFFBQWYsTUFBNkJuRCxJQUFqQyxFQUF1QztBQUNyQyxhQUFPLElBQVA7QUFDRDtBQUNGLEdBSkQ7O0FBTUEsTUFBTW9ELHNCQUFzQixTQUF0QkEsbUJBQXNCLENBQUNELFFBQUQsRUFBYztBQUN4QyxRQUFNRSxnQkFBZ0IsaUNBQVEseUJBQU9GLFFBQVAsQ0FBUixFQUEwQixVQUFDcEMsS0FBRCxVQUFXLE9BQU9BLEtBQVAsS0FBaUIsU0FBakIsR0FBNkIsRUFBN0IsR0FBa0MsZ0JBQUtrQyxRQUFMLEVBQWVsQyxLQUFmLENBQTdDLEVBQTFCLENBQXRCOztBQUVBLFFBQUksZ0NBQVNzQyxhQUFULEVBQXdCckQsSUFBeEIsQ0FBSixFQUFtQztBQUNqQyxhQUFPLElBQVA7QUFDRDtBQUNGLEdBTkQ7O0FBUUEsTUFBTXNELGdCQUFnQixTQUFoQkEsYUFBZ0IsQ0FBQ0gsUUFBRCxFQUFjO0FBQ2xDLFFBQUksT0FBT0EsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUNoQyxhQUFPRCxvQkFBb0JDLFFBQXBCLENBQVA7QUFDRDs7QUFFRCxRQUFJLFFBQU9BLFFBQVAseUNBQU9BLFFBQVAsT0FBb0IsUUFBeEIsRUFBa0M7QUFDaEMsYUFBT0Msb0JBQW9CRCxRQUFwQixDQUFQO0FBQ0Q7QUFDRixHQVJEOztBQVVBLE1BQUlILG1CQUFnQixJQUFwQixFQUEwQjtBQUN4QixXQUFPLEtBQVA7QUFDRDs7QUFFRCxNQUFJQSxJQUFJTyxHQUFSLEVBQWE7QUFDWCxRQUFJRCxjQUFjTixJQUFJTyxHQUFsQixDQUFKLEVBQTRCO0FBQzFCLGFBQU8sSUFBUDtBQUNEO0FBQ0Y7O0FBRUQsTUFBSVAsSUFBSVEsT0FBUixFQUFpQjtBQUNmLFFBQUlGLGNBQWNOLElBQUlRLE9BQWxCLENBQUosRUFBZ0M7QUFDOUIsYUFBTyxJQUFQO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJUixJQUFJUyxJQUFSLEVBQWM7QUFDWixRQUFJUCxvQkFBb0JGLElBQUlTLElBQXhCLENBQUosRUFBbUM7QUFDakMsYUFBTyxJQUFQO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPLEtBQVA7QUFDRCxDQW5ERDs7QUFxREFDLE9BQU96RCxPQUFQLEdBQWlCO0FBQ2YwRCxRQUFNO0FBQ0puRixVQUFNLFlBREY7QUFFSm9GLFVBQU07QUFDSkMsZ0JBQVUsa0JBRE47QUFFSkMsbUJBQWEsdUZBRlQ7QUFHSkMsV0FBSywwQkFBUSxtQkFBUixDQUhELEVBRkY7O0FBT0pDLFlBQVEsQ0FBQztBQUNQQyxrQkFBWTtBQUNWbkosYUFBSztBQUNIZ0osdUJBQWEsc0RBRFY7QUFFSHRGLGdCQUFNLE9BRkg7QUFHSDBGLHVCQUFhLElBSFY7QUFJSEMsaUJBQU87QUFDTDNGLGtCQUFNLFFBREQ7QUFFTDRGLHVCQUFXLENBRk4sRUFKSixFQURLOzs7QUFVVjdFLHVCQUFlO0FBQ2J1RSx1QkFBYSxxRkFEQTtBQUVidEYsZ0JBQU0sT0FGTztBQUdiMEYsdUJBQWEsSUFIQTtBQUliQyxpQkFBTztBQUNMM0Ysa0JBQU0sUUFERDtBQUVMNEYsdUJBQVcsQ0FGTixFQUpNLEVBVkw7OztBQW1CVkMsd0JBQWdCO0FBQ2RQLHVCQUFhLG9DQURDO0FBRWR0RixnQkFBTSxTQUZRLEVBbkJOOztBQXVCVjhGLHVCQUFlO0FBQ2JSLHVCQUFhLGtDQURBO0FBRWJ0RixnQkFBTSxTQUZPLEVBdkJMOztBQTJCVitGLGlDQUF5QjtBQUN2QlQsdUJBQWEsdUNBRFU7QUFFdkJ0RixnQkFBTSxTQUZpQixFQTNCZixFQURMOzs7QUFpQ1BnRyxhQUFPO0FBQ0w7QUFDRVAsb0JBQVk7QUFDVksseUJBQWUsRUFBRSxRQUFNLENBQUMsSUFBRCxDQUFSLEVBREw7QUFFVnhKLGVBQUs7QUFDSDJKLHNCQUFVLENBRFAsRUFGSyxFQURkOzs7QUFPRUMsa0JBQVUsQ0FBQyxlQUFELENBUFosRUFESzs7QUFVTDtBQUNFVCxvQkFBWTtBQUNWSSwwQkFBZ0IsRUFBRSxRQUFNLENBQUMsSUFBRCxDQUFSLEVBRE4sRUFEZDs7QUFJRUssa0JBQVUsQ0FBQyxnQkFBRCxDQUpaLEVBVkssQ0FqQ0EsRUFBRCxDQVBKLEVBRFM7Ozs7OztBQTZEZkMsUUE3RGUsK0JBNkRSeEgsT0E3RFEsRUE2REM7Ozs7Ozs7QUFPVkEsY0FBUXlILE9BQVIsQ0FBZ0IsQ0FBaEIsS0FBc0IsRUFQWixDQUVaOUosR0FGWSxTQUVaQSxHQUZZLDZCQUdaeUUsYUFIWSxDQUdaQSxhQUhZLHVDQUdJLEVBSEosdUJBSVo4RSxjQUpZLFNBSVpBLGNBSlksQ0FLWkMsYUFMWSxTQUtaQSxhQUxZLENBTVpDLHVCQU5ZLFNBTVpBLHVCQU5ZOztBQVNkLFVBQUlELGFBQUosRUFBbUI7QUFDakJqQyxzQkFBY3ZILEdBQWQsRUFBbUJ5RSxhQUFuQixFQUFrQ3BDLE9BQWxDO0FBQ0Q7O0FBRUQsVUFBTTZDLE9BQU8sd0NBQW9CN0MsT0FBcEIsQ0FBYjs7QUFFQSxVQUFNMEgsbUNBQXNCLFNBQXRCQSxtQkFBc0IsQ0FBQ0MsSUFBRCxFQUFVO0FBQ3BDLGNBQUksQ0FBQ1QsY0FBTCxFQUFxQjtBQUNuQjtBQUNEOztBQUVELGNBQUluRixhQUFhdUMsR0FBYixDQUFpQnpCLElBQWpCLENBQUosRUFBNEI7QUFDMUI7QUFDRDs7QUFFRCxjQUFNK0UsY0FBYy9GLFdBQVdxQixHQUFYLENBQWVMLElBQWYsQ0FBcEI7QUFDQSxjQUFNRCxZQUFZZ0YsWUFBWTFFLEdBQVosQ0FBZ0IvQyxzQkFBaEIsQ0FBbEI7QUFDQSxjQUFNMEgsbUJBQW1CRCxZQUFZMUUsR0FBWixDQUFnQjdDLDBCQUFoQixDQUF6Qjs7QUFFQXVILGdDQUFtQnpILHNCQUFuQjtBQUNBeUgsZ0NBQW1CdkgsMEJBQW5CO0FBQ0EsY0FBSXVILFlBQVlFLElBQVosR0FBbUIsQ0FBdkIsRUFBMEI7QUFDeEI7QUFDQTtBQUNBOUgsb0JBQVErSCxNQUFSLENBQWVKLEtBQUtLLElBQUwsQ0FBVSxDQUFWLElBQWVMLEtBQUtLLElBQUwsQ0FBVSxDQUFWLENBQWYsR0FBOEJMLElBQTdDLEVBQW1ELGtCQUFuRDtBQUNEO0FBQ0RDLHNCQUFZcEUsR0FBWixDQUFnQnJELHNCQUFoQixFQUF3Q3lDLFNBQXhDO0FBQ0FnRixzQkFBWXBFLEdBQVosQ0FBZ0JuRCwwQkFBaEIsRUFBNEN3SCxnQkFBNUM7QUFDRCxTQXRCSyw4QkFBTjs7QUF3QkEsVUFBTUksMEJBQWEsU0FBYkEsVUFBYSxDQUFDTixJQUFELEVBQU9PLGFBQVAsRUFBc0JDLFlBQXRCLEVBQXVDO0FBQ3hELGNBQUksQ0FBQ2hCLGFBQUwsRUFBb0I7QUFDbEI7QUFDRDs7QUFFRCxjQUFJZ0IsZ0JBQWdCZix1QkFBcEIsRUFBNkM7QUFDM0M7QUFDRDs7QUFFRCxjQUFJckYsYUFBYXVDLEdBQWIsQ0FBaUJ6QixJQUFqQixDQUFKLEVBQTRCO0FBQzFCO0FBQ0Q7O0FBRUQsY0FBSStDLFlBQVkvQyxJQUFaLENBQUosRUFBdUI7QUFDckI7QUFDRDs7QUFFRCxjQUFJWixnQkFBZ0JxQyxHQUFoQixDQUFvQnpCLElBQXBCLENBQUosRUFBK0I7QUFDN0I7QUFDRDs7QUFFRDtBQUNBLGNBQUksQ0FBQ0YsU0FBUzJCLEdBQVQsQ0FBYXpCLElBQWIsQ0FBTCxFQUF5QjtBQUN2QkYsdUJBQVdSLGFBQWEyQyxPQUFPbkgsR0FBUCxDQUFiLEVBQTBCeUUsYUFBMUIsRUFBeUNwQyxPQUF6QyxDQUFYO0FBQ0EsZ0JBQUksQ0FBQzJDLFNBQVMyQixHQUFULENBQWF6QixJQUFiLENBQUwsRUFBeUI7QUFDdkJaLDhCQUFnQk8sR0FBaEIsQ0FBb0JLLElBQXBCO0FBQ0E7QUFDRDtBQUNGOztBQUVEQyxvQkFBVWpCLFdBQVdxQixHQUFYLENBQWVMLElBQWYsQ0FBVjs7QUFFQSxjQUFJLENBQUNDLE9BQUwsRUFBYztBQUNac0Ysb0JBQVFDLEtBQVIsbUJBQXdCeEYsSUFBeEI7QUFDRDs7QUFFRDtBQUNBLGNBQU1ELFlBQVlFLFFBQVFJLEdBQVIsQ0FBWS9DLHNCQUFaLENBQWxCO0FBQ0EsY0FBSSxPQUFPeUMsU0FBUCxLQUFxQixXQUFyQixJQUFvQ3NGLGtCQUFrQjVILHdCQUExRCxFQUFvRjtBQUNsRixnQkFBSXNDLFVBQVVrQixTQUFWLENBQW9CZ0UsSUFBcEIsR0FBMkIsQ0FBL0IsRUFBa0M7QUFDaEM7QUFDRDtBQUNGOztBQUVEO0FBQ0EsY0FBTUQsbUJBQW1CL0UsUUFBUUksR0FBUixDQUFZN0MsMEJBQVosQ0FBekI7QUFDQSxjQUFJLE9BQU93SCxnQkFBUCxLQUE0QixXQUFoQyxFQUE2QztBQUMzQyxnQkFBSUEsaUJBQWlCL0QsU0FBakIsQ0FBMkJnRSxJQUEzQixHQUFrQyxDQUF0QyxFQUF5QztBQUN2QztBQUNEO0FBQ0Y7O0FBRUQ7QUFDQSxjQUFNUSxhQUFhSixrQkFBa0JsSCxPQUFsQixHQUE0QlYsd0JBQTVCLEdBQXVENEgsYUFBMUU7O0FBRUEsY0FBTXJELGtCQUFrQi9CLFFBQVFJLEdBQVIsQ0FBWW9GLFVBQVosQ0FBeEI7O0FBRUEsY0FBTTFFLFFBQVEwRSxlQUFlaEksd0JBQWYsR0FBMENVLE9BQTFDLEdBQW9Ec0gsVUFBbEU7O0FBRUEsY0FBSSxPQUFPekQsZUFBUCxLQUEyQixXQUEvQixFQUE0QztBQUMxQyxnQkFBSUEsZ0JBQWdCZixTQUFoQixDQUEwQmdFLElBQTFCLEdBQWlDLENBQXJDLEVBQXdDO0FBQ3RDOUgsc0JBQVErSCxNQUFSO0FBQ0VKLGtCQURGO0FBRTJCL0QsbUJBRjNCOztBQUlEO0FBQ0YsV0FQRCxNQU9PO0FBQ0w1RCxvQkFBUStILE1BQVI7QUFDRUosZ0JBREY7QUFFMkIvRCxpQkFGM0I7O0FBSUQ7QUFDRixTQXhFSyxxQkFBTjs7QUEwRUE7Ozs7O0FBS0EsVUFBTTJFLGlDQUFvQixTQUFwQkEsaUJBQW9CLENBQUNaLElBQUQsRUFBVTtBQUNsQyxjQUFJNUYsYUFBYXVDLEdBQWIsQ0FBaUJ6QixJQUFqQixDQUFKLEVBQTRCO0FBQzFCO0FBQ0Q7O0FBRUQsY0FBSUMsVUFBVWpCLFdBQVdxQixHQUFYLENBQWVMLElBQWYsQ0FBZDs7QUFFQTtBQUNBO0FBQ0EsY0FBSSxPQUFPQyxPQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDQSxzQkFBVSxJQUFJbEIsR0FBSixFQUFWO0FBQ0Q7O0FBRUQsY0FBTTRHLGFBQWEsSUFBSTVHLEdBQUosRUFBbkI7QUFDQSxjQUFNNkcsdUJBQXVCLElBQUl6RyxHQUFKLEVBQTdCOztBQUVBMkYsZUFBS0ssSUFBTCxDQUFVdkcsT0FBVixDQUFrQixrQkFBdUMsS0FBcENKLElBQW9DLFVBQXBDQSxJQUFvQyxDQUE5QkgsV0FBOEIsVUFBOUJBLFdBQThCLENBQWpCdUUsVUFBaUIsVUFBakJBLFVBQWlCO0FBQ3ZELGdCQUFJcEUsU0FBU3BCLDBCQUFiLEVBQXlDO0FBQ3ZDd0ksbUNBQXFCakcsR0FBckIsQ0FBeUJsQyx3QkFBekI7QUFDRDtBQUNELGdCQUFJZSxTQUFTbkIsd0JBQWIsRUFBdUM7QUFDckMsa0JBQUl1RixXQUFXMUYsTUFBWCxHQUFvQixDQUF4QixFQUEyQjtBQUN6QjBGLDJCQUFXaEUsT0FBWCxDQUFtQixVQUFDNEMsU0FBRCxFQUFlO0FBQ2hDLHNCQUFJQSxVQUFVcUUsUUFBZCxFQUF3QjtBQUN0QkQseUNBQXFCakcsR0FBckIsQ0FBeUI2QixVQUFVcUUsUUFBVixDQUFtQm5ILElBQW5CLElBQTJCOEMsVUFBVXFFLFFBQVYsQ0FBbUI5RSxLQUF2RTtBQUNEO0FBQ0YsaUJBSkQ7QUFLRDtBQUNEM0MsMkNBQTZCQyxXQUE3QixFQUEwQyxVQUFDSyxJQUFELEVBQVU7QUFDbERrSCxxQ0FBcUJqRyxHQUFyQixDQUF5QmpCLElBQXpCO0FBQ0QsZUFGRDtBQUdEO0FBQ0YsV0FoQkQ7O0FBa0JBO0FBQ0F1QixrQkFBUXJCLE9BQVIsQ0FBZ0IsVUFBQ21DLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUM5QixnQkFBSTRFLHFCQUFxQm5FLEdBQXJCLENBQXlCVCxHQUF6QixDQUFKLEVBQW1DO0FBQ2pDMkUseUJBQVdoRixHQUFYLENBQWVLLEdBQWYsRUFBb0JELEtBQXBCO0FBQ0Q7QUFDRixXQUpEOztBQU1BO0FBQ0E2RSwrQkFBcUJoSCxPQUFyQixDQUE2QixVQUFDb0MsR0FBRCxFQUFTO0FBQ3BDLGdCQUFJLENBQUNmLFFBQVF3QixHQUFSLENBQVlULEdBQVosQ0FBTCxFQUF1QjtBQUNyQjJFLHlCQUFXaEYsR0FBWCxDQUFlSyxHQUFmLEVBQW9CLEVBQUVDLFdBQVcsSUFBSTlCLEdBQUosRUFBYixFQUFwQjtBQUNEO0FBQ0YsV0FKRDs7QUFNQTtBQUNBLGNBQU1ZLFlBQVlFLFFBQVFJLEdBQVIsQ0FBWS9DLHNCQUFaLENBQWxCO0FBQ0EsY0FBSTBILG1CQUFtQi9FLFFBQVFJLEdBQVIsQ0FBWTdDLDBCQUFaLENBQXZCOztBQUVBLGNBQUksT0FBT3dILGdCQUFQLEtBQTRCLFdBQWhDLEVBQTZDO0FBQzNDQSwrQkFBbUIsRUFBRS9ELFdBQVcsSUFBSTlCLEdBQUosRUFBYixFQUFuQjtBQUNEOztBQUVEd0cscUJBQVdoRixHQUFYLENBQWVyRCxzQkFBZixFQUF1Q3lDLFNBQXZDO0FBQ0E0RixxQkFBV2hGLEdBQVgsQ0FBZW5ELDBCQUFmLEVBQTJDd0gsZ0JBQTNDO0FBQ0FoRyxxQkFBVzJCLEdBQVgsQ0FBZVgsSUFBZixFQUFxQjJGLFVBQXJCO0FBQ0QsU0EzREssNEJBQU47O0FBNkRBOzs7OztBQUtBLFVBQU1HLGlDQUFvQixTQUFwQkEsaUJBQW9CLENBQUNoQixJQUFELEVBQVU7QUFDbEMsY0FBSSxDQUFDUixhQUFMLEVBQW9CO0FBQ2xCO0FBQ0Q7O0FBRUQsY0FBSXlCLGlCQUFpQmpILFdBQVd1QixHQUFYLENBQWVMLElBQWYsQ0FBckI7QUFDQSxjQUFJLE9BQU8rRixjQUFQLEtBQTBCLFdBQTlCLEVBQTJDO0FBQ3pDQSw2QkFBaUIsSUFBSWhILEdBQUosRUFBakI7QUFDRDs7QUFFRCxjQUFNaUgsc0JBQXNCLElBQUk3RyxHQUFKLEVBQTVCO0FBQ0EsY0FBTThHLHNCQUFzQixJQUFJOUcsR0FBSixFQUE1Qjs7QUFFQSxjQUFNK0csZUFBZSxJQUFJL0csR0FBSixFQUFyQjtBQUNBLGNBQU1nSCxlQUFlLElBQUloSCxHQUFKLEVBQXJCOztBQUVBLGNBQU1pSCxvQkFBb0IsSUFBSWpILEdBQUosRUFBMUI7QUFDQSxjQUFNa0gsb0JBQW9CLElBQUlsSCxHQUFKLEVBQTFCOztBQUVBLGNBQU1tSCxhQUFhLElBQUl2SCxHQUFKLEVBQW5CO0FBQ0EsY0FBTXdILGFBQWEsSUFBSXhILEdBQUosRUFBbkI7QUFDQWdILHlCQUFlbkgsT0FBZixDQUF1QixVQUFDbUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ3JDLGdCQUFJRCxNQUFNVSxHQUFOLENBQVVuRSxzQkFBVixDQUFKLEVBQXVDO0FBQ3JDNEksMkJBQWF2RyxHQUFiLENBQWlCcUIsR0FBakI7QUFDRDtBQUNELGdCQUFJRCxNQUFNVSxHQUFOLENBQVVqRSwwQkFBVixDQUFKLEVBQTJDO0FBQ3pDd0ksa0NBQW9CckcsR0FBcEIsQ0FBd0JxQixHQUF4QjtBQUNEO0FBQ0QsZ0JBQUlELE1BQU1VLEdBQU4sQ0FBVWhFLHdCQUFWLENBQUosRUFBeUM7QUFDdkMySSxnQ0FBa0J6RyxHQUFsQixDQUFzQnFCLEdBQXRCO0FBQ0Q7QUFDREQsa0JBQU1uQyxPQUFOLENBQWMsVUFBQzhDLEdBQUQsRUFBUztBQUNyQjtBQUNFQSxzQkFBUWxFLDBCQUFSO0FBQ0drRSxzQkFBUWpFLHdCQUZiO0FBR0U7QUFDQTZJLDJCQUFXM0YsR0FBWCxDQUFlZSxHQUFmLEVBQW9CVixHQUFwQjtBQUNEO0FBQ0YsYUFQRDtBQVFELFdBbEJEOztBQW9CQSxtQkFBU3dGLG9CQUFULENBQThCQyxNQUE5QixFQUFzQztBQUNwQyxnQkFBSUEsT0FBT2pJLElBQVAsS0FBZ0IsU0FBcEIsRUFBK0I7QUFDN0IscUJBQU8sSUFBUDtBQUNEO0FBQ0QsZ0JBQU1rSSxJQUFJLDBCQUFRRCxPQUFPMUYsS0FBZixFQUFzQjVELE9BQXRCLENBQVY7QUFDQSxnQkFBSXVKLEtBQUssSUFBVCxFQUFlO0FBQ2IscUJBQU8sSUFBUDtBQUNEO0FBQ0RULGdDQUFvQnRHLEdBQXBCLENBQXdCK0csQ0FBeEI7QUFDRDs7QUFFRCxrQ0FBTTVCLElBQU4sRUFBWTdGLGNBQWNvQixHQUFkLENBQWtCTCxJQUFsQixDQUFaLEVBQXFDO0FBQ25DMkcsNEJBRG1DLHlDQUNsQkMsS0FEa0IsRUFDWDtBQUN0QkoscUNBQXFCSSxNQUFNSCxNQUEzQjtBQUNELGVBSGtDO0FBSW5DSSwwQkFKbUMsdUNBSXBCRCxLQUpvQixFQUliO0FBQ3BCLG9CQUFJQSxNQUFNRSxNQUFOLENBQWF0SSxJQUFiLEtBQXNCLFFBQTFCLEVBQW9DO0FBQ2xDZ0ksdUNBQXFCSSxNQUFNRyxTQUFOLENBQWdCLENBQWhCLENBQXJCO0FBQ0Q7QUFDRixlQVJrQywyQkFBckM7OztBQVdBakMsZUFBS0ssSUFBTCxDQUFVdkcsT0FBVixDQUFrQixVQUFDb0ksT0FBRCxFQUFhO0FBQzdCLGdCQUFJQyxxQkFBSjs7QUFFQTtBQUNBLGdCQUFJRCxRQUFReEksSUFBUixLQUFpQm5CLHdCQUFyQixFQUErQztBQUM3QyxrQkFBSTJKLFFBQVFQLE1BQVosRUFBb0I7QUFDbEJRLCtCQUFlLDBCQUFRRCxRQUFRUCxNQUFSLENBQWVTLEdBQWYsQ0FBbUJDLE9BQW5CLENBQTJCLFFBQTNCLEVBQXFDLEVBQXJDLENBQVIsRUFBa0RoSyxPQUFsRCxDQUFmO0FBQ0E2Six3QkFBUXBFLFVBQVIsQ0FBbUJoRSxPQUFuQixDQUEyQixVQUFDNEMsU0FBRCxFQUFlO0FBQ3hDLHNCQUFNOUMsT0FBTzhDLFVBQVVGLEtBQVYsQ0FBZ0I1QyxJQUFoQixJQUF3QjhDLFVBQVVGLEtBQVYsQ0FBZ0JQLEtBQXJEO0FBQ0Esc0JBQUlyQyxTQUFTUCxPQUFiLEVBQXNCO0FBQ3BCa0ksc0NBQWtCMUcsR0FBbEIsQ0FBc0JzSCxZQUF0QjtBQUNELG1CQUZELE1BRU87QUFDTFYsK0JBQVc1RixHQUFYLENBQWVqQyxJQUFmLEVBQXFCdUksWUFBckI7QUFDRDtBQUNGLGlCQVBEO0FBUUQ7QUFDRjs7QUFFRCxnQkFBSUQsUUFBUXhJLElBQVIsS0FBaUJsQixzQkFBckIsRUFBNkM7QUFDM0MySiw2QkFBZSwwQkFBUUQsUUFBUVAsTUFBUixDQUFlUyxHQUFmLENBQW1CQyxPQUFuQixDQUEyQixRQUEzQixFQUFxQyxFQUFyQyxDQUFSLEVBQWtEaEssT0FBbEQsQ0FBZjtBQUNBZ0osMkJBQWF4RyxHQUFiLENBQWlCc0gsWUFBakI7QUFDRDs7QUFFRCxnQkFBSUQsUUFBUXhJLElBQVIsS0FBaUJqQixrQkFBckIsRUFBeUM7QUFDdkMwSiw2QkFBZSwwQkFBUUQsUUFBUVAsTUFBUixDQUFlUyxHQUFmLENBQW1CQyxPQUFuQixDQUEyQixRQUEzQixFQUFxQyxFQUFyQyxDQUFSLEVBQWtEaEssT0FBbEQsQ0FBZjtBQUNBLGtCQUFJLENBQUM4SixZQUFMLEVBQW1CO0FBQ2pCO0FBQ0Q7O0FBRUQsa0JBQUk1SCxhQUFhNEgsWUFBYixDQUFKLEVBQWdDO0FBQzlCO0FBQ0Q7O0FBRUQsa0JBQUl0RSx5QkFBeUJxRSxRQUFRcEUsVUFBakMsQ0FBSixFQUFrRDtBQUNoRHFELG9DQUFvQnRHLEdBQXBCLENBQXdCc0gsWUFBeEI7QUFDRDs7QUFFRCxrQkFBSW5FLHVCQUF1QmtFLFFBQVFwRSxVQUEvQixDQUFKLEVBQWdEO0FBQzlDeUQsa0NBQWtCMUcsR0FBbEIsQ0FBc0JzSCxZQUF0QjtBQUNEOztBQUVERCxzQkFBUXBFLFVBQVI7QUFDRzdGLG9CQURILENBQ1UsVUFBQ3lFLFNBQUQsVUFBZUEsVUFBVWhELElBQVYsS0FBbUJmLHdCQUFuQixJQUErQytELFVBQVVoRCxJQUFWLEtBQW1CaEIsMEJBQWpGLEVBRFY7QUFFR29CLHFCQUZILENBRVcsVUFBQzRDLFNBQUQsRUFBZTtBQUN0QitFLDJCQUFXNUYsR0FBWCxDQUFlYSxVQUFVNEYsUUFBVixDQUFtQjFJLElBQW5CLElBQTJCOEMsVUFBVTRGLFFBQVYsQ0FBbUJyRyxLQUE3RCxFQUFvRWtHLFlBQXBFO0FBQ0QsZUFKSDtBQUtEO0FBQ0YsV0EvQ0Q7O0FBaURBZCx1QkFBYXZILE9BQWIsQ0FBcUIsVUFBQ21DLEtBQUQsRUFBVztBQUM5QixnQkFBSSxDQUFDbUYsYUFBYXpFLEdBQWIsQ0FBaUJWLEtBQWpCLENBQUwsRUFBOEI7QUFDNUIsa0JBQUliLFVBQVU2RixlQUFlMUYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUlmLEdBQUosRUFBVjtBQUNEO0FBQ0RlLHNCQUFRUCxHQUFSLENBQVlyQyxzQkFBWjtBQUNBeUksNkJBQWVwRixHQUFmLENBQW1CSSxLQUFuQixFQUEwQmIsT0FBMUI7O0FBRUEsa0JBQUlELFdBQVVqQixXQUFXcUIsR0FBWCxDQUFlVSxLQUFmLENBQWQ7QUFDQSxrQkFBSVksc0JBQUo7QUFDQSxrQkFBSSxPQUFPMUIsUUFBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQzBCLGdDQUFnQjFCLFNBQVFJLEdBQVIsQ0FBWS9DLHNCQUFaLENBQWhCO0FBQ0QsZUFGRCxNQUVPO0FBQ0wyQywyQkFBVSxJQUFJbEIsR0FBSixFQUFWO0FBQ0FDLDJCQUFXMkIsR0FBWCxDQUFlSSxLQUFmLEVBQXNCZCxRQUF0QjtBQUNEOztBQUVELGtCQUFJLE9BQU8wQixhQUFQLEtBQXlCLFdBQTdCLEVBQTBDO0FBQ3hDQSw4QkFBY1YsU0FBZCxDQUF3QnRCLEdBQXhCLENBQTRCSyxJQUE1QjtBQUNELGVBRkQsTUFFTztBQUNMLG9CQUFNaUIsWUFBWSxJQUFJOUIsR0FBSixFQUFsQjtBQUNBOEIsMEJBQVV0QixHQUFWLENBQWNLLElBQWQ7QUFDQUMseUJBQVFVLEdBQVIsQ0FBWXJELHNCQUFaLEVBQW9DLEVBQUUyRCxvQkFBRixFQUFwQztBQUNEO0FBQ0Y7QUFDRixXQTFCRDs7QUE0QkFpRix1QkFBYXRILE9BQWIsQ0FBcUIsVUFBQ21DLEtBQUQsRUFBVztBQUM5QixnQkFBSSxDQUFDb0YsYUFBYTFFLEdBQWIsQ0FBaUJWLEtBQWpCLENBQUwsRUFBOEI7QUFDNUIsa0JBQU1iLFVBQVU2RixlQUFlMUYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBaEI7QUFDQWIsZ0NBQWU1QyxzQkFBZjs7QUFFQSxrQkFBTTJDLFlBQVVqQixXQUFXcUIsR0FBWCxDQUFlVSxLQUFmLENBQWhCO0FBQ0Esa0JBQUksT0FBT2QsU0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQyxvQkFBTTBCLGdCQUFnQjFCLFVBQVFJLEdBQVIsQ0FBWS9DLHNCQUFaLENBQXRCO0FBQ0Esb0JBQUksT0FBT3FFLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLGdDQUFjVixTQUFkLFdBQStCakIsSUFBL0I7QUFDRDtBQUNGO0FBQ0Y7QUFDRixXQWJEOztBQWVBcUcsNEJBQWtCekgsT0FBbEIsQ0FBMEIsVUFBQ21DLEtBQUQsRUFBVztBQUNuQyxnQkFBSSxDQUFDcUYsa0JBQWtCM0UsR0FBbEIsQ0FBc0JWLEtBQXRCLENBQUwsRUFBbUM7QUFDakMsa0JBQUliLFVBQVU2RixlQUFlMUYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUlmLEdBQUosRUFBVjtBQUNEO0FBQ0RlLHNCQUFRUCxHQUFSLENBQVlsQyx3QkFBWjtBQUNBc0ksNkJBQWVwRixHQUFmLENBQW1CSSxLQUFuQixFQUEwQmIsT0FBMUI7O0FBRUEsa0JBQUlELFlBQVVqQixXQUFXcUIsR0FBWCxDQUFlVSxLQUFmLENBQWQ7QUFDQSxrQkFBSVksc0JBQUo7QUFDQSxrQkFBSSxPQUFPMUIsU0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQzBCLGdDQUFnQjFCLFVBQVFJLEdBQVIsQ0FBWTVDLHdCQUFaLENBQWhCO0FBQ0QsZUFGRCxNQUVPO0FBQ0x3Qyw0QkFBVSxJQUFJbEIsR0FBSixFQUFWO0FBQ0FDLDJCQUFXMkIsR0FBWCxDQUFlSSxLQUFmLEVBQXNCZCxTQUF0QjtBQUNEOztBQUVELGtCQUFJLE9BQU8wQixhQUFQLEtBQXlCLFdBQTdCLEVBQTBDO0FBQ3hDQSw4QkFBY1YsU0FBZCxDQUF3QnRCLEdBQXhCLENBQTRCSyxJQUE1QjtBQUNELGVBRkQsTUFFTztBQUNMLG9CQUFNaUIsWUFBWSxJQUFJOUIsR0FBSixFQUFsQjtBQUNBOEIsMEJBQVV0QixHQUFWLENBQWNLLElBQWQ7QUFDQUMsMEJBQVFVLEdBQVIsQ0FBWWxELHdCQUFaLEVBQXNDLEVBQUV3RCxvQkFBRixFQUF0QztBQUNEO0FBQ0Y7QUFDRixXQTFCRDs7QUE0QkFtRiw0QkFBa0J4SCxPQUFsQixDQUEwQixVQUFDbUMsS0FBRCxFQUFXO0FBQ25DLGdCQUFJLENBQUNzRixrQkFBa0I1RSxHQUFsQixDQUFzQlYsS0FBdEIsQ0FBTCxFQUFtQztBQUNqQyxrQkFBTWIsVUFBVTZGLGVBQWUxRixHQUFmLENBQW1CVSxLQUFuQixDQUFoQjtBQUNBYixnQ0FBZXpDLHdCQUFmOztBQUVBLGtCQUFNd0MsWUFBVWpCLFdBQVdxQixHQUFYLENBQWVVLEtBQWYsQ0FBaEI7QUFDQSxrQkFBSSxPQUFPZCxTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDLG9CQUFNMEIsZ0JBQWdCMUIsVUFBUUksR0FBUixDQUFZNUMsd0JBQVosQ0FBdEI7QUFDQSxvQkFBSSxPQUFPa0UsYUFBUCxLQUF5QixXQUE3QixFQUEwQztBQUN4Q0EsZ0NBQWNWLFNBQWQsV0FBK0JqQixJQUEvQjtBQUNEO0FBQ0Y7QUFDRjtBQUNGLFdBYkQ7O0FBZUFpRyw4QkFBb0JySCxPQUFwQixDQUE0QixVQUFDbUMsS0FBRCxFQUFXO0FBQ3JDLGdCQUFJLENBQUNpRixvQkFBb0J2RSxHQUFwQixDQUF3QlYsS0FBeEIsQ0FBTCxFQUFxQztBQUNuQyxrQkFBSWIsVUFBVTZGLGVBQWUxRixHQUFmLENBQW1CVSxLQUFuQixDQUFkO0FBQ0Esa0JBQUksT0FBT2IsT0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQ0EsMEJBQVUsSUFBSWYsR0FBSixFQUFWO0FBQ0Q7QUFDRGUsc0JBQVFQLEdBQVIsQ0FBWW5DLDBCQUFaO0FBQ0F1SSw2QkFBZXBGLEdBQWYsQ0FBbUJJLEtBQW5CLEVBQTBCYixPQUExQjs7QUFFQSxrQkFBSUQsWUFBVWpCLFdBQVdxQixHQUFYLENBQWVVLEtBQWYsQ0FBZDtBQUNBLGtCQUFJWSxzQkFBSjtBQUNBLGtCQUFJLE9BQU8xQixTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDMEIsZ0NBQWdCMUIsVUFBUUksR0FBUixDQUFZN0MsMEJBQVosQ0FBaEI7QUFDRCxlQUZELE1BRU87QUFDTHlDLDRCQUFVLElBQUlsQixHQUFKLEVBQVY7QUFDQUMsMkJBQVcyQixHQUFYLENBQWVJLEtBQWYsRUFBc0JkLFNBQXRCO0FBQ0Q7O0FBRUQsa0JBQUksT0FBTzBCLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLDhCQUFjVixTQUFkLENBQXdCdEIsR0FBeEIsQ0FBNEJLLElBQTVCO0FBQ0QsZUFGRCxNQUVPO0FBQ0wsb0JBQU1pQixZQUFZLElBQUk5QixHQUFKLEVBQWxCO0FBQ0E4QiwwQkFBVXRCLEdBQVYsQ0FBY0ssSUFBZDtBQUNBQywwQkFBUVUsR0FBUixDQUFZbkQsMEJBQVosRUFBd0MsRUFBRXlELG9CQUFGLEVBQXhDO0FBQ0Q7QUFDRjtBQUNGLFdBMUJEOztBQTRCQStFLDhCQUFvQnBILE9BQXBCLENBQTRCLFVBQUNtQyxLQUFELEVBQVc7QUFDckMsZ0JBQUksQ0FBQ2tGLG9CQUFvQnhFLEdBQXBCLENBQXdCVixLQUF4QixDQUFMLEVBQXFDO0FBQ25DLGtCQUFNYixVQUFVNkYsZUFBZTFGLEdBQWYsQ0FBbUJVLEtBQW5CLENBQWhCO0FBQ0FiLGdDQUFlMUMsMEJBQWY7O0FBRUEsa0JBQU15QyxZQUFVakIsV0FBV3FCLEdBQVgsQ0FBZVUsS0FBZixDQUFoQjtBQUNBLGtCQUFJLE9BQU9kLFNBQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbEMsb0JBQU0wQixnQkFBZ0IxQixVQUFRSSxHQUFSLENBQVk3QywwQkFBWixDQUF0QjtBQUNBLG9CQUFJLE9BQU9tRSxhQUFQLEtBQXlCLFdBQTdCLEVBQTBDO0FBQ3hDQSxnQ0FBY1YsU0FBZCxXQUErQmpCLElBQS9CO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsV0FiRDs7QUFlQXVHLHFCQUFXM0gsT0FBWCxDQUFtQixVQUFDbUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2pDLGdCQUFJLENBQUNzRixXQUFXN0UsR0FBWCxDQUFlVCxHQUFmLENBQUwsRUFBMEI7QUFDeEIsa0JBQUlkLFVBQVU2RixlQUFlMUYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUlmLEdBQUosRUFBVjtBQUNEO0FBQ0RlLHNCQUFRUCxHQUFSLENBQVlxQixHQUFaO0FBQ0ErRSw2QkFBZXBGLEdBQWYsQ0FBbUJJLEtBQW5CLEVBQTBCYixPQUExQjs7QUFFQSxrQkFBSUQsWUFBVWpCLFdBQVdxQixHQUFYLENBQWVVLEtBQWYsQ0FBZDtBQUNBLGtCQUFJWSxzQkFBSjtBQUNBLGtCQUFJLE9BQU8xQixTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDMEIsZ0NBQWdCMUIsVUFBUUksR0FBUixDQUFZVyxHQUFaLENBQWhCO0FBQ0QsZUFGRCxNQUVPO0FBQ0xmLDRCQUFVLElBQUlsQixHQUFKLEVBQVY7QUFDQUMsMkJBQVcyQixHQUFYLENBQWVJLEtBQWYsRUFBc0JkLFNBQXRCO0FBQ0Q7O0FBRUQsa0JBQUksT0FBTzBCLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLDhCQUFjVixTQUFkLENBQXdCdEIsR0FBeEIsQ0FBNEJLLElBQTVCO0FBQ0QsZUFGRCxNQUVPO0FBQ0wsb0JBQU1pQixZQUFZLElBQUk5QixHQUFKLEVBQWxCO0FBQ0E4QiwwQkFBVXRCLEdBQVYsQ0FBY0ssSUFBZDtBQUNBQywwQkFBUVUsR0FBUixDQUFZSyxHQUFaLEVBQWlCLEVBQUVDLG9CQUFGLEVBQWpCO0FBQ0Q7QUFDRjtBQUNGLFdBMUJEOztBQTRCQXFGLHFCQUFXMUgsT0FBWCxDQUFtQixVQUFDbUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2pDLGdCQUFJLENBQUN1RixXQUFXOUUsR0FBWCxDQUFlVCxHQUFmLENBQUwsRUFBMEI7QUFDeEIsa0JBQU1kLFVBQVU2RixlQUFlMUYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBaEI7QUFDQWIsZ0NBQWVjLEdBQWY7O0FBRUEsa0JBQU1mLFlBQVVqQixXQUFXcUIsR0FBWCxDQUFlVSxLQUFmLENBQWhCO0FBQ0Esa0JBQUksT0FBT2QsU0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQyxvQkFBTTBCLGdCQUFnQjFCLFVBQVFJLEdBQVIsQ0FBWVcsR0FBWixDQUF0QjtBQUNBLG9CQUFJLE9BQU9XLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLGdDQUFjVixTQUFkLFdBQStCakIsSUFBL0I7QUFDRDtBQUNGO0FBQ0Y7QUFDRixXQWJEO0FBY0QsU0EzUkssNEJBQU47O0FBNlJBLGFBQU87QUFDTCxzQkFESyxvQ0FDVThFLElBRFYsRUFDZ0I7QUFDbkJZLDhCQUFrQlosSUFBbEI7QUFDQWdCLDhCQUFrQmhCLElBQWxCO0FBQ0FELGdDQUFvQkMsSUFBcEI7QUFDRCxXQUxJO0FBTUx1QyxnQ0FOSyxpREFNb0J2QyxJQU5wQixFQU0wQjtBQUM3Qk0sdUJBQVdOLElBQVgsRUFBaUJySCx3QkFBakIsRUFBMkMsS0FBM0M7QUFDRCxXQVJJO0FBU0w2Siw4QkFUSywrQ0FTa0J4QyxJQVRsQixFQVN3QjtBQUMzQkEsaUJBQUtsQyxVQUFMLENBQWdCaEUsT0FBaEIsQ0FBd0IsVUFBQzRDLFNBQUQsRUFBZTtBQUNyQzRELHlCQUFXNUQsU0FBWCxFQUFzQkEsVUFBVXFFLFFBQVYsQ0FBbUJuSCxJQUFuQixJQUEyQjhDLFVBQVVxRSxRQUFWLENBQW1COUUsS0FBcEUsRUFBMkUsS0FBM0U7QUFDRCxhQUZEO0FBR0EzQyx5Q0FBNkIwRyxLQUFLekcsV0FBbEMsRUFBK0MsVUFBQ0ssSUFBRCxFQUFPNEcsWUFBUCxFQUF3QjtBQUNyRUYseUJBQVdOLElBQVgsRUFBaUJwRyxJQUFqQixFQUF1QjRHLFlBQXZCO0FBQ0QsYUFGRDtBQUdELFdBaEJJLG1DQUFQOztBQWtCRCxLQXBpQmMsbUJBQWpCIiwiZmlsZSI6Im5vLXVudXNlZC1tb2R1bGVzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IEVuc3VyZXMgdGhhdCBtb2R1bGVzIGNvbnRhaW4gZXhwb3J0cyBhbmQvb3IgYWxsXG4gKiBtb2R1bGVzIGFyZSBjb25zdW1lZCB3aXRoaW4gb3RoZXIgbW9kdWxlcy5cbiAqIEBhdXRob3IgUmVuw6kgRmVybWFublxuICovXG5cbmltcG9ydCB7IGdldFBoeXNpY2FsRmlsZW5hbWUgfSBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL2NvbnRleHRDb21wYXQnO1xuaW1wb3J0IHsgZ2V0RmlsZUV4dGVuc2lvbnMgfSBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL2lnbm9yZSc7XG5pbXBvcnQgcmVzb2x2ZSBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL3Jlc29sdmUnO1xuaW1wb3J0IHZpc2l0IGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvdmlzaXQnO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiwgcmVzb2x2ZSBhcyByZXNvbHZlUGF0aCB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHJlYWRQa2dVcCBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL3JlYWRQa2dVcCc7XG5pbXBvcnQgdmFsdWVzIGZyb20gJ29iamVjdC52YWx1ZXMnO1xuaW1wb3J0IGluY2x1ZGVzIGZyb20gJ2FycmF5LWluY2x1ZGVzJztcbmltcG9ydCBmbGF0TWFwIGZyb20gJ2FycmF5LnByb3RvdHlwZS5mbGF0bWFwJztcblxuaW1wb3J0IHsgd2Fsa1N5bmMgfSBmcm9tICcuLi9jb3JlL2ZzV2Fsayc7XG5pbXBvcnQgRXhwb3J0TWFwQnVpbGRlciBmcm9tICcuLi9leHBvcnRNYXAvYnVpbGRlcic7XG5pbXBvcnQgcmVjdXJzaXZlUGF0dGVybkNhcHR1cmUgZnJvbSAnLi4vZXhwb3J0TWFwL3BhdHRlcm5DYXB0dXJlJztcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnO1xuXG4vKipcbiAqIEF0dGVtcHQgdG8gbG9hZCB0aGUgaW50ZXJuYWwgYEZpbGVFbnVtZXJhdG9yYCBjbGFzcywgd2hpY2ggaGFzIGV4aXN0ZWQgaW4gYSBjb3VwbGVcbiAqIG9mIGRpZmZlcmVudCBwbGFjZXMsIGRlcGVuZGluZyBvbiB0aGUgdmVyc2lvbiBvZiBgZXNsaW50YC4gIFRyeSByZXF1aXJpbmcgaXQgZnJvbSBib3RoXG4gKiBsb2NhdGlvbnMuXG4gKiBAcmV0dXJucyBSZXR1cm5zIHRoZSBgRmlsZUVudW1lcmF0b3JgIGNsYXNzIGlmIGl0cyByZXF1aXJhYmxlLCBvdGhlcndpc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIHJlcXVpcmVGaWxlRW51bWVyYXRvcigpIHtcbiAgbGV0IEZpbGVFbnVtZXJhdG9yO1xuXG4gIC8vIFRyeSBnZXR0aW5nIGl0IGZyb20gdGhlIGVzbGludCBwcml2YXRlIC8gZGVwcmVjYXRlZCBhcGlcbiAgdHJ5IHtcbiAgICAoeyBGaWxlRW51bWVyYXRvciB9ID0gcmVxdWlyZSgnZXNsaW50L3VzZS1hdC15b3VyLW93bi1yaXNrJykpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gQWJzb3JiIHRoaXMgaWYgaXQncyBNT0RVTEVfTk9UX0ZPVU5EXG4gICAgaWYgKGUuY29kZSAhPT0gJ01PRFVMRV9OT1RfRk9VTkQnKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIC8vIElmIG5vdCB0aGVyZSwgdGhlbiB0cnkgZ2V0dGluZyBpdCBmcm9tIGVzbGludC9saWIvY2xpLWVuZ2luZS9maWxlLWVudW1lcmF0b3IgKG1vdmVkIHRoZXJlIGluIHY2KVxuICAgIHRyeSB7XG4gICAgICAoeyBGaWxlRW51bWVyYXRvciB9ID0gcmVxdWlyZSgnZXNsaW50L2xpYi9jbGktZW5naW5lL2ZpbGUtZW51bWVyYXRvcicpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBBYnNvcmIgdGhpcyBpZiBpdCdzIE1PRFVMRV9OT1RfRk9VTkRcbiAgICAgIGlmIChlLmNvZGUgIT09ICdNT0RVTEVfTk9UX0ZPVU5EJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gRmlsZUVudW1lcmF0b3I7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBGaWxlRW51bWVyYXRvciB0aGUgYEZpbGVFbnVtZXJhdG9yYCBjbGFzcyBmcm9tIGBlc2xpbnRgJ3MgaW50ZXJuYWwgYXBpXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjIHBhdGggdG8gdGhlIHNyYyByb290XG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBleHRlbnNpb25zIGxpc3Qgb2Ygc3VwcG9ydGVkIGV4dGVuc2lvbnNcbiAqIEByZXR1cm5zIHt7IGZpbGVuYW1lOiBzdHJpbmcsIGlnbm9yZWQ6IGJvb2xlYW4gfVtdfSBsaXN0IG9mIGZpbGVzIHRvIG9wZXJhdGUgb25cbiAqL1xuZnVuY3Rpb24gbGlzdEZpbGVzVXNpbmdGaWxlRW51bWVyYXRvcihGaWxlRW51bWVyYXRvciwgc3JjLCBleHRlbnNpb25zKSB7XG4gIGNvbnN0IGUgPSBuZXcgRmlsZUVudW1lcmF0b3Ioe1xuICAgIGV4dGVuc2lvbnMsXG4gIH0pO1xuXG4gIHJldHVybiBBcnJheS5mcm9tKFxuICAgIGUuaXRlcmF0ZUZpbGVzKHNyYyksXG4gICAgKHsgZmlsZVBhdGgsIGlnbm9yZWQgfSkgPT4gKHsgZmlsZW5hbWU6IGZpbGVQYXRoLCBpZ25vcmVkIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEF0dGVtcHQgdG8gcmVxdWlyZSBvbGQgdmVyc2lvbnMgb2YgdGhlIGZpbGUgZW51bWVyYXRpb24gY2FwYWJpbGl0eSBmcm9tIHY2IGBlc2xpbnRgIGFuZCBlYXJsaWVyLCBhbmQgdXNlXG4gKiB0aG9zZSBmdW5jdGlvbnMgdG8gcHJvdmlkZSB0aGUgbGlzdCBvZiBmaWxlcyB0byBvcGVyYXRlIG9uXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjIHBhdGggdG8gdGhlIHNyYyByb290XG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBleHRlbnNpb25zIGxpc3Qgb2Ygc3VwcG9ydGVkIGV4dGVuc2lvbnNcbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gbGlzdCBvZiBmaWxlcyB0byBvcGVyYXRlIG9uXG4gKi9cbmZ1bmN0aW9uIGxpc3RGaWxlc1dpdGhMZWdhY3lGdW5jdGlvbnMoc3JjLCBleHRlbnNpb25zKSB7XG4gIHRyeSB7XG4gICAgLy8gZXNsaW50L2xpYi91dGlsL2dsb2ItdXRpbCBoYXMgYmVlbiBtb3ZlZCB0byBlc2xpbnQvbGliL3V0aWwvZ2xvYi11dGlscyB3aXRoIHZlcnNpb24gNS4zXG4gICAgY29uc3QgeyBsaXN0RmlsZXNUb1Byb2Nlc3M6IG9yaWdpbmFsTGlzdEZpbGVzVG9Qcm9jZXNzIH0gPSByZXF1aXJlKCdlc2xpbnQvbGliL3V0aWwvZ2xvYi11dGlscycpO1xuICAgIC8vIFByZXZlbnQgcGFzc2luZyBpbnZhbGlkIG9wdGlvbnMgKGV4dGVuc2lvbnMgYXJyYXkpIHRvIG9sZCB2ZXJzaW9ucyBvZiB0aGUgZnVuY3Rpb24uXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2VzbGludC9lc2xpbnQvYmxvYi92NS4xNi4wL2xpYi91dGlsL2dsb2ItdXRpbHMuanMjTDE3OC1MMjgwXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2VzbGludC9lc2xpbnQvYmxvYi92NS4yLjAvbGliL3V0aWwvZ2xvYi11dGlsLmpzI0wxNzQtTDI2OVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsTGlzdEZpbGVzVG9Qcm9jZXNzKHNyYywge1xuICAgICAgZXh0ZW5zaW9ucyxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIEFic29yYiB0aGlzIGlmIGl0J3MgTU9EVUxFX05PVF9GT1VORFxuICAgIGlmIChlLmNvZGUgIT09ICdNT0RVTEVfTk9UX0ZPVU5EJykge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICAvLyBMYXN0IHBsYWNlIHRvIHRyeSAocHJlIHY1LjMpXG4gICAgY29uc3Qge1xuICAgICAgbGlzdEZpbGVzVG9Qcm9jZXNzOiBvcmlnaW5hbExpc3RGaWxlc1RvUHJvY2VzcyxcbiAgICB9ID0gcmVxdWlyZSgnZXNsaW50L2xpYi91dGlsL2dsb2ItdXRpbCcpO1xuICAgIGNvbnN0IHBhdHRlcm5zID0gc3JjLmNvbmNhdChcbiAgICAgIGZsYXRNYXAoXG4gICAgICAgIHNyYyxcbiAgICAgICAgKHBhdHRlcm4pID0+IGV4dGVuc2lvbnMubWFwKChleHRlbnNpb24pID0+ICgvXFwqXFwqfFxcKlxcLi8pLnRlc3QocGF0dGVybikgPyBwYXR0ZXJuIDogYCR7cGF0dGVybn0vKiovKiR7ZXh0ZW5zaW9ufWApLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcmV0dXJuIG9yaWdpbmFsTGlzdEZpbGVzVG9Qcm9jZXNzKHBhdHRlcm5zKTtcbiAgfVxufVxuXG4vKipcbiAqIEdpdmVuIGEgc291cmNlIHJvb3QgYW5kIGxpc3Qgb2Ygc3VwcG9ydGVkIGV4dGVuc2lvbnMsIHVzZSBmc1dhbGsgYW5kIHRoZVxuICogbmV3IGBlc2xpbnRgIGBjb250ZXh0LnNlc3Npb25gIGFwaSB0byBidWlsZCB0aGUgbGlzdCBvZiBmaWxlcyB3ZSB3YW50IHRvIG9wZXJhdGUgb25cbiAqIEBwYXJhbSB7c3RyaW5nW119IHNyY1BhdGhzIGFycmF5IG9mIHNvdXJjZSBwYXRocyAoZm9yIGZsYXQgY29uZmlnIHRoaXMgc2hvdWxkIGp1c3QgYmUgYSBzaW5ndWxhciByb290IChlLmcuIGN3ZCkpXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBleHRlbnNpb25zIGxpc3Qgb2Ygc3VwcG9ydGVkIGV4dGVuc2lvbnNcbiAqIEBwYXJhbSB7eyBpc0RpcmVjdG9yeUlnbm9yZWQ6IChwYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4sIGlzRmlsZUlnbm9yZWQ6IChwYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4gfX0gc2Vzc2lvbiBlc2xpbnQgY29udGV4dCBzZXNzaW9uIG9iamVjdFxuICogQHJldHVybnMge3N0cmluZ1tdfSBsaXN0IG9mIGZpbGVzIHRvIG9wZXJhdGUgb25cbiAqL1xuZnVuY3Rpb24gbGlzdEZpbGVzV2l0aE1vZGVybkFwaShzcmNQYXRocywgZXh0ZW5zaW9ucywgc2Vzc2lvbikge1xuICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCBmaWxlcyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3JjUGF0aHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzcmMgPSBzcmNQYXRoc1tpXTtcbiAgICAvLyBVc2Ugd2Fsa1N5bmMgYWxvbmcgd2l0aCB0aGUgbmV3IHNlc3Npb24gYXBpIHRvIGdhdGhlciB0aGUgbGlzdCBvZiBmaWxlc1xuICAgIGNvbnN0IGVudHJpZXMgPSB3YWxrU3luYyhzcmMsIHtcbiAgICAgIGRlZXBGaWx0ZXIoZW50cnkpIHtcbiAgICAgICAgY29uc3QgZnVsbEVudHJ5UGF0aCA9IHJlc29sdmVQYXRoKHNyYywgZW50cnkucGF0aCk7XG5cbiAgICAgICAgLy8gSW5jbHVkZSB0aGUgZGlyZWN0b3J5IGlmIGl0J3Mgbm90IG1hcmtlZCBhcyBpZ25vcmUgYnkgZXNsaW50XG4gICAgICAgIHJldHVybiAhc2Vzc2lvbi5pc0RpcmVjdG9yeUlnbm9yZWQoZnVsbEVudHJ5UGF0aCk7XG4gICAgICB9LFxuICAgICAgZW50cnlGaWx0ZXIoZW50cnkpIHtcbiAgICAgICAgY29uc3QgZnVsbEVudHJ5UGF0aCA9IHJlc29sdmVQYXRoKHNyYywgZW50cnkucGF0aCk7XG5cbiAgICAgICAgLy8gSW5jbHVkZSB0aGUgZmlsZSBpZiBpdCdzIG5vdCBtYXJrZWQgYXMgaWdub3JlIGJ5IGVzbGludCBhbmQgaXRzIGV4dGVuc2lvbiBpcyBpbmNsdWRlZCBpbiBvdXIgbGlzdFxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICFzZXNzaW9uLmlzRmlsZUlnbm9yZWQoZnVsbEVudHJ5UGF0aClcbiAgICAgICAgICAmJiBleHRlbnNpb25zLmZpbmQoKGV4dGVuc2lvbikgPT4gZW50cnkucGF0aC5lbmRzV2l0aChleHRlbnNpb24pKVxuICAgICAgICApO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIEZpbHRlciBvdXQgZGlyZWN0b3JpZXMgYW5kIG1hcCBlbnRyaWVzIHRvIHRoZWlyIHBhdGhzXG4gICAgZmlsZXMucHVzaChcbiAgICAgIC4uLmVudHJpZXNcbiAgICAgICAgLmZpbHRlcigoZW50cnkpID0+ICFlbnRyeS5kaXJlbnQuaXNEaXJlY3RvcnkoKSlcbiAgICAgICAgLm1hcCgoZW50cnkpID0+IGVudHJ5LnBhdGgpLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGZpbGVzO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgc3JjIHBhdHRlcm4gYW5kIGxpc3Qgb2Ygc3VwcG9ydGVkIGV4dGVuc2lvbnMsIHJldHVybiBhIGxpc3Qgb2YgZmlsZXMgdG8gcHJvY2Vzc1xuICogd2l0aCB0aGlzIHJ1bGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjIC0gZmlsZSwgZGlyZWN0b3J5LCBvciBnbG9iIHBhdHRlcm4gb2YgZmlsZXMgdG8gYWN0IG9uXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBleHRlbnNpb25zIC0gbGlzdCBvZiBzdXBwb3J0ZWQgZmlsZSBleHRlbnNpb25zXG4gKiBAcGFyYW0ge2ltcG9ydCgnZXNsaW50JykuUnVsZS5SdWxlQ29udGV4dH0gY29udGV4dCAtIHRoZSBlc2xpbnQgY29udGV4dCBvYmplY3RcbiAqIEByZXR1cm5zIHtzdHJpbmdbXSB8IHsgZmlsZW5hbWU6IHN0cmluZywgaWdub3JlZDogYm9vbGVhbiB9W119IHRoZSBsaXN0IG9mIGZpbGVzIHRoYXQgdGhpcyBydWxlIHdpbGwgZXZhbHVhdGUuXG4gKi9cbmZ1bmN0aW9uIGxpc3RGaWxlc1RvUHJvY2VzcyhzcmMsIGV4dGVuc2lvbnMsIGNvbnRleHQpIHtcbiAgLy8gSWYgdGhlIGNvbnRleHQgb2JqZWN0IGhhcyB0aGUgbmV3IHNlc3Npb24gZnVuY3Rpb25zLCB0aGVuIHByZWZlciB0aG9zZVxuICAvLyBPdGhlcndpc2UsIGZhbGxiYWNrIHRvIHVzaW5nIHRoZSBkZXByZWNhdGVkIGBGaWxlRW51bWVyYXRvcmAgZm9yIGxlZ2FjeSBzdXBwb3J0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZXNsaW50L2VzbGludC9pc3N1ZXMvMTgwODdcbiAgaWYgKFxuICAgIGNvbnRleHQuc2Vzc2lvblxuICAgICYmIGNvbnRleHQuc2Vzc2lvbi5pc0ZpbGVJZ25vcmVkXG4gICAgJiYgY29udGV4dC5zZXNzaW9uLmlzRGlyZWN0b3J5SWdub3JlZFxuICApIHtcbiAgICByZXR1cm4gbGlzdEZpbGVzV2l0aE1vZGVybkFwaShzcmMsIGV4dGVuc2lvbnMsIGNvbnRleHQuc2Vzc2lvbik7XG4gIH1cblxuICAvLyBGYWxsYmFjayB0byBvZyBGaWxlRW51bWVyYXRvclxuICBjb25zdCBGaWxlRW51bWVyYXRvciA9IHJlcXVpcmVGaWxlRW51bWVyYXRvcigpO1xuXG4gIC8vIElmIHdlIGdvdCB0aGUgRmlsZUVudW1lcmF0b3IsIHRoZW4gbGV0J3MgZ28gd2l0aCB0aGF0XG4gIGlmIChGaWxlRW51bWVyYXRvcikge1xuICAgIHJldHVybiBsaXN0RmlsZXNVc2luZ0ZpbGVFbnVtZXJhdG9yKEZpbGVFbnVtZXJhdG9yLCBzcmMsIGV4dGVuc2lvbnMpO1xuICB9XG4gIC8vIElmIG5vdCwgdGhlbiB3ZSBjYW4gdHJ5IGV2ZW4gb2xkZXIgdmVyc2lvbnMgb2YgdGhpcyBjYXBhYmlsaXR5IChsaXN0RmlsZXNUb1Byb2Nlc3MpXG4gIHJldHVybiBsaXN0RmlsZXNXaXRoTGVnYWN5RnVuY3Rpb25zKHNyYywgZXh0ZW5zaW9ucyk7XG59XG5cbmNvbnN0IEVYUE9SVF9ERUZBVUxUX0RFQ0xBUkFUSU9OID0gJ0V4cG9ydERlZmF1bHREZWNsYXJhdGlvbic7XG5jb25zdCBFWFBPUlRfTkFNRURfREVDTEFSQVRJT04gPSAnRXhwb3J0TmFtZWREZWNsYXJhdGlvbic7XG5jb25zdCBFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OID0gJ0V4cG9ydEFsbERlY2xhcmF0aW9uJztcbmNvbnN0IElNUE9SVF9ERUNMQVJBVElPTiA9ICdJbXBvcnREZWNsYXJhdGlvbic7XG5jb25zdCBJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiA9ICdJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXInO1xuY29uc3QgSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSID0gJ0ltcG9ydERlZmF1bHRTcGVjaWZpZXInO1xuY29uc3QgVkFSSUFCTEVfREVDTEFSQVRJT04gPSAnVmFyaWFibGVEZWNsYXJhdGlvbic7XG5jb25zdCBGVU5DVElPTl9ERUNMQVJBVElPTiA9ICdGdW5jdGlvbkRlY2xhcmF0aW9uJztcbmNvbnN0IENMQVNTX0RFQ0xBUkFUSU9OID0gJ0NsYXNzRGVjbGFyYXRpb24nO1xuY29uc3QgSURFTlRJRklFUiA9ICdJZGVudGlmaWVyJztcbmNvbnN0IE9CSkVDVF9QQVRURVJOID0gJ09iamVjdFBhdHRlcm4nO1xuY29uc3QgQVJSQVlfUEFUVEVSTiA9ICdBcnJheVBhdHRlcm4nO1xuY29uc3QgVFNfSU5URVJGQUNFX0RFQ0xBUkFUSU9OID0gJ1RTSW50ZXJmYWNlRGVjbGFyYXRpb24nO1xuY29uc3QgVFNfVFlQRV9BTElBU19ERUNMQVJBVElPTiA9ICdUU1R5cGVBbGlhc0RlY2xhcmF0aW9uJztcbmNvbnN0IFRTX0VOVU1fREVDTEFSQVRJT04gPSAnVFNFbnVtRGVjbGFyYXRpb24nO1xuY29uc3QgREVGQVVMVCA9ICdkZWZhdWx0JztcblxuZnVuY3Rpb24gZm9yRWFjaERlY2xhcmF0aW9uSWRlbnRpZmllcihkZWNsYXJhdGlvbiwgY2IpIHtcbiAgaWYgKGRlY2xhcmF0aW9uKSB7XG4gICAgY29uc3QgaXNUeXBlRGVjbGFyYXRpb24gPSBkZWNsYXJhdGlvbi50eXBlID09PSBUU19JTlRFUkZBQ0VfREVDTEFSQVRJT05cbiAgICAgIHx8IGRlY2xhcmF0aW9uLnR5cGUgPT09IFRTX1RZUEVfQUxJQVNfREVDTEFSQVRJT05cbiAgICAgIHx8IGRlY2xhcmF0aW9uLnR5cGUgPT09IFRTX0VOVU1fREVDTEFSQVRJT047XG5cbiAgICBpZiAoXG4gICAgICBkZWNsYXJhdGlvbi50eXBlID09PSBGVU5DVElPTl9ERUNMQVJBVElPTlxuICAgICAgfHwgZGVjbGFyYXRpb24udHlwZSA9PT0gQ0xBU1NfREVDTEFSQVRJT05cbiAgICAgIHx8IGlzVHlwZURlY2xhcmF0aW9uXG4gICAgKSB7XG4gICAgICBjYihkZWNsYXJhdGlvbi5pZC5uYW1lLCBpc1R5cGVEZWNsYXJhdGlvbik7XG4gICAgfSBlbHNlIGlmIChkZWNsYXJhdGlvbi50eXBlID09PSBWQVJJQUJMRV9ERUNMQVJBVElPTikge1xuICAgICAgZGVjbGFyYXRpb24uZGVjbGFyYXRpb25zLmZvckVhY2goKHsgaWQgfSkgPT4ge1xuICAgICAgICBpZiAoaWQudHlwZSA9PT0gT0JKRUNUX1BBVFRFUk4pIHtcbiAgICAgICAgICByZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZShpZCwgKHBhdHRlcm4pID0+IHtcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuLnR5cGUgPT09IElERU5USUZJRVIpIHtcbiAgICAgICAgICAgICAgY2IocGF0dGVybi5uYW1lLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaWQudHlwZSA9PT0gQVJSQVlfUEFUVEVSTikge1xuICAgICAgICAgIGlkLmVsZW1lbnRzLmZvckVhY2goKHsgbmFtZSB9KSA9PiB7XG4gICAgICAgICAgICBjYihuYW1lLCBmYWxzZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2IoaWQubmFtZSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBMaXN0IG9mIGltcG9ydHMgcGVyIGZpbGUuXG4gKlxuICogUmVwcmVzZW50ZWQgYnkgYSB0d28tbGV2ZWwgTWFwIHRvIGEgU2V0IG9mIGlkZW50aWZpZXJzLiBUaGUgdXBwZXItbGV2ZWwgTWFwXG4gKiBrZXlzIGFyZSB0aGUgcGF0aHMgdG8gdGhlIG1vZHVsZXMgY29udGFpbmluZyB0aGUgaW1wb3J0cywgd2hpbGUgdGhlXG4gKiBsb3dlci1sZXZlbCBNYXAga2V5cyBhcmUgdGhlIHBhdGhzIHRvIHRoZSBmaWxlcyB3aGljaCBhcmUgYmVpbmcgaW1wb3J0ZWRcbiAqIGZyb20uIExhc3RseSwgdGhlIFNldCBvZiBpZGVudGlmaWVycyBjb250YWlucyBlaXRoZXIgbmFtZXMgYmVpbmcgaW1wb3J0ZWRcbiAqIG9yIGEgc3BlY2lhbCBBU1Qgbm9kZSBuYW1lIGxpc3RlZCBhYm92ZSAoZS5nIEltcG9ydERlZmF1bHRTcGVjaWZpZXIpLlxuICpcbiAqIEZvciBleGFtcGxlLCBpZiB3ZSBoYXZlIGEgZmlsZSBuYW1lZCBmb28uanMgY29udGFpbmluZzpcbiAqXG4gKiAgIGltcG9ydCB7IG8yIH0gZnJvbSAnLi9iYXIuanMnO1xuICpcbiAqIFRoZW4gd2Ugd2lsbCBoYXZlIGEgc3RydWN0dXJlIHRoYXQgbG9va3MgbGlrZTpcbiAqXG4gKiAgIE1hcCB7ICdmb28uanMnID0+IE1hcCB7ICdiYXIuanMnID0+IFNldCB7ICdvMicgfSB9IH1cbiAqXG4gKiBAdHlwZSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgU2V0PHN0cmluZz4+Pn1cbiAqL1xuY29uc3QgaW1wb3J0TGlzdCA9IG5ldyBNYXAoKTtcblxuLyoqXG4gKiBMaXN0IG9mIGV4cG9ydHMgcGVyIGZpbGUuXG4gKlxuICogUmVwcmVzZW50ZWQgYnkgYSB0d28tbGV2ZWwgTWFwIHRvIGFuIG9iamVjdCBvZiBtZXRhZGF0YS4gVGhlIHVwcGVyLWxldmVsIE1hcFxuICoga2V5cyBhcmUgdGhlIHBhdGhzIHRvIHRoZSBtb2R1bGVzIGNvbnRhaW5pbmcgdGhlIGV4cG9ydHMsIHdoaWxlIHRoZVxuICogbG93ZXItbGV2ZWwgTWFwIGtleXMgYXJlIHRoZSBzcGVjaWZpYyBpZGVudGlmaWVycyBvciBzcGVjaWFsIEFTVCBub2RlIG5hbWVzXG4gKiBiZWluZyBleHBvcnRlZC4gVGhlIGxlYWYtbGV2ZWwgbWV0YWRhdGEgb2JqZWN0IGF0IHRoZSBtb21lbnQgb25seSBjb250YWlucyBhXG4gKiBgd2hlcmVVc2VkYCBwcm9wZXJ0eSwgd2hpY2ggY29udGFpbnMgYSBTZXQgb2YgcGF0aHMgdG8gbW9kdWxlcyB0aGF0IGltcG9ydFxuICogdGhlIG5hbWUuXG4gKlxuICogRm9yIGV4YW1wbGUsIGlmIHdlIGhhdmUgYSBmaWxlIG5hbWVkIGJhci5qcyBjb250YWluaW5nIHRoZSBmb2xsb3dpbmcgZXhwb3J0czpcbiAqXG4gKiAgIGNvbnN0IG8yID0gJ2Jhcic7XG4gKiAgIGV4cG9ydCB7IG8yIH07XG4gKlxuICogQW5kIGEgZmlsZSBuYW1lZCBmb28uanMgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIGltcG9ydDpcbiAqXG4gKiAgIGltcG9ydCB7IG8yIH0gZnJvbSAnLi9iYXIuanMnO1xuICpcbiAqIFRoZW4gd2Ugd2lsbCBoYXZlIGEgc3RydWN0dXJlIHRoYXQgbG9va3MgbGlrZTpcbiAqXG4gKiAgIE1hcCB7ICdiYXIuanMnID0+IE1hcCB7ICdvMicgPT4geyB3aGVyZVVzZWQ6IFNldCB7ICdmb28uanMnIH0gfSB9IH1cbiAqXG4gKiBAdHlwZSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgb2JqZWN0Pj59XG4gKi9cbmNvbnN0IGV4cG9ydExpc3QgPSBuZXcgTWFwKCk7XG5cbmNvbnN0IHZpc2l0b3JLZXlNYXAgPSBuZXcgTWFwKCk7XG5cbi8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG5jb25zdCBpZ25vcmVkRmlsZXMgPSBuZXcgU2V0KCk7XG5jb25zdCBmaWxlc091dHNpZGVTcmMgPSBuZXcgU2V0KCk7XG5cbmNvbnN0IGlzTm9kZU1vZHVsZSA9IChwYXRoKSA9PiAoL1xcLyhub2RlX21vZHVsZXMpXFwvLykudGVzdChwYXRoKTtcblxuLyoqXG4gKiByZWFkIGFsbCBmaWxlcyBtYXRjaGluZyB0aGUgcGF0dGVybnMgaW4gc3JjIGFuZCBpZ25vcmVFeHBvcnRzXG4gKlxuICogcmV0dXJuIGFsbCBmaWxlcyBtYXRjaGluZyBzcmMgcGF0dGVybiwgd2hpY2ggYXJlIG5vdCBtYXRjaGluZyB0aGUgaWdub3JlRXhwb3J0cyBwYXR0ZXJuXG4gKiBAdHlwZSB7KHNyYzogc3RyaW5nLCBpZ25vcmVFeHBvcnRzOiBzdHJpbmcsIGNvbnRleHQ6IGltcG9ydCgnZXNsaW50JykuUnVsZS5SdWxlQ29udGV4dCkgPT4gU2V0PHN0cmluZz59XG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGaWxlcyhzcmMsIGlnbm9yZUV4cG9ydHMsIGNvbnRleHQpIHtcbiAgY29uc3QgZXh0ZW5zaW9ucyA9IEFycmF5LmZyb20oZ2V0RmlsZUV4dGVuc2lvbnMoY29udGV4dC5zZXR0aW5ncykpO1xuXG4gIGNvbnN0IHNyY0ZpbGVMaXN0ID0gbGlzdEZpbGVzVG9Qcm9jZXNzKHNyYywgZXh0ZW5zaW9ucywgY29udGV4dCk7XG5cbiAgLy8gcHJlcGFyZSBsaXN0IG9mIGlnbm9yZWQgZmlsZXNcbiAgY29uc3QgaWdub3JlZEZpbGVzTGlzdCA9IGxpc3RGaWxlc1RvUHJvY2VzcyhpZ25vcmVFeHBvcnRzLCBleHRlbnNpb25zLCBjb250ZXh0KTtcblxuICAvLyBUaGUgbW9kZXJuIGFwaSB3aWxsIHJldHVybiBhIGxpc3Qgb2YgZmlsZSBwYXRocywgcmF0aGVyIHRoYW4gYW4gb2JqZWN0XG4gIGlmIChpZ25vcmVkRmlsZXNMaXN0Lmxlbmd0aCAmJiB0eXBlb2YgaWdub3JlZEZpbGVzTGlzdFswXSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZ25vcmVkRmlsZXNMaXN0LmZvckVhY2goKGZpbGVuYW1lKSA9PiBpZ25vcmVkRmlsZXMuYWRkKGZpbGVuYW1lKSk7XG4gIH0gZWxzZSB7XG4gICAgaWdub3JlZEZpbGVzTGlzdC5mb3JFYWNoKCh7IGZpbGVuYW1lIH0pID0+IGlnbm9yZWRGaWxlcy5hZGQoZmlsZW5hbWUpKTtcbiAgfVxuXG4gIC8vIHByZXBhcmUgbGlzdCBvZiBzb3VyY2UgZmlsZXMsIGRvbid0IGNvbnNpZGVyIGZpbGVzIGZyb20gbm9kZV9tb2R1bGVzXG4gIGNvbnN0IHJlc29sdmVkRmlsZXMgPSBzcmNGaWxlTGlzdC5sZW5ndGggJiYgdHlwZW9mIHNyY0ZpbGVMaXN0WzBdID09PSAnc3RyaW5nJ1xuICAgID8gc3JjRmlsZUxpc3QuZmlsdGVyKChmaWxlUGF0aCkgPT4gIWlzTm9kZU1vZHVsZShmaWxlUGF0aCkpXG4gICAgOiBmbGF0TWFwKHNyY0ZpbGVMaXN0LCAoeyBmaWxlbmFtZSB9KSA9PiBpc05vZGVNb2R1bGUoZmlsZW5hbWUpID8gW10gOiBmaWxlbmFtZSk7XG5cbiAgcmV0dXJuIG5ldyBTZXQocmVzb2x2ZWRGaWxlcyk7XG59XG5cbi8qKlxuICogcGFyc2UgYWxsIHNvdXJjZSBmaWxlcyBhbmQgYnVpbGQgdXAgMiBtYXBzIGNvbnRhaW5pbmcgdGhlIGV4aXN0aW5nIGltcG9ydHMgYW5kIGV4cG9ydHNcbiAqL1xuY29uc3QgcHJlcGFyZUltcG9ydHNBbmRFeHBvcnRzID0gKHNyY0ZpbGVzLCBjb250ZXh0KSA9PiB7XG4gIGNvbnN0IGV4cG9ydEFsbCA9IG5ldyBNYXAoKTtcbiAgc3JjRmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgIGNvbnN0IGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgaW1wb3J0cyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBjdXJyZW50RXhwb3J0cyA9IEV4cG9ydE1hcEJ1aWxkZXIuZ2V0KGZpbGUsIGNvbnRleHQpO1xuICAgIGlmIChjdXJyZW50RXhwb3J0cykge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkZXBlbmRlbmNpZXMsXG4gICAgICAgIHJlZXhwb3J0cyxcbiAgICAgICAgaW1wb3J0czogbG9jYWxJbXBvcnRMaXN0LFxuICAgICAgICBuYW1lc3BhY2UsXG4gICAgICAgIHZpc2l0b3JLZXlzLFxuICAgICAgfSA9IGN1cnJlbnRFeHBvcnRzO1xuXG4gICAgICB2aXNpdG9yS2V5TWFwLnNldChmaWxlLCB2aXNpdG9yS2V5cyk7XG4gICAgICAvLyBkZXBlbmRlbmNpZXMgPT09IGV4cG9ydCAqIGZyb21cbiAgICAgIGNvbnN0IGN1cnJlbnRFeHBvcnRBbGwgPSBuZXcgU2V0KCk7XG4gICAgICBkZXBlbmRlbmNpZXMuZm9yRWFjaCgoZ2V0RGVwZW5kZW5jeSkgPT4ge1xuICAgICAgICBjb25zdCBkZXBlbmRlbmN5ID0gZ2V0RGVwZW5kZW5jeSgpO1xuICAgICAgICBpZiAoZGVwZW5kZW5jeSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRFeHBvcnRBbGwuYWRkKGRlcGVuZGVuY3kucGF0aCk7XG4gICAgICB9KTtcbiAgICAgIGV4cG9ydEFsbC5zZXQoZmlsZSwgY3VycmVudEV4cG9ydEFsbCk7XG5cbiAgICAgIHJlZXhwb3J0cy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09IERFRkFVTFQpIHtcbiAgICAgICAgICBleHBvcnRzLnNldChJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIsIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwb3J0cy5zZXQoa2V5LCB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlZXhwb3J0ID0gdmFsdWUuZ2V0SW1wb3J0KCk7XG4gICAgICAgIGlmICghcmVleHBvcnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxvY2FsSW1wb3J0ID0gaW1wb3J0cy5nZXQocmVleHBvcnQucGF0aCk7XG4gICAgICAgIGxldCBjdXJyZW50VmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZS5sb2NhbCA9PT0gREVGQVVMVCkge1xuICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50VmFsdWUgPSB2YWx1ZS5sb2NhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGxvY2FsSW1wb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGxvY2FsSW1wb3J0ID0gbmV3IFNldChbLi4ubG9jYWxJbXBvcnQsIGN1cnJlbnRWYWx1ZV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvY2FsSW1wb3J0ID0gbmV3IFNldChbY3VycmVudFZhbHVlXSk7XG4gICAgICAgIH1cbiAgICAgICAgaW1wb3J0cy5zZXQocmVleHBvcnQucGF0aCwgbG9jYWxJbXBvcnQpO1xuICAgICAgfSk7XG5cbiAgICAgIGxvY2FsSW1wb3J0TGlzdC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChpc05vZGVNb2R1bGUoa2V5KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsb2NhbEltcG9ydCA9IGltcG9ydHMuZ2V0KGtleSkgfHwgbmV3IFNldCgpO1xuICAgICAgICB2YWx1ZS5kZWNsYXJhdGlvbnMuZm9yRWFjaCgoeyBpbXBvcnRlZFNwZWNpZmllcnMgfSkgPT4ge1xuICAgICAgICAgIGltcG9ydGVkU3BlY2lmaWVycy5mb3JFYWNoKChzcGVjaWZpZXIpID0+IHtcbiAgICAgICAgICAgIGxvY2FsSW1wb3J0LmFkZChzcGVjaWZpZXIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgaW1wb3J0cy5zZXQoa2V5LCBsb2NhbEltcG9ydCk7XG4gICAgICB9KTtcbiAgICAgIGltcG9ydExpc3Quc2V0KGZpbGUsIGltcG9ydHMpO1xuXG4gICAgICAvLyBidWlsZCB1cCBleHBvcnQgbGlzdCBvbmx5LCBpZiBmaWxlIGlzIG5vdCBpZ25vcmVkXG4gICAgICBpZiAoaWdub3JlZEZpbGVzLmhhcyhmaWxlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBuYW1lc3BhY2UuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSBERUZBVUxUKSB7XG4gICAgICAgICAgZXhwb3J0cy5zZXQoSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSLCB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGV4cG9ydHMuc2V0KGtleSwgeyB3aGVyZVVzZWQ6IG5ldyBTZXQoKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGV4cG9ydHMuc2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04sIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgZXhwb3J0cy5zZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIsIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgZXhwb3J0TGlzdC5zZXQoZmlsZSwgZXhwb3J0cyk7XG4gIH0pO1xuICBleHBvcnRBbGwuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgIHZhbHVlLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudEV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWwpO1xuICAgICAgaWYgKGN1cnJlbnRFeHBvcnRzKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRFeHBvcnQgPSBjdXJyZW50RXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmFkZChrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn07XG5cbi8qKlxuICogdHJhdmVyc2UgdGhyb3VnaCBhbGwgaW1wb3J0cyBhbmQgYWRkIHRoZSByZXNwZWN0aXZlIHBhdGggdG8gdGhlIHdoZXJlVXNlZC1saXN0XG4gKiBvZiB0aGUgY29ycmVzcG9uZGluZyBleHBvcnRcbiAqL1xuY29uc3QgZGV0ZXJtaW5lVXNhZ2UgPSAoKSA9PiB7XG4gIGltcG9ydExpc3QuZm9yRWFjaCgobGlzdFZhbHVlLCBsaXN0S2V5KSA9PiB7XG4gICAgbGlzdFZhbHVlLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldChrZXkpO1xuICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKChjdXJyZW50SW1wb3J0KSA9PiB7XG4gICAgICAgICAgbGV0IHNwZWNpZmllcjtcbiAgICAgICAgICBpZiAoY3VycmVudEltcG9ydCA9PT0gSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpIHtcbiAgICAgICAgICAgIHNwZWNpZmllciA9IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudEltcG9ydCA9PT0gSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKSB7XG4gICAgICAgICAgICBzcGVjaWZpZXIgPSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNwZWNpZmllciA9IGN1cnJlbnRJbXBvcnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2Ygc3BlY2lmaWVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgZXhwb3J0U3RhdGVtZW50ID0gZXhwb3J0cy5nZXQoc3BlY2lmaWVyKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXhwb3J0U3RhdGVtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBjb25zdCB7IHdoZXJlVXNlZCB9ID0gZXhwb3J0U3RhdGVtZW50O1xuICAgICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGxpc3RLZXkpO1xuICAgICAgICAgICAgICBleHBvcnRzLnNldChzcGVjaWZpZXIsIHsgd2hlcmVVc2VkIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuY29uc3QgZ2V0U3JjID0gKHNyYykgPT4ge1xuICBpZiAoc3JjKSB7XG4gICAgcmV0dXJuIHNyYztcbiAgfVxuICByZXR1cm4gW3Byb2Nlc3MuY3dkKCldO1xufTtcblxuLyoqXG4gKiBwcmVwYXJlIHRoZSBsaXN0cyBvZiBleGlzdGluZyBpbXBvcnRzIGFuZCBleHBvcnRzIC0gc2hvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgb25jZSBhdFxuICogdGhlIHN0YXJ0IG9mIGEgbmV3IGVzbGludCBydW5cbiAqL1xuLyoqIEB0eXBlIHtTZXQ8c3RyaW5nPn0gKi9cbmxldCBzcmNGaWxlcztcbmxldCBsYXN0UHJlcGFyZUtleTtcbmNvbnN0IGRvUHJlcGFyYXRpb24gPSAoc3JjLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KSA9PiB7XG4gIGNvbnN0IHByZXBhcmVLZXkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgc3JjOiAoc3JjIHx8IFtdKS5zb3J0KCksXG4gICAgaWdub3JlRXhwb3J0czogKGlnbm9yZUV4cG9ydHMgfHwgW10pLnNvcnQoKSxcbiAgICBleHRlbnNpb25zOiBBcnJheS5mcm9tKGdldEZpbGVFeHRlbnNpb25zKGNvbnRleHQuc2V0dGluZ3MpKS5zb3J0KCksXG4gIH0pO1xuICBpZiAocHJlcGFyZUtleSA9PT0gbGFzdFByZXBhcmVLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpbXBvcnRMaXN0LmNsZWFyKCk7XG4gIGV4cG9ydExpc3QuY2xlYXIoKTtcbiAgaWdub3JlZEZpbGVzLmNsZWFyKCk7XG4gIGZpbGVzT3V0c2lkZVNyYy5jbGVhcigpO1xuXG4gIHNyY0ZpbGVzID0gcmVzb2x2ZUZpbGVzKGdldFNyYyhzcmMpLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgcHJlcGFyZUltcG9ydHNBbmRFeHBvcnRzKHNyY0ZpbGVzLCBjb250ZXh0KTtcbiAgZGV0ZXJtaW5lVXNhZ2UoKTtcbiAgbGFzdFByZXBhcmVLZXkgPSBwcmVwYXJlS2V5O1xufTtcblxuY29uc3QgbmV3TmFtZXNwYWNlSW1wb3J0RXhpc3RzID0gKHNwZWNpZmllcnMpID0+IHNwZWNpZmllcnMuc29tZSgoeyB0eXBlIH0pID0+IHR5cGUgPT09IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcblxuY29uc3QgbmV3RGVmYXVsdEltcG9ydEV4aXN0cyA9IChzcGVjaWZpZXJzKSA9PiBzcGVjaWZpZXJzLnNvbWUoKHsgdHlwZSB9KSA9PiB0eXBlID09PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpO1xuXG5jb25zdCBmaWxlSXNJblBrZyA9IChmaWxlKSA9PiB7XG4gIGNvbnN0IHsgcGF0aCwgcGtnIH0gPSByZWFkUGtnVXAoeyBjd2Q6IGZpbGUgfSk7XG4gIGNvbnN0IGJhc2VQYXRoID0gZGlybmFtZShwYXRoKTtcblxuICBjb25zdCBjaGVja1BrZ0ZpZWxkU3RyaW5nID0gKHBrZ0ZpZWxkKSA9PiB7XG4gICAgaWYgKGpvaW4oYmFzZVBhdGgsIHBrZ0ZpZWxkKSA9PT0gZmlsZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGNoZWNrUGtnRmllbGRPYmplY3QgPSAocGtnRmllbGQpID0+IHtcbiAgICBjb25zdCBwa2dGaWVsZEZpbGVzID0gZmxhdE1hcCh2YWx1ZXMocGtnRmllbGQpLCAodmFsdWUpID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nID8gW10gOiBqb2luKGJhc2VQYXRoLCB2YWx1ZSkpO1xuXG4gICAgaWYgKGluY2x1ZGVzKHBrZ0ZpZWxkRmlsZXMsIGZpbGUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgY2hlY2tQa2dGaWVsZCA9IChwa2dGaWVsZCkgPT4ge1xuICAgIGlmICh0eXBlb2YgcGtnRmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gY2hlY2tQa2dGaWVsZFN0cmluZyhwa2dGaWVsZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwa2dGaWVsZCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBjaGVja1BrZ0ZpZWxkT2JqZWN0KHBrZ0ZpZWxkKTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKHBrZy5wcml2YXRlID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHBrZy5iaW4pIHtcbiAgICBpZiAoY2hlY2tQa2dGaWVsZChwa2cuYmluKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBrZy5icm93c2VyKSB7XG4gICAgaWYgKGNoZWNrUGtnRmllbGQocGtnLmJyb3dzZXIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAocGtnLm1haW4pIHtcbiAgICBpZiAoY2hlY2tQa2dGaWVsZFN0cmluZyhwa2cubWFpbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGNhdGVnb3J5OiAnSGVscGZ1bCB3YXJuaW5ncycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0ZvcmJpZCBtb2R1bGVzIHdpdGhvdXQgZXhwb3J0cywgb3IgZXhwb3J0cyB3aXRob3V0IG1hdGNoaW5nIGltcG9ydCBpbiBhbm90aGVyIG1vZHVsZS4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCduby11bnVzZWQtbW9kdWxlcycpLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbe1xuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBzcmM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ2ZpbGVzL3BhdGhzIHRvIGJlIGFuYWx5emVkIChvbmx5IGZvciB1bnVzZWQgZXhwb3J0cyknLFxuICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgdW5pcXVlSXRlbXM6IHRydWUsXG4gICAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgbWluTGVuZ3RoOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGlnbm9yZUV4cG9ydHM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ2ZpbGVzL3BhdGhzIGZvciB3aGljaCB1bnVzZWQgZXhwb3J0cyB3aWxsIG5vdCBiZSByZXBvcnRlZCAoZS5nIG1vZHVsZSBlbnRyeSBwb2ludHMpJyxcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBtaXNzaW5nRXhwb3J0czoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAncmVwb3J0IG1vZHVsZXMgd2l0aG91dCBhbnkgZXhwb3J0cycsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgICB1bnVzZWRFeHBvcnRzOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdyZXBvcnQgZXhwb3J0cyB3aXRob3V0IGFueSB1c2FnZScsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgICBpZ25vcmVVbnVzZWRUeXBlRXhwb3J0czoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnaWdub3JlIHR5cGUgZXhwb3J0cyB3aXRob3V0IGFueSB1c2FnZScsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFueU9mOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICB1bnVzZWRFeHBvcnRzOiB7IGVudW06IFt0cnVlXSB9LFxuICAgICAgICAgICAgc3JjOiB7XG4gICAgICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVpcmVkOiBbJ3VudXNlZEV4cG9ydHMnXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIG1pc3NpbmdFeHBvcnRzOiB7IGVudW06IFt0cnVlXSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVxdWlyZWQ6IFsnbWlzc2luZ0V4cG9ydHMnXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfV0sXG4gIH0sXG5cbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCB7XG4gICAgICBzcmMsXG4gICAgICBpZ25vcmVFeHBvcnRzID0gW10sXG4gICAgICBtaXNzaW5nRXhwb3J0cyxcbiAgICAgIHVudXNlZEV4cG9ydHMsXG4gICAgICBpZ25vcmVVbnVzZWRUeXBlRXhwb3J0cyxcbiAgICB9ID0gY29udGV4dC5vcHRpb25zWzBdIHx8IHt9O1xuXG4gICAgaWYgKHVudXNlZEV4cG9ydHMpIHtcbiAgICAgIGRvUHJlcGFyYXRpb24oc3JjLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlID0gZ2V0UGh5c2ljYWxGaWxlbmFtZShjb250ZXh0KTtcblxuICAgIGNvbnN0IGNoZWNrRXhwb3J0UHJlc2VuY2UgPSAobm9kZSkgPT4ge1xuICAgICAgaWYgKCFtaXNzaW5nRXhwb3J0cykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpZ25vcmVkRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhwb3J0Q291bnQgPSBleHBvcnRMaXN0LmdldChmaWxlKTtcbiAgICAgIGNvbnN0IGV4cG9ydEFsbCA9IGV4cG9ydENvdW50LmdldChFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcbiAgICAgIGNvbnN0IG5hbWVzcGFjZUltcG9ydHMgPSBleHBvcnRDb3VudC5nZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuXG4gICAgICBleHBvcnRDb3VudC5kZWxldGUoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICBleHBvcnRDb3VudC5kZWxldGUoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuICAgICAgaWYgKGV4cG9ydENvdW50LnNpemUgPCAxKSB7XG4gICAgICAgIC8vIG5vZGUuYm9keVswXSA9PT0gJ3VuZGVmaW5lZCcgb25seSBoYXBwZW5zLCBpZiBldmVyeXRoaW5nIGlzIGNvbW1lbnRlZCBvdXQgaW4gdGhlIGZpbGVcbiAgICAgICAgLy8gYmVpbmcgbGludGVkXG4gICAgICAgIGNvbnRleHQucmVwb3J0KG5vZGUuYm9keVswXSA/IG5vZGUuYm9keVswXSA6IG5vZGUsICdObyBleHBvcnRzIGZvdW5kJyk7XG4gICAgICB9XG4gICAgICBleHBvcnRDb3VudC5zZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTiwgZXhwb3J0QWxsKTtcbiAgICAgIGV4cG9ydENvdW50LnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgbmFtZXNwYWNlSW1wb3J0cyk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNoZWNrVXNhZ2UgPSAobm9kZSwgZXhwb3J0ZWRWYWx1ZSwgaXNUeXBlRXhwb3J0KSA9PiB7XG4gICAgICBpZiAoIXVudXNlZEV4cG9ydHMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNUeXBlRXhwb3J0ICYmIGlnbm9yZVVudXNlZFR5cGVFeHBvcnRzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlnbm9yZWRGaWxlcy5oYXMoZmlsZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZUlzSW5Qa2coZmlsZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZXNPdXRzaWRlU3JjLmhhcyhmaWxlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG1ha2Ugc3VyZSBmaWxlIHRvIGJlIGxpbnRlZCBpcyBpbmNsdWRlZCBpbiBzb3VyY2UgZmlsZXNcbiAgICAgIGlmICghc3JjRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHNyY0ZpbGVzID0gcmVzb2x2ZUZpbGVzKGdldFNyYyhzcmMpLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKCFzcmNGaWxlcy5oYXMoZmlsZSkpIHtcbiAgICAgICAgICBmaWxlc091dHNpZGVTcmMuYWRkKGZpbGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBleHBvcnRzID0gZXhwb3J0TGlzdC5nZXQoZmlsZSk7XG5cbiAgICAgIGlmICghZXhwb3J0cykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBmaWxlIFxcYCR7ZmlsZX1cXGAgaGFzIG5vIGV4cG9ydHMuIFBsZWFzZSB1cGRhdGUgdG8gdGhlIGxhdGVzdCwgYW5kIGlmIGl0IHN0aWxsIGhhcHBlbnMsIHJlcG9ydCB0aGlzIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9pbXBvcnQtanMvZXNsaW50LXBsdWdpbi1pbXBvcnQvaXNzdWVzLzI4NjYhYCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogZXhwb3J0ICogZnJvbVxuICAgICAgY29uc3QgZXhwb3J0QWxsID0gZXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICBpZiAodHlwZW9mIGV4cG9ydEFsbCAhPT0gJ3VuZGVmaW5lZCcgJiYgZXhwb3J0ZWRWYWx1ZSAhPT0gSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKSB7XG4gICAgICAgIGlmIChleHBvcnRBbGwud2hlcmVVc2VkLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogbmFtZXNwYWNlIGltcG9ydFxuICAgICAgY29uc3QgbmFtZXNwYWNlSW1wb3J0cyA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgIGlmICh0eXBlb2YgbmFtZXNwYWNlSW1wb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKG5hbWVzcGFjZUltcG9ydHMud2hlcmVVc2VkLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGV4cG9ydHNMaXN0IHdpbGwgYWx3YXlzIG1hcCBhbnkgaW1wb3J0ZWQgdmFsdWUgb2YgJ2RlZmF1bHQnIHRvICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJ1xuICAgICAgY29uc3QgZXhwb3J0c0tleSA9IGV4cG9ydGVkVmFsdWUgPT09IERFRkFVTFQgPyBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgOiBleHBvcnRlZFZhbHVlO1xuXG4gICAgICBjb25zdCBleHBvcnRTdGF0ZW1lbnQgPSBleHBvcnRzLmdldChleHBvcnRzS2V5KTtcblxuICAgICAgY29uc3QgdmFsdWUgPSBleHBvcnRzS2V5ID09PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgPyBERUZBVUxUIDogZXhwb3J0c0tleTtcblxuICAgICAgaWYgKHR5cGVvZiBleHBvcnRTdGF0ZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChleHBvcnRTdGF0ZW1lbnQud2hlcmVVc2VkLnNpemUgPCAxKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgYGV4cG9ydGVkIGRlY2xhcmF0aW9uICcke3ZhbHVlfScgbm90IHVzZWQgd2l0aGluIG90aGVyIG1vZHVsZXNgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgYGV4cG9ydGVkIGRlY2xhcmF0aW9uICcke3ZhbHVlfScgbm90IHVzZWQgd2l0aGluIG90aGVyIG1vZHVsZXNgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBvbmx5IHVzZWZ1bCBmb3IgdG9vbHMgbGlrZSB2c2NvZGUtZXNsaW50XG4gICAgICpcbiAgICAgKiB1cGRhdGUgbGlzdHMgb2YgZXhpc3RpbmcgZXhwb3J0cyBkdXJpbmcgcnVudGltZVxuICAgICAqL1xuICAgIGNvbnN0IHVwZGF0ZUV4cG9ydFVzYWdlID0gKG5vZGUpID0+IHtcbiAgICAgIGlmIChpZ25vcmVkRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldChmaWxlKTtcblxuICAgICAgLy8gbmV3IG1vZHVsZSBoYXMgYmVlbiBjcmVhdGVkIGR1cmluZyBydW50aW1lXG4gICAgICAvLyBpbmNsdWRlIGl0IGluIGZ1cnRoZXIgcHJvY2Vzc2luZ1xuICAgICAgaWYgKHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdFeHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgY29uc3QgbmV3RXhwb3J0SWRlbnRpZmllcnMgPSBuZXcgU2V0KCk7XG5cbiAgICAgIG5vZGUuYm9keS5mb3JFYWNoKCh7IHR5cGUsIGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzIH0pID0+IHtcbiAgICAgICAgaWYgKHR5cGUgPT09IEVYUE9SVF9ERUZBVUxUX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgbmV3RXhwb3J0SWRlbnRpZmllcnMuYWRkKElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09IEVYUE9SVF9OQU1FRF9ERUNMQVJBVElPTikge1xuICAgICAgICAgIGlmIChzcGVjaWZpZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNwZWNpZmllcnMuZm9yRWFjaCgoc3BlY2lmaWVyKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChzcGVjaWZpZXIuZXhwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICBuZXdFeHBvcnRJZGVudGlmaWVycy5hZGQoc3BlY2lmaWVyLmV4cG9ydGVkLm5hbWUgfHwgc3BlY2lmaWVyLmV4cG9ydGVkLnZhbHVlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvckVhY2hEZWNsYXJhdGlvbklkZW50aWZpZXIoZGVjbGFyYXRpb24sIChuYW1lKSA9PiB7XG4gICAgICAgICAgICBuZXdFeHBvcnRJZGVudGlmaWVycy5hZGQobmFtZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBvbGQgZXhwb3J0cyBleGlzdCB3aXRoaW4gbGlzdCBvZiBuZXcgZXhwb3J0cyBpZGVudGlmaWVyczogYWRkIHRvIG1hcCBvZiBuZXcgZXhwb3J0c1xuICAgICAgZXhwb3J0cy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChuZXdFeHBvcnRJZGVudGlmaWVycy5oYXMoa2V5KSkge1xuICAgICAgICAgIG5ld0V4cG9ydHMuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gbmV3IGV4cG9ydCBpZGVudGlmaWVycyBhZGRlZDogYWRkIHRvIG1hcCBvZiBuZXcgZXhwb3J0c1xuICAgICAgbmV3RXhwb3J0SWRlbnRpZmllcnMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmICghZXhwb3J0cy5oYXMoa2V5KSkge1xuICAgICAgICAgIG5ld0V4cG9ydHMuc2V0KGtleSwgeyB3aGVyZVVzZWQ6IG5ldyBTZXQoKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIHByZXNlcnZlIGluZm9ybWF0aW9uIGFib3V0IG5hbWVzcGFjZSBpbXBvcnRzXG4gICAgICBjb25zdCBleHBvcnRBbGwgPSBleHBvcnRzLmdldChFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcbiAgICAgIGxldCBuYW1lc3BhY2VJbXBvcnRzID0gZXhwb3J0cy5nZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuXG4gICAgICBpZiAodHlwZW9mIG5hbWVzcGFjZUltcG9ydHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG5hbWVzcGFjZUltcG9ydHMgPSB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH07XG4gICAgICB9XG5cbiAgICAgIG5ld0V4cG9ydHMuc2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04sIGV4cG9ydEFsbCk7XG4gICAgICBuZXdFeHBvcnRzLnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgbmFtZXNwYWNlSW1wb3J0cyk7XG4gICAgICBleHBvcnRMaXN0LnNldChmaWxlLCBuZXdFeHBvcnRzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogb25seSB1c2VmdWwgZm9yIHRvb2xzIGxpa2UgdnNjb2RlLWVzbGludFxuICAgICAqXG4gICAgICogdXBkYXRlIGxpc3RzIG9mIGV4aXN0aW5nIGltcG9ydHMgZHVyaW5nIHJ1bnRpbWVcbiAgICAgKi9cbiAgICBjb25zdCB1cGRhdGVJbXBvcnRVc2FnZSA9IChub2RlKSA9PiB7XG4gICAgICBpZiAoIXVudXNlZEV4cG9ydHMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgb2xkSW1wb3J0UGF0aHMgPSBpbXBvcnRMaXN0LmdldChmaWxlKTtcbiAgICAgIGlmICh0eXBlb2Ygb2xkSW1wb3J0UGF0aHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG9sZEltcG9ydFBhdGhzID0gbmV3IE1hcCgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvbGROYW1lc3BhY2VJbXBvcnRzID0gbmV3IFNldCgpO1xuICAgICAgY29uc3QgbmV3TmFtZXNwYWNlSW1wb3J0cyA9IG5ldyBTZXQoKTtcblxuICAgICAgY29uc3Qgb2xkRXhwb3J0QWxsID0gbmV3IFNldCgpO1xuICAgICAgY29uc3QgbmV3RXhwb3J0QWxsID0gbmV3IFNldCgpO1xuXG4gICAgICBjb25zdCBvbGREZWZhdWx0SW1wb3J0cyA9IG5ldyBTZXQoKTtcbiAgICAgIGNvbnN0IG5ld0RlZmF1bHRJbXBvcnRzID0gbmV3IFNldCgpO1xuXG4gICAgICBjb25zdCBvbGRJbXBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgY29uc3QgbmV3SW1wb3J0cyA9IG5ldyBNYXAoKTtcbiAgICAgIG9sZEltcG9ydFBhdGhzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKHZhbHVlLmhhcyhFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKSkge1xuICAgICAgICAgIG9sZEV4cG9ydEFsbC5hZGQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUuaGFzKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKSkge1xuICAgICAgICAgIG9sZE5hbWVzcGFjZUltcG9ydHMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlLmhhcyhJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpKSB7XG4gICAgICAgICAgb2xkRGVmYXVsdEltcG9ydHMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWUuZm9yRWFjaCgodmFsKSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdmFsICE9PSBJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUlxuICAgICAgICAgICAgJiYgdmFsICE9PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVJcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG9sZEltcG9ydHMuc2V0KHZhbCwga2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGZ1bmN0aW9uIHByb2Nlc3NEeW5hbWljSW1wb3J0KHNvdXJjZSkge1xuICAgICAgICBpZiAoc291cmNlLnR5cGUgIT09ICdMaXRlcmFsJykge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHAgPSByZXNvbHZlKHNvdXJjZS52YWx1ZSwgY29udGV4dCk7XG4gICAgICAgIGlmIChwID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBuZXdOYW1lc3BhY2VJbXBvcnRzLmFkZChwKTtcbiAgICAgIH1cblxuICAgICAgdmlzaXQobm9kZSwgdmlzaXRvcktleU1hcC5nZXQoZmlsZSksIHtcbiAgICAgICAgSW1wb3J0RXhwcmVzc2lvbihjaGlsZCkge1xuICAgICAgICAgIHByb2Nlc3NEeW5hbWljSW1wb3J0KGNoaWxkLnNvdXJjZSk7XG4gICAgICAgIH0sXG4gICAgICAgIENhbGxFeHByZXNzaW9uKGNoaWxkKSB7XG4gICAgICAgICAgaWYgKGNoaWxkLmNhbGxlZS50eXBlID09PSAnSW1wb3J0Jykge1xuICAgICAgICAgICAgcHJvY2Vzc0R5bmFtaWNJbXBvcnQoY2hpbGQuYXJndW1lbnRzWzBdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgbm9kZS5ib2R5LmZvckVhY2goKGFzdE5vZGUpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkUGF0aDtcblxuICAgICAgICAvLyBzdXBwb3J0IGZvciBleHBvcnQgeyB2YWx1ZSB9IGZyb20gJ21vZHVsZSdcbiAgICAgICAgaWYgKGFzdE5vZGUudHlwZSA9PT0gRVhQT1JUX05BTUVEX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgaWYgKGFzdE5vZGUuc291cmNlKSB7XG4gICAgICAgICAgICByZXNvbHZlZFBhdGggPSByZXNvbHZlKGFzdE5vZGUuc291cmNlLnJhdy5yZXBsYWNlKC8oJ3xcIikvZywgJycpLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGFzdE5vZGUuc3BlY2lmaWVycy5mb3JFYWNoKChzcGVjaWZpZXIpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHNwZWNpZmllci5sb2NhbC5uYW1lIHx8IHNwZWNpZmllci5sb2NhbC52YWx1ZTtcbiAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IERFRkFVTFQpIHtcbiAgICAgICAgICAgICAgICBuZXdEZWZhdWx0SW1wb3J0cy5hZGQocmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdJbXBvcnRzLnNldChuYW1lLCByZXNvbHZlZFBhdGgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXN0Tm9kZS50eXBlID09PSBFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShhc3ROb2RlLnNvdXJjZS5yYXcucmVwbGFjZSgvKCd8XCIpL2csICcnKSwgY29udGV4dCk7XG4gICAgICAgICAgbmV3RXhwb3J0QWxsLmFkZChyZXNvbHZlZFBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFzdE5vZGUudHlwZSA9PT0gSU1QT1JUX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShhc3ROb2RlLnNvdXJjZS5yYXcucmVwbGFjZSgvKCd8XCIpL2csICcnKSwgY29udGV4dCk7XG4gICAgICAgICAgaWYgKCFyZXNvbHZlZFBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNOb2RlTW9kdWxlKHJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobmV3TmFtZXNwYWNlSW1wb3J0RXhpc3RzKGFzdE5vZGUuc3BlY2lmaWVycykpIHtcbiAgICAgICAgICAgIG5ld05hbWVzcGFjZUltcG9ydHMuYWRkKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5ld0RlZmF1bHRJbXBvcnRFeGlzdHMoYXN0Tm9kZS5zcGVjaWZpZXJzKSkge1xuICAgICAgICAgICAgbmV3RGVmYXVsdEltcG9ydHMuYWRkKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXN0Tm9kZS5zcGVjaWZpZXJzXG4gICAgICAgICAgICAuZmlsdGVyKChzcGVjaWZpZXIpID0+IHNwZWNpZmllci50eXBlICE9PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgJiYgc3BlY2lmaWVyLnR5cGUgIT09IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKVxuICAgICAgICAgICAgLmZvckVhY2goKHNwZWNpZmllcikgPT4ge1xuICAgICAgICAgICAgICBuZXdJbXBvcnRzLnNldChzcGVjaWZpZXIuaW1wb3J0ZWQubmFtZSB8fCBzcGVjaWZpZXIuaW1wb3J0ZWQudmFsdWUsIHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG5ld0V4cG9ydEFsbC5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoIW9sZEV4cG9ydEFsbC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKEVYUE9SVF9BTExfREVDTEFSQVRJT04pO1xuICAgICAgICAgIG9sZEltcG9ydFBhdGhzLnNldCh2YWx1ZSwgaW1wb3J0cyk7XG5cbiAgICAgICAgICBsZXQgZXhwb3J0cyA9IGV4cG9ydExpc3QuZ2V0KHZhbHVlKTtcbiAgICAgICAgICBsZXQgY3VycmVudEV4cG9ydDtcbiAgICAgICAgICBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjdXJyZW50RXhwb3J0ID0gZXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBleHBvcnRMaXN0LnNldCh2YWx1ZSwgZXhwb3J0cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3aGVyZVVzZWQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgICAgZXhwb3J0cy5zZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkRXhwb3J0QWxsLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICghbmV3RXhwb3J0QWxsLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICBjb25zdCBpbXBvcnRzID0gb2xkSW1wb3J0UGF0aHMuZ2V0KHZhbHVlKTtcbiAgICAgICAgICBpbXBvcnRzLmRlbGV0ZShFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBjdXJyZW50RXhwb3J0LndoZXJlVXNlZC5kZWxldGUoZmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgbmV3RGVmYXVsdEltcG9ydHMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKCFvbGREZWZhdWx0SW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgICAgb2xkSW1wb3J0UGF0aHMuc2V0KHZhbHVlLCBpbXBvcnRzKTtcblxuICAgICAgICAgIGxldCBleHBvcnRzID0gZXhwb3J0TGlzdC5nZXQodmFsdWUpO1xuICAgICAgICAgIGxldCBjdXJyZW50RXhwb3J0O1xuICAgICAgICAgIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQgPSBleHBvcnRzLmdldChJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgZXhwb3J0TGlzdC5zZXQodmFsdWUsIGV4cG9ydHMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudEV4cG9ydCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmFkZChmaWxlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgd2hlcmVVc2VkID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgd2hlcmVVc2VkLmFkZChmaWxlKTtcbiAgICAgICAgICAgIGV4cG9ydHMuc2V0KElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkRGVmYXVsdEltcG9ydHMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKCFuZXdEZWZhdWx0SW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgY29uc3QgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaW1wb3J0cy5kZWxldGUoSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmRlbGV0ZShmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBuZXdOYW1lc3BhY2VJbXBvcnRzLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICghb2xkTmFtZXNwYWNlSW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICBvbGRJbXBvcnRQYXRocy5zZXQodmFsdWUsIGltcG9ydHMpO1xuXG4gICAgICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgbGV0IGN1cnJlbnRFeHBvcnQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXhwb3J0cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGV4cG9ydExpc3Quc2V0KHZhbHVlLCBleHBvcnRzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjdXJyZW50RXhwb3J0LndoZXJlVXNlZC5hZGQoZmlsZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHdoZXJlVXNlZCA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIHdoZXJlVXNlZC5hZGQoZmlsZSk7XG4gICAgICAgICAgICBleHBvcnRzLnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkTmFtZXNwYWNlSW1wb3J0cy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoIW5ld05hbWVzcGFjZUltcG9ydHMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgIGNvbnN0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGltcG9ydHMuZGVsZXRlKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudEV4cG9ydCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuZGVsZXRlKGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG5ld0ltcG9ydHMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICBpZiAoIW9sZEltcG9ydHMuaGFzKGtleSkpIHtcbiAgICAgICAgICBsZXQgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBpbXBvcnRzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgaW1wb3J0cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW1wb3J0cy5hZGQoa2V5KTtcbiAgICAgICAgICBvbGRJbXBvcnRQYXRocy5zZXQodmFsdWUsIGltcG9ydHMpO1xuXG4gICAgICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgbGV0IGN1cnJlbnRFeHBvcnQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KGtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBleHBvcnRMaXN0LnNldCh2YWx1ZSwgZXhwb3J0cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3aGVyZVVzZWQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgICAgZXhwb3J0cy5zZXQoa2V5LCB7IHdoZXJlVXNlZCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBvbGRJbXBvcnRzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKCFuZXdJbXBvcnRzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgY29uc3QgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaW1wb3J0cy5kZWxldGUoa2V5KTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KGtleSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmRlbGV0ZShmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgJ1Byb2dyYW06ZXhpdCcobm9kZSkge1xuICAgICAgICB1cGRhdGVFeHBvcnRVc2FnZShub2RlKTtcbiAgICAgICAgdXBkYXRlSW1wb3J0VXNhZ2Uobm9kZSk7XG4gICAgICAgIGNoZWNrRXhwb3J0UHJlc2VuY2Uobm9kZSk7XG4gICAgICB9LFxuICAgICAgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgY2hlY2tVc2FnZShub2RlLCBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIsIGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBFeHBvcnROYW1lZERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS5zcGVjaWZpZXJzLmZvckVhY2goKHNwZWNpZmllcikgPT4ge1xuICAgICAgICAgIGNoZWNrVXNhZ2Uoc3BlY2lmaWVyLCBzcGVjaWZpZXIuZXhwb3J0ZWQubmFtZSB8fCBzcGVjaWZpZXIuZXhwb3J0ZWQudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZvckVhY2hEZWNsYXJhdGlvbklkZW50aWZpZXIobm9kZS5kZWNsYXJhdGlvbiwgKG5hbWUsIGlzVHlwZUV4cG9ydCkgPT4ge1xuICAgICAgICAgIGNoZWNrVXNhZ2Uobm9kZSwgbmFtZSwgaXNUeXBlRXhwb3J0KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuIl19+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby11bnVzZWQtbW9kdWxlcy5qcyJdLCJuYW1lcyI6WyJyZXF1aXJlRmlsZUVudW1lcmF0b3IiLCJGaWxlRW51bWVyYXRvciIsInJlcXVpcmUiLCJlIiwiY29kZSIsImxpc3RGaWxlc1VzaW5nRmlsZUVudW1lcmF0b3IiLCJzcmMiLCJleHRlbnNpb25zIiwiRVNMSU5UX1VTRV9GTEFUX0NPTkZJRyIsInByb2Nlc3MiLCJlbnYiLCJpc1VzaW5nRmxhdENvbmZpZyIsInNob3VsZFVzZUZsYXRDb25maWciLCJfIiwiZW51bWVyYXRvciIsIkFycmF5IiwiZnJvbSIsIml0ZXJhdGVGaWxlcyIsImZpbGVQYXRoIiwiaWdub3JlZCIsImZpbGVuYW1lIiwibWVzc2FnZSIsImluY2x1ZGVzIiwiRXJyb3IiLCJsaXN0RmlsZXNXaXRoTGVnYWN5RnVuY3Rpb25zIiwib3JpZ2luYWxMaXN0RmlsZXNUb1Byb2Nlc3MiLCJsaXN0RmlsZXNUb1Byb2Nlc3MiLCJwYXR0ZXJucyIsImNvbmNhdCIsInBhdHRlcm4iLCJtYXAiLCJleHRlbnNpb24iLCJ0ZXN0IiwiRVhQT1JUX0RFRkFVTFRfREVDTEFSQVRJT04iLCJFWFBPUlRfTkFNRURfREVDTEFSQVRJT04iLCJFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OIiwiSU1QT1JUX0RFQ0xBUkFUSU9OIiwiSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIiLCJJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIiLCJWQVJJQUJMRV9ERUNMQVJBVElPTiIsIkZVTkNUSU9OX0RFQ0xBUkFUSU9OIiwiQ0xBU1NfREVDTEFSQVRJT04iLCJJREVOVElGSUVSIiwiT0JKRUNUX1BBVFRFUk4iLCJBUlJBWV9QQVRURVJOIiwiVFNfSU5URVJGQUNFX0RFQ0xBUkFUSU9OIiwiVFNfVFlQRV9BTElBU19ERUNMQVJBVElPTiIsIlRTX0VOVU1fREVDTEFSQVRJT04iLCJERUZBVUxUIiwiZm9yRWFjaERlY2xhcmF0aW9uSWRlbnRpZmllciIsImRlY2xhcmF0aW9uIiwiY2IiLCJpc1R5cGVEZWNsYXJhdGlvbiIsInR5cGUiLCJpZCIsIm5hbWUiLCJkZWNsYXJhdGlvbnMiLCJmb3JFYWNoIiwiZWxlbWVudHMiLCJpbXBvcnRMaXN0IiwiTWFwIiwiZXhwb3J0TGlzdCIsInZpc2l0b3JLZXlNYXAiLCJpZ25vcmVkRmlsZXMiLCJTZXQiLCJmaWxlc091dHNpZGVTcmMiLCJpc05vZGVNb2R1bGUiLCJwYXRoIiwicmVzb2x2ZUZpbGVzIiwiaWdub3JlRXhwb3J0cyIsImNvbnRleHQiLCJzZXR0aW5ncyIsInNyY0ZpbGVMaXN0IiwiaWdub3JlZEZpbGVzTGlzdCIsImxlbmd0aCIsImFkZCIsInJlc29sdmVkRmlsZXMiLCJmaWx0ZXIiLCJwcmVwYXJlSW1wb3J0c0FuZEV4cG9ydHMiLCJzcmNGaWxlcyIsImV4cG9ydEFsbCIsImZpbGUiLCJleHBvcnRzIiwiaW1wb3J0cyIsImN1cnJlbnRFeHBvcnRzIiwiRXhwb3J0TWFwQnVpbGRlciIsImdldCIsImRlcGVuZGVuY2llcyIsInJlZXhwb3J0cyIsImxvY2FsSW1wb3J0TGlzdCIsIm5hbWVzcGFjZSIsInZpc2l0b3JLZXlzIiwic2V0IiwiY3VycmVudEV4cG9ydEFsbCIsImdldERlcGVuZGVuY3kiLCJkZXBlbmRlbmN5IiwidmFsdWUiLCJrZXkiLCJ3aGVyZVVzZWQiLCJyZWV4cG9ydCIsImdldEltcG9ydCIsImxvY2FsSW1wb3J0IiwiY3VycmVudFZhbHVlIiwibG9jYWwiLCJpbXBvcnRlZFNwZWNpZmllcnMiLCJzcGVjaWZpZXIiLCJoYXMiLCJ2YWwiLCJjdXJyZW50RXhwb3J0IiwiZGV0ZXJtaW5lVXNhZ2UiLCJsaXN0VmFsdWUiLCJsaXN0S2V5IiwiY3VycmVudEltcG9ydCIsImV4cG9ydFN0YXRlbWVudCIsImdldFNyYyIsImN3ZCIsImxhc3RQcmVwYXJlS2V5IiwiZG9QcmVwYXJhdGlvbiIsInByZXBhcmVLZXkiLCJKU09OIiwic3RyaW5naWZ5Iiwic29ydCIsImNsZWFyIiwibmV3TmFtZXNwYWNlSW1wb3J0RXhpc3RzIiwic3BlY2lmaWVycyIsInNvbWUiLCJuZXdEZWZhdWx0SW1wb3J0RXhpc3RzIiwiZmlsZUlzSW5Qa2ciLCJwa2ciLCJiYXNlUGF0aCIsImNoZWNrUGtnRmllbGRTdHJpbmciLCJwa2dGaWVsZCIsImNoZWNrUGtnRmllbGRPYmplY3QiLCJwa2dGaWVsZEZpbGVzIiwiY2hlY2tQa2dGaWVsZCIsImJpbiIsImJyb3dzZXIiLCJtYWluIiwibW9kdWxlIiwibWV0YSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwic2NoZW1hIiwicHJvcGVydGllcyIsInVuaXF1ZUl0ZW1zIiwiaXRlbXMiLCJtaW5MZW5ndGgiLCJtaXNzaW5nRXhwb3J0cyIsInVudXNlZEV4cG9ydHMiLCJpZ25vcmVVbnVzZWRUeXBlRXhwb3J0cyIsImFueU9mIiwibWluSXRlbXMiLCJyZXF1aXJlZCIsImNyZWF0ZSIsIm9wdGlvbnMiLCJjaGVja0V4cG9ydFByZXNlbmNlIiwibm9kZSIsImV4cG9ydENvdW50IiwibmFtZXNwYWNlSW1wb3J0cyIsInNpemUiLCJyZXBvcnQiLCJib2R5IiwiY2hlY2tVc2FnZSIsImV4cG9ydGVkVmFsdWUiLCJpc1R5cGVFeHBvcnQiLCJjb25zb2xlIiwiZXJyb3IiLCJleHBvcnRzS2V5IiwidXBkYXRlRXhwb3J0VXNhZ2UiLCJuZXdFeHBvcnRzIiwibmV3RXhwb3J0SWRlbnRpZmllcnMiLCJleHBvcnRlZCIsInVwZGF0ZUltcG9ydFVzYWdlIiwib2xkSW1wb3J0UGF0aHMiLCJvbGROYW1lc3BhY2VJbXBvcnRzIiwibmV3TmFtZXNwYWNlSW1wb3J0cyIsIm9sZEV4cG9ydEFsbCIsIm5ld0V4cG9ydEFsbCIsIm9sZERlZmF1bHRJbXBvcnRzIiwibmV3RGVmYXVsdEltcG9ydHMiLCJvbGRJbXBvcnRzIiwibmV3SW1wb3J0cyIsInByb2Nlc3NEeW5hbWljSW1wb3J0Iiwic291cmNlIiwicCIsIkltcG9ydEV4cHJlc3Npb24iLCJjaGlsZCIsIkNhbGxFeHByZXNzaW9uIiwiY2FsbGVlIiwiYXJndW1lbnRzIiwiYXN0Tm9kZSIsInJlc29sdmVkUGF0aCIsInJhdyIsInJlcGxhY2UiLCJpbXBvcnRlZCIsIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvbiIsIkV4cG9ydE5hbWVkRGVjbGFyYXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7OztBQU1BO0FBQ0E7QUFDQSxzRDtBQUNBLGtEO0FBQ0E7QUFDQSwyRDtBQUNBLHVDO0FBQ0EsK0M7QUFDQSx5RDs7QUFFQSwrQztBQUNBLDZEO0FBQ0EscUMsMlVBbEJBOzs7O29YQW9CQTs7Ozs7dVhBTUEsU0FBU0EscUJBQVQsR0FBaUMsQ0FDL0IsSUFBSUMsdUJBQUo7O0FBRUE7QUFDQSxNQUFJO0FBQ29CQyxZQUFRLDZCQUFSLENBRHBCLENBQ0NELGNBREQsWUFDQ0EsY0FERDtBQUVILEdBRkQsQ0FFRSxPQUFPRSxDQUFQLEVBQVU7QUFDVjtBQUNBLFFBQUlBLEVBQUVDLElBQUYsS0FBVyxrQkFBZixFQUFtQztBQUNqQyxZQUFNRCxDQUFOO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJO0FBQ29CRCxjQUFRLHVDQUFSLENBRHBCLENBQ0NELGNBREQsYUFDQ0EsY0FERDtBQUVILEtBRkQsQ0FFRSxPQUFPRSxDQUFQLEVBQVU7QUFDVjtBQUNBLFVBQUlBLEVBQUVDLElBQUYsS0FBVyxrQkFBZixFQUFtQztBQUNqQyxjQUFNRCxDQUFOO0FBQ0Q7QUFDRjtBQUNGO0FBQ0QsU0FBT0YsY0FBUDtBQUNEOztBQUVEOzs7Ozs7O0FBT0EsU0FBU0ksNEJBQVQsQ0FBc0NKLGNBQXRDLEVBQXNESyxHQUF0RCxFQUEyREMsVUFBM0QsRUFBdUU7QUFDckU7QUFDQTtBQUZxRTtBQUk3REMsd0JBSjZELEdBSWxDQyxRQUFRQyxHQUowQixDQUk3REYsc0JBSjZEOztBQU1yRTtBQUNBLE1BQUlHLG9CQUFvQkgsMEJBQTBCQyxRQUFRQyxHQUFSLENBQVlGLHNCQUFaLEtBQXVDLE9BQXpGOztBQUVBO0FBQ0E7QUFDQSxNQUFJO0FBQzhCTixZQUFRLDZCQUFSLENBRDlCLENBQ01VLG1CQUROLGFBQ01BLG1CQUROO0FBRUZELHdCQUFvQkMsdUJBQXVCSiwyQkFBMkIsT0FBdEU7QUFDRCxHQUhELENBR0UsT0FBT0ssQ0FBUCxFQUFVO0FBQ1Y7QUFDQTtBQUNEOztBQUVELE1BQU1DLGFBQWEsSUFBSWIsY0FBSixDQUFtQjtBQUNwQ00sMEJBRG9DLEVBQW5CLENBQW5COzs7QUFJQSxNQUFJO0FBQ0YsV0FBT1EsTUFBTUMsSUFBTjtBQUNMRixlQUFXRyxZQUFYLENBQXdCWCxHQUF4QixDQURLO0FBRUwseUJBQUdZLFFBQUgsUUFBR0EsUUFBSCxDQUFhQyxPQUFiLFFBQWFBLE9BQWIsUUFBNEIsRUFBRUMsVUFBVUYsUUFBWixFQUFzQkMsZ0JBQXRCLEVBQTVCLEVBRkssQ0FBUDs7QUFJRCxHQUxELENBS0UsT0FBT2hCLENBQVAsRUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0VRO0FBQ0dSLE1BQUVrQixPQUFGLENBQVVDLFFBQVYsQ0FBbUIsK0JBQW5CLENBRkw7QUFHRTtBQUNBLFlBQU0sSUFBSUMsS0FBSixtYUFBTjs7Ozs7Ozs7OztBQVVEO0FBQ0Q7QUFDQSxVQUFNcEIsQ0FBTjtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7QUFPQSxTQUFTcUIsNEJBQVQsQ0FBc0NsQixHQUF0QyxFQUEyQ0MsVUFBM0MsRUFBdUQ7QUFDckQsTUFBSTtBQUNGO0FBREUsb0JBRXlETCxRQUFRLDRCQUFSLENBRnpELENBRTBCdUIsMEJBRjFCLGFBRU1DLGtCQUZOO0FBR0Y7QUFDQTtBQUNBOztBQUVBLFdBQU9ELDJCQUEyQm5CLEdBQTNCLEVBQWdDO0FBQ3JDQyw0QkFEcUMsRUFBaEMsQ0FBUDs7QUFHRCxHQVZELENBVUUsT0FBT0osQ0FBUCxFQUFVO0FBQ1Y7QUFDQSxRQUFJQSxFQUFFQyxJQUFGLEtBQVcsa0JBQWYsRUFBbUM7QUFDakMsWUFBTUQsQ0FBTjtBQUNEOztBQUVEO0FBTlU7O0FBU05ELFlBQVEsMkJBQVIsQ0FUTSxDQVFZdUIsMkJBUlosYUFRUkMsa0JBUlE7QUFVVixRQUFNQyxXQUFXckIsSUFBSXNCLE1BQUo7QUFDZjtBQUNFdEIsT0FERjtBQUVFLGNBQUN1QixPQUFELFVBQWF0QixXQUFXdUIsR0FBWCxDQUFlLFVBQUNDLFNBQUQsVUFBZ0IsWUFBRCxDQUFjQyxJQUFkLENBQW1CSCxPQUFuQixJQUE4QkEsT0FBOUIsVUFBMkNBLE9BQTNDLHFCQUEwREUsU0FBMUQsQ0FBZixHQUFmLENBQWIsRUFGRixDQURlLENBQWpCOzs7O0FBT0EsV0FBT04sNEJBQTJCRSxRQUEzQixDQUFQO0FBQ0Q7QUFDRjs7QUFFRDs7Ozs7OztBQU9BLFNBQVNELGtCQUFULENBQTRCcEIsR0FBNUIsRUFBaUNDLFVBQWpDLEVBQTZDO0FBQzNDLE1BQU1OLGlCQUFpQkQsdUJBQXZCOztBQUVBO0FBQ0EsTUFBSUMsY0FBSixFQUFvQjtBQUNsQixXQUFPSSw2QkFBNkJKLGNBQTdCLEVBQTZDSyxHQUE3QyxFQUFrREMsVUFBbEQsQ0FBUDtBQUNEO0FBQ0Q7QUFDQSxTQUFPaUIsNkJBQTZCbEIsR0FBN0IsRUFBa0NDLFVBQWxDLENBQVA7QUFDRDs7QUFFRCxJQUFNMEIsNkJBQTZCLDBCQUFuQztBQUNBLElBQU1DLDJCQUEyQix3QkFBakM7QUFDQSxJQUFNQyx5QkFBeUIsc0JBQS9CO0FBQ0EsSUFBTUMscUJBQXFCLG1CQUEzQjtBQUNBLElBQU1DLDZCQUE2QiwwQkFBbkM7QUFDQSxJQUFNQywyQkFBMkIsd0JBQWpDO0FBQ0EsSUFBTUMsdUJBQXVCLHFCQUE3QjtBQUNBLElBQU1DLHVCQUF1QixxQkFBN0I7QUFDQSxJQUFNQyxvQkFBb0Isa0JBQTFCO0FBQ0EsSUFBTUMsYUFBYSxZQUFuQjtBQUNBLElBQU1DLGlCQUFpQixlQUF2QjtBQUNBLElBQU1DLGdCQUFnQixjQUF0QjtBQUNBLElBQU1DLDJCQUEyQix3QkFBakM7QUFDQSxJQUFNQyw0QkFBNEIsd0JBQWxDO0FBQ0EsSUFBTUMsc0JBQXNCLG1CQUE1QjtBQUNBLElBQU1DLFVBQVUsU0FBaEI7O0FBRUEsU0FBU0MsNEJBQVQsQ0FBc0NDLFdBQXRDLEVBQW1EQyxFQUFuRCxFQUF1RDtBQUNyRCxNQUFJRCxXQUFKLEVBQWlCO0FBQ2YsUUFBTUUsb0JBQW9CRixZQUFZRyxJQUFaLEtBQXFCUix3QkFBckI7QUFDckJLLGdCQUFZRyxJQUFaLEtBQXFCUCx5QkFEQTtBQUVyQkksZ0JBQVlHLElBQVosS0FBcUJOLG1CQUYxQjs7QUFJQTtBQUNFRyxnQkFBWUcsSUFBWixLQUFxQmIsb0JBQXJCO0FBQ0dVLGdCQUFZRyxJQUFaLEtBQXFCWixpQkFEeEI7QUFFR1cscUJBSEw7QUFJRTtBQUNBRCxTQUFHRCxZQUFZSSxFQUFaLENBQWVDLElBQWxCLEVBQXdCSCxpQkFBeEI7QUFDRCxLQU5ELE1BTU8sSUFBSUYsWUFBWUcsSUFBWixLQUFxQmQsb0JBQXpCLEVBQStDO0FBQ3BEVyxrQkFBWU0sWUFBWixDQUF5QkMsT0FBekIsQ0FBaUMsaUJBQVksS0FBVEgsRUFBUyxTQUFUQSxFQUFTO0FBQzNDLFlBQUlBLEdBQUdELElBQUgsS0FBWVYsY0FBaEIsRUFBZ0M7QUFDOUIsMkNBQXdCVyxFQUF4QixFQUE0QixVQUFDekIsT0FBRCxFQUFhO0FBQ3ZDLGdCQUFJQSxRQUFRd0IsSUFBUixLQUFpQlgsVUFBckIsRUFBaUM7QUFDL0JTLGlCQUFHdEIsUUFBUTBCLElBQVgsRUFBaUIsS0FBakI7QUFDRDtBQUNGLFdBSkQ7QUFLRCxTQU5ELE1BTU8sSUFBSUQsR0FBR0QsSUFBSCxLQUFZVCxhQUFoQixFQUErQjtBQUNwQ1UsYUFBR0ksUUFBSCxDQUFZRCxPQUFaLENBQW9CLGlCQUFjLEtBQVhGLElBQVcsU0FBWEEsSUFBVztBQUNoQ0osZUFBR0ksSUFBSCxFQUFTLEtBQVQ7QUFDRCxXQUZEO0FBR0QsU0FKTSxNQUlBO0FBQ0xKLGFBQUdHLEdBQUdDLElBQU4sRUFBWSxLQUFaO0FBQ0Q7QUFDRixPQWREO0FBZUQ7QUFDRjtBQUNGOztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbUJBLElBQU1JLGFBQWEsSUFBSUMsR0FBSixFQUFuQjs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXlCQSxJQUFNQyxhQUFhLElBQUlELEdBQUosRUFBbkI7O0FBRUEsSUFBTUUsZ0JBQWdCLElBQUlGLEdBQUosRUFBdEI7O0FBRUE7QUFDQSxJQUFNRyxlQUFlLElBQUlDLEdBQUosRUFBckI7QUFDQSxJQUFNQyxrQkFBa0IsSUFBSUQsR0FBSixFQUF4Qjs7QUFFQSxJQUFNRSxlQUFlLFNBQWZBLFlBQWUsQ0FBQ0MsSUFBRCxVQUFXLHFCQUFELENBQXVCbkMsSUFBdkIsQ0FBNEJtQyxJQUE1QixDQUFWLEdBQXJCOztBQUVBOzs7Ozs7QUFNQSxTQUFTQyxZQUFULENBQXNCOUQsR0FBdEIsRUFBMkIrRCxhQUEzQixFQUEwQ0MsT0FBMUMsRUFBbUQ7QUFDakQsTUFBTS9ELGFBQWFRLE1BQU1DLElBQU4sQ0FBVywrQkFBa0JzRCxRQUFRQyxRQUExQixDQUFYLENBQW5COztBQUVBLE1BQU1DLGNBQWM5QyxtQkFBbUJwQixHQUFuQixFQUF3QkMsVUFBeEIsQ0FBcEI7O0FBRUE7QUFDQSxNQUFNa0UsbUJBQW1CL0MsbUJBQW1CMkMsYUFBbkIsRUFBa0M5RCxVQUFsQyxDQUF6Qjs7QUFFQTtBQUNBLE1BQUlrRSxpQkFBaUJDLE1BQWpCLElBQTJCLE9BQU9ELGlCQUFpQixDQUFqQixDQUFQLEtBQStCLFFBQTlELEVBQXdFO0FBQ3RFQSxxQkFBaUJoQixPQUFqQixDQUF5QixVQUFDckMsUUFBRCxVQUFjMkMsYUFBYVksR0FBYixDQUFpQnZELFFBQWpCLENBQWQsRUFBekI7QUFDRCxHQUZELE1BRU87QUFDTHFELHFCQUFpQmhCLE9BQWpCLENBQXlCLHNCQUFHckMsUUFBSCxTQUFHQSxRQUFILFFBQWtCMkMsYUFBYVksR0FBYixDQUFpQnZELFFBQWpCLENBQWxCLEVBQXpCO0FBQ0Q7O0FBRUQ7QUFDQSxNQUFNd0QsZ0JBQWdCSixZQUFZRSxNQUFaLElBQXNCLE9BQU9GLFlBQVksQ0FBWixDQUFQLEtBQTBCLFFBQWhEO0FBQ2xCQSxjQUFZSyxNQUFaLENBQW1CLFVBQUMzRCxRQUFELFVBQWMsQ0FBQ2dELGFBQWFoRCxRQUFiLENBQWYsRUFBbkIsQ0FEa0I7QUFFbEIsbUNBQVFzRCxXQUFSLEVBQXFCLHNCQUFHcEQsUUFBSCxTQUFHQSxRQUFILFFBQWtCOEMsYUFBYTlDLFFBQWIsSUFBeUIsRUFBekIsR0FBOEJBLFFBQWhELEVBQXJCLENBRko7O0FBSUEsU0FBTyxJQUFJNEMsR0FBSixDQUFRWSxhQUFSLENBQVA7QUFDRDs7QUFFRDs7O0FBR0EsSUFBTUUsMkJBQTJCLFNBQTNCQSx3QkFBMkIsQ0FBQ0MsUUFBRCxFQUFXVCxPQUFYLEVBQXVCO0FBQ3RELE1BQU1VLFlBQVksSUFBSXBCLEdBQUosRUFBbEI7QUFDQW1CLFdBQVN0QixPQUFULENBQWlCLFVBQUN3QixJQUFELEVBQVU7QUFDekIsUUFBTUMsVUFBVSxJQUFJdEIsR0FBSixFQUFoQjtBQUNBLFFBQU11QixVQUFVLElBQUl2QixHQUFKLEVBQWhCO0FBQ0EsUUFBTXdCLGlCQUFpQkMscUJBQWlCQyxHQUFqQixDQUFxQkwsSUFBckIsRUFBMkJYLE9BQTNCLENBQXZCO0FBQ0EsUUFBSWMsY0FBSixFQUFvQjs7QUFFaEJHLGtCQUZnQjs7Ozs7QUFPZEgsb0JBUGMsQ0FFaEJHLFlBRmdCLENBR2hCQyxTQUhnQixHQU9kSixjQVBjLENBR2hCSSxTQUhnQixDQUlQQyxlQUpPLEdBT2RMLGNBUGMsQ0FJaEJELE9BSmdCLENBS2hCTyxTQUxnQixHQU9kTixjQVBjLENBS2hCTSxTQUxnQixDQU1oQkMsV0FOZ0IsR0FPZFAsY0FQYyxDQU1oQk8sV0FOZ0I7O0FBU2xCN0Isb0JBQWM4QixHQUFkLENBQWtCWCxJQUFsQixFQUF3QlUsV0FBeEI7QUFDQTtBQUNBLFVBQU1FLG1CQUFtQixJQUFJN0IsR0FBSixFQUF6QjtBQUNBdUIsbUJBQWE5QixPQUFiLENBQXFCLFVBQUNxQyxhQUFELEVBQW1CO0FBQ3RDLFlBQU1DLGFBQWFELGVBQW5CO0FBQ0EsWUFBSUMsZUFBZSxJQUFuQixFQUF5QjtBQUN2QjtBQUNEOztBQUVERix5QkFBaUJsQixHQUFqQixDQUFxQm9CLFdBQVc1QixJQUFoQztBQUNELE9BUEQ7QUFRQWEsZ0JBQVVZLEdBQVYsQ0FBY1gsSUFBZCxFQUFvQlksZ0JBQXBCOztBQUVBTCxnQkFBVS9CLE9BQVYsQ0FBa0IsVUFBQ3VDLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUNoQyxZQUFJQSxRQUFRakQsT0FBWixFQUFxQjtBQUNuQmtDLGtCQUFRVSxHQUFSLENBQVl0RCx3QkFBWixFQUFzQyxFQUFFNEQsV0FBVyxJQUFJbEMsR0FBSixFQUFiLEVBQXRDO0FBQ0QsU0FGRCxNQUVPO0FBQ0xrQixrQkFBUVUsR0FBUixDQUFZSyxHQUFaLEVBQWlCLEVBQUVDLFdBQVcsSUFBSWxDLEdBQUosRUFBYixFQUFqQjtBQUNEO0FBQ0QsWUFBTW1DLFdBQVdILE1BQU1JLFNBQU4sRUFBakI7QUFDQSxZQUFJLENBQUNELFFBQUwsRUFBZTtBQUNiO0FBQ0Q7QUFDRCxZQUFJRSxjQUFjbEIsUUFBUUcsR0FBUixDQUFZYSxTQUFTaEMsSUFBckIsQ0FBbEI7QUFDQSxZQUFJbUMscUJBQUo7QUFDQSxZQUFJTixNQUFNTyxLQUFOLEtBQWdCdkQsT0FBcEIsRUFBNkI7QUFDM0JzRCx5QkFBZWhFLHdCQUFmO0FBQ0QsU0FGRCxNQUVPO0FBQ0xnRSx5QkFBZU4sTUFBTU8sS0FBckI7QUFDRDtBQUNELFlBQUksT0FBT0YsV0FBUCxLQUF1QixXQUEzQixFQUF3QztBQUN0Q0Esd0JBQWMsSUFBSXJDLEdBQUosOEJBQVlxQyxXQUFaLElBQXlCQyxZQUF6QixHQUFkO0FBQ0QsU0FGRCxNQUVPO0FBQ0xELHdCQUFjLElBQUlyQyxHQUFKLENBQVEsQ0FBQ3NDLFlBQUQsQ0FBUixDQUFkO0FBQ0Q7QUFDRG5CLGdCQUFRUyxHQUFSLENBQVlPLFNBQVNoQyxJQUFyQixFQUEyQmtDLFdBQTNCO0FBQ0QsT0F2QkQ7O0FBeUJBWixzQkFBZ0JoQyxPQUFoQixDQUF3QixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ3RDLFlBQUkvQixhQUFhK0IsR0FBYixDQUFKLEVBQXVCO0FBQ3JCO0FBQ0Q7QUFDRCxZQUFNSSxjQUFjbEIsUUFBUUcsR0FBUixDQUFZVyxHQUFaLEtBQW9CLElBQUlqQyxHQUFKLEVBQXhDO0FBQ0FnQyxjQUFNeEMsWUFBTixDQUFtQkMsT0FBbkIsQ0FBMkIsaUJBQTRCLEtBQXpCK0Msa0JBQXlCLFNBQXpCQSxrQkFBeUI7QUFDckRBLDZCQUFtQi9DLE9BQW5CLENBQTJCLFVBQUNnRCxTQUFELEVBQWU7QUFDeENKLHdCQUFZMUIsR0FBWixDQUFnQjhCLFNBQWhCO0FBQ0QsV0FGRDtBQUdELFNBSkQ7QUFLQXRCLGdCQUFRUyxHQUFSLENBQVlLLEdBQVosRUFBaUJJLFdBQWpCO0FBQ0QsT0FYRDtBQVlBMUMsaUJBQVdpQyxHQUFYLENBQWVYLElBQWYsRUFBcUJFLE9BQXJCOztBQUVBO0FBQ0EsVUFBSXBCLGFBQWEyQyxHQUFiLENBQWlCekIsSUFBakIsQ0FBSixFQUE0QjtBQUMxQjtBQUNEO0FBQ0RTLGdCQUFVakMsT0FBVixDQUFrQixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2hDLFlBQUlBLFFBQVFqRCxPQUFaLEVBQXFCO0FBQ25Ca0Msa0JBQVFVLEdBQVIsQ0FBWXRELHdCQUFaLEVBQXNDLEVBQUU0RCxXQUFXLElBQUlsQyxHQUFKLEVBQWIsRUFBdEM7QUFDRCxTQUZELE1BRU87QUFDTGtCLGtCQUFRVSxHQUFSLENBQVlLLEdBQVosRUFBaUIsRUFBRUMsV0FBVyxJQUFJbEMsR0FBSixFQUFiLEVBQWpCO0FBQ0Q7QUFDRixPQU5EO0FBT0Q7QUFDRGtCLFlBQVFVLEdBQVIsQ0FBWXpELHNCQUFaLEVBQW9DLEVBQUUrRCxXQUFXLElBQUlsQyxHQUFKLEVBQWIsRUFBcEM7QUFDQWtCLFlBQVFVLEdBQVIsQ0FBWXZELDBCQUFaLEVBQXdDLEVBQUU2RCxXQUFXLElBQUlsQyxHQUFKLEVBQWIsRUFBeEM7QUFDQUgsZUFBVytCLEdBQVgsQ0FBZVgsSUFBZixFQUFxQkMsT0FBckI7QUFDRCxHQWhGRDtBQWlGQUYsWUFBVXZCLE9BQVYsQ0FBa0IsVUFBQ3VDLEtBQUQsRUFBUUMsR0FBUixFQUFnQjtBQUNoQ0QsVUFBTXZDLE9BQU4sQ0FBYyxVQUFDa0QsR0FBRCxFQUFTO0FBQ3JCLFVBQU12QixpQkFBaUJ2QixXQUFXeUIsR0FBWCxDQUFlcUIsR0FBZixDQUF2QjtBQUNBLFVBQUl2QixjQUFKLEVBQW9CO0FBQ2xCLFlBQU13QixnQkFBZ0J4QixlQUFlRSxHQUFmLENBQW1CbkQsc0JBQW5CLENBQXRCO0FBQ0F5RSxzQkFBY1YsU0FBZCxDQUF3QnZCLEdBQXhCLENBQTRCc0IsR0FBNUI7QUFDRDtBQUNGLEtBTkQ7QUFPRCxHQVJEO0FBU0QsQ0E1RkQ7O0FBOEZBOzs7O0FBSUEsSUFBTVksaUJBQWlCLFNBQWpCQSxjQUFpQixHQUFNO0FBQzNCbEQsYUFBV0YsT0FBWCxDQUFtQixVQUFDcUQsU0FBRCxFQUFZQyxPQUFaLEVBQXdCO0FBQ3pDRCxjQUFVckQsT0FBVixDQUFrQixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2hDLFVBQU1mLFVBQVVyQixXQUFXeUIsR0FBWCxDQUFlVyxHQUFmLENBQWhCO0FBQ0EsVUFBSSxPQUFPZixPQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDYyxjQUFNdkMsT0FBTixDQUFjLFVBQUN1RCxhQUFELEVBQW1CO0FBQy9CLGNBQUlQLGtCQUFKO0FBQ0EsY0FBSU8sa0JBQWtCM0UsMEJBQXRCLEVBQWtEO0FBQ2hEb0Usd0JBQVlwRSwwQkFBWjtBQUNELFdBRkQsTUFFTyxJQUFJMkUsa0JBQWtCMUUsd0JBQXRCLEVBQWdEO0FBQ3JEbUUsd0JBQVluRSx3QkFBWjtBQUNELFdBRk0sTUFFQTtBQUNMbUUsd0JBQVlPLGFBQVo7QUFDRDtBQUNELGNBQUksT0FBT1AsU0FBUCxLQUFxQixXQUF6QixFQUFzQztBQUNwQyxnQkFBTVEsa0JBQWtCL0IsUUFBUUksR0FBUixDQUFZbUIsU0FBWixDQUF4QjtBQUNBLGdCQUFJLE9BQU9RLGVBQVAsS0FBMkIsV0FBL0IsRUFBNEM7QUFDbENmLHVCQURrQyxHQUNwQmUsZUFEb0IsQ0FDbENmLFNBRGtDO0FBRTFDQSx3QkFBVXZCLEdBQVYsQ0FBY29DLE9BQWQ7QUFDQTdCLHNCQUFRVSxHQUFSLENBQVlhLFNBQVosRUFBdUIsRUFBRVAsb0JBQUYsRUFBdkI7QUFDRDtBQUNGO0FBQ0YsU0FqQkQ7QUFrQkQ7QUFDRixLQXRCRDtBQXVCRCxHQXhCRDtBQXlCRCxDQTFCRDs7QUE0QkEsSUFBTWdCLFNBQVMsU0FBVEEsTUFBUyxDQUFDNUcsR0FBRCxFQUFTO0FBQ3RCLE1BQUlBLEdBQUosRUFBUztBQUNQLFdBQU9BLEdBQVA7QUFDRDtBQUNELFNBQU8sQ0FBQ0csUUFBUTBHLEdBQVIsRUFBRCxDQUFQO0FBQ0QsQ0FMRDs7QUFPQTs7OztBQUlBO0FBQ0EsSUFBSXBDLGlCQUFKO0FBQ0EsSUFBSXFDLHVCQUFKO0FBQ0EsSUFBTUMsZ0JBQWdCLFNBQWhCQSxhQUFnQixDQUFDL0csR0FBRCxFQUFNK0QsYUFBTixFQUFxQkMsT0FBckIsRUFBaUM7QUFDckQsTUFBTWdELGFBQWFDLEtBQUtDLFNBQUwsQ0FBZTtBQUNoQ2xILFNBQUssQ0FBQ0EsT0FBTyxFQUFSLEVBQVltSCxJQUFaLEVBRDJCO0FBRWhDcEQsbUJBQWUsQ0FBQ0EsaUJBQWlCLEVBQWxCLEVBQXNCb0QsSUFBdEIsRUFGaUI7QUFHaENsSCxnQkFBWVEsTUFBTUMsSUFBTixDQUFXLCtCQUFrQnNELFFBQVFDLFFBQTFCLENBQVgsRUFBZ0RrRCxJQUFoRCxFQUhvQixFQUFmLENBQW5COztBQUtBLE1BQUlILGVBQWVGLGNBQW5CLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBRUR6RCxhQUFXK0QsS0FBWDtBQUNBN0QsYUFBVzZELEtBQVg7QUFDQTNELGVBQWEyRCxLQUFiO0FBQ0F6RCxrQkFBZ0J5RCxLQUFoQjs7QUFFQTNDLGFBQVdYLGFBQWE4QyxPQUFPNUcsR0FBUCxDQUFiLEVBQTBCK0QsYUFBMUIsRUFBeUNDLE9BQXpDLENBQVg7QUFDQVEsMkJBQXlCQyxRQUF6QixFQUFtQ1QsT0FBbkM7QUFDQXVDO0FBQ0FPLG1CQUFpQkUsVUFBakI7QUFDRCxDQW5CRDs7QUFxQkEsSUFBTUssMkJBQTJCLFNBQTNCQSx3QkFBMkIsQ0FBQ0MsVUFBRCxVQUFnQkEsV0FBV0MsSUFBWCxDQUFnQixzQkFBR3hFLElBQUgsU0FBR0EsSUFBSCxRQUFjQSxTQUFTaEIsMEJBQXZCLEVBQWhCLENBQWhCLEVBQWpDOztBQUVBLElBQU15Rix5QkFBeUIsU0FBekJBLHNCQUF5QixDQUFDRixVQUFELFVBQWdCQSxXQUFXQyxJQUFYLENBQWdCLHNCQUFHeEUsSUFBSCxTQUFHQSxJQUFILFFBQWNBLFNBQVNmLHdCQUF2QixFQUFoQixDQUFoQixFQUEvQjs7QUFFQSxJQUFNeUYsY0FBYyxTQUFkQSxXQUFjLENBQUM5QyxJQUFELEVBQVU7QUFDTiw4QkFBVSxFQUFFa0MsS0FBS2xDLElBQVAsRUFBVixDQURNLENBQ3BCZCxJQURvQixjQUNwQkEsSUFEb0IsQ0FDZDZELEdBRGMsY0FDZEEsR0FEYztBQUU1QixNQUFNQyxXQUFXLG1CQUFROUQsSUFBUixDQUFqQjs7QUFFQSxNQUFNK0Qsc0JBQXNCLFNBQXRCQSxtQkFBc0IsQ0FBQ0MsUUFBRCxFQUFjO0FBQ3hDLFFBQUksZ0JBQUtGLFFBQUwsRUFBZUUsUUFBZixNQUE2QmxELElBQWpDLEVBQXVDO0FBQ3JDLGFBQU8sSUFBUDtBQUNEO0FBQ0YsR0FKRDs7QUFNQSxNQUFNbUQsc0JBQXNCLFNBQXRCQSxtQkFBc0IsQ0FBQ0QsUUFBRCxFQUFjO0FBQ3hDLFFBQU1FLGdCQUFnQixpQ0FBUSx5QkFBT0YsUUFBUCxDQUFSLEVBQTBCLFVBQUNuQyxLQUFELFVBQVcsT0FBT0EsS0FBUCxLQUFpQixTQUFqQixHQUE2QixFQUE3QixHQUFrQyxnQkFBS2lDLFFBQUwsRUFBZWpDLEtBQWYsQ0FBN0MsRUFBMUIsQ0FBdEI7O0FBRUEsUUFBSSxnQ0FBU3FDLGFBQVQsRUFBd0JwRCxJQUF4QixDQUFKLEVBQW1DO0FBQ2pDLGFBQU8sSUFBUDtBQUNEO0FBQ0YsR0FORDs7QUFRQSxNQUFNcUQsZ0JBQWdCLFNBQWhCQSxhQUFnQixDQUFDSCxRQUFELEVBQWM7QUFDbEMsUUFBSSxPQUFPQSxRQUFQLEtBQW9CLFFBQXhCLEVBQWtDO0FBQ2hDLGFBQU9ELG9CQUFvQkMsUUFBcEIsQ0FBUDtBQUNEOztBQUVELFFBQUksUUFBT0EsUUFBUCx5Q0FBT0EsUUFBUCxPQUFvQixRQUF4QixFQUFrQztBQUNoQyxhQUFPQyxvQkFBb0JELFFBQXBCLENBQVA7QUFDRDtBQUNGLEdBUkQ7O0FBVUEsTUFBSUgsbUJBQWdCLElBQXBCLEVBQTBCO0FBQ3hCLFdBQU8sS0FBUDtBQUNEOztBQUVELE1BQUlBLElBQUlPLEdBQVIsRUFBYTtBQUNYLFFBQUlELGNBQWNOLElBQUlPLEdBQWxCLENBQUosRUFBNEI7QUFDMUIsYUFBTyxJQUFQO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJUCxJQUFJUSxPQUFSLEVBQWlCO0FBQ2YsUUFBSUYsY0FBY04sSUFBSVEsT0FBbEIsQ0FBSixFQUFnQztBQUM5QixhQUFPLElBQVA7QUFDRDtBQUNGOztBQUVELE1BQUlSLElBQUlTLElBQVIsRUFBYztBQUNaLFFBQUlQLG9CQUFvQkYsSUFBSVMsSUFBeEIsQ0FBSixFQUFtQztBQUNqQyxhQUFPLElBQVA7QUFDRDtBQUNGOztBQUVELFNBQU8sS0FBUDtBQUNELENBbkREOztBQXFEQUMsT0FBT3hELE9BQVAsR0FBaUI7QUFDZnlELFFBQU07QUFDSnRGLFVBQU0sWUFERjtBQUVKdUYsVUFBTTtBQUNKQyxnQkFBVSxrQkFETjtBQUVKQyxtQkFBYSx1RkFGVDtBQUdKQyxXQUFLLDBCQUFRLG1CQUFSLENBSEQsRUFGRjs7QUFPSkMsWUFBUSxDQUFDO0FBQ1BDLGtCQUFZO0FBQ1YzSSxhQUFLO0FBQ0h3SSx1QkFBYSxzREFEVjtBQUVIekYsZ0JBQU0sT0FGSDtBQUdINkYsdUJBQWEsSUFIVjtBQUlIQyxpQkFBTztBQUNMOUYsa0JBQU0sUUFERDtBQUVMK0YsdUJBQVcsQ0FGTixFQUpKLEVBREs7OztBQVVWL0UsdUJBQWU7QUFDYnlFLHVCQUFhLHFGQURBO0FBRWJ6RixnQkFBTSxPQUZPO0FBR2I2Rix1QkFBYSxJQUhBO0FBSWJDLGlCQUFPO0FBQ0w5RixrQkFBTSxRQUREO0FBRUwrRix1QkFBVyxDQUZOLEVBSk0sRUFWTDs7O0FBbUJWQyx3QkFBZ0I7QUFDZFAsdUJBQWEsb0NBREM7QUFFZHpGLGdCQUFNLFNBRlEsRUFuQk47O0FBdUJWaUcsdUJBQWU7QUFDYlIsdUJBQWEsa0NBREE7QUFFYnpGLGdCQUFNLFNBRk8sRUF2Qkw7O0FBMkJWa0csaUNBQXlCO0FBQ3ZCVCx1QkFBYSx1Q0FEVTtBQUV2QnpGLGdCQUFNLFNBRmlCLEVBM0JmLEVBREw7OztBQWlDUG1HLGFBQU87QUFDTDtBQUNFUCxvQkFBWTtBQUNWSyx5QkFBZSxFQUFFLFFBQU0sQ0FBQyxJQUFELENBQVIsRUFETDtBQUVWaEosZUFBSztBQUNIbUosc0JBQVUsQ0FEUCxFQUZLLEVBRGQ7OztBQU9FQyxrQkFBVSxDQUFDLGVBQUQsQ0FQWixFQURLOztBQVVMO0FBQ0VULG9CQUFZO0FBQ1ZJLDBCQUFnQixFQUFFLFFBQU0sQ0FBQyxJQUFELENBQVIsRUFETixFQURkOztBQUlFSyxrQkFBVSxDQUFDLGdCQUFELENBSlosRUFWSyxDQWpDQSxFQUFELENBUEosRUFEUzs7Ozs7O0FBNkRmQyxRQTdEZSwrQkE2RFJyRixPQTdEUSxFQTZEQzs7Ozs7OztBQU9WQSxjQUFRc0YsT0FBUixDQUFnQixDQUFoQixLQUFzQixFQVBaLENBRVp0SixHQUZZLFNBRVpBLEdBRlksNkJBR1orRCxhQUhZLENBR1pBLGFBSFksdUNBR0ksRUFISix1QkFJWmdGLGNBSlksU0FJWkEsY0FKWSxDQUtaQyxhQUxZLFNBS1pBLGFBTFksQ0FNWkMsdUJBTlksU0FNWkEsdUJBTlk7O0FBU2QsVUFBSUQsYUFBSixFQUFtQjtBQUNqQmpDLHNCQUFjL0csR0FBZCxFQUFtQitELGFBQW5CLEVBQWtDQyxPQUFsQztBQUNEOztBQUVELFVBQU1XLE9BQU8sd0NBQW9CWCxPQUFwQixDQUFiOztBQUVBLFVBQU11RixtQ0FBc0IsU0FBdEJBLG1CQUFzQixDQUFDQyxJQUFELEVBQVU7QUFDcEMsY0FBSSxDQUFDVCxjQUFMLEVBQXFCO0FBQ25CO0FBQ0Q7O0FBRUQsY0FBSXRGLGFBQWEyQyxHQUFiLENBQWlCekIsSUFBakIsQ0FBSixFQUE0QjtBQUMxQjtBQUNEOztBQUVELGNBQU04RSxjQUFjbEcsV0FBV3lCLEdBQVgsQ0FBZUwsSUFBZixDQUFwQjtBQUNBLGNBQU1ELFlBQVkrRSxZQUFZekUsR0FBWixDQUFnQm5ELHNCQUFoQixDQUFsQjtBQUNBLGNBQU02SCxtQkFBbUJELFlBQVl6RSxHQUFaLENBQWdCakQsMEJBQWhCLENBQXpCOztBQUVBMEgsZ0NBQW1CNUgsc0JBQW5CO0FBQ0E0SCxnQ0FBbUIxSCwwQkFBbkI7QUFDQSxjQUFJMEgsWUFBWUUsSUFBWixHQUFtQixDQUF2QixFQUEwQjtBQUN4QjtBQUNBO0FBQ0EzRixvQkFBUTRGLE1BQVIsQ0FBZUosS0FBS0ssSUFBTCxDQUFVLENBQVYsSUFBZUwsS0FBS0ssSUFBTCxDQUFVLENBQVYsQ0FBZixHQUE4QkwsSUFBN0MsRUFBbUQsa0JBQW5EO0FBQ0Q7QUFDREMsc0JBQVluRSxHQUFaLENBQWdCekQsc0JBQWhCLEVBQXdDNkMsU0FBeEM7QUFDQStFLHNCQUFZbkUsR0FBWixDQUFnQnZELDBCQUFoQixFQUE0QzJILGdCQUE1QztBQUNELFNBdEJLLDhCQUFOOztBQXdCQSxVQUFNSSwwQkFBYSxTQUFiQSxVQUFhLENBQUNOLElBQUQsRUFBT08sYUFBUCxFQUFzQkMsWUFBdEIsRUFBdUM7QUFDeEQsY0FBSSxDQUFDaEIsYUFBTCxFQUFvQjtBQUNsQjtBQUNEOztBQUVELGNBQUlnQixnQkFBZ0JmLHVCQUFwQixFQUE2QztBQUMzQztBQUNEOztBQUVELGNBQUl4RixhQUFhMkMsR0FBYixDQUFpQnpCLElBQWpCLENBQUosRUFBNEI7QUFDMUI7QUFDRDs7QUFFRCxjQUFJOEMsWUFBWTlDLElBQVosQ0FBSixFQUF1QjtBQUNyQjtBQUNEOztBQUVELGNBQUloQixnQkFBZ0J5QyxHQUFoQixDQUFvQnpCLElBQXBCLENBQUosRUFBK0I7QUFDN0I7QUFDRDs7QUFFRDtBQUNBLGNBQUksQ0FBQ0YsU0FBUzJCLEdBQVQsQ0FBYXpCLElBQWIsQ0FBTCxFQUF5QjtBQUN2QkYsdUJBQVdYLGFBQWE4QyxPQUFPNUcsR0FBUCxDQUFiLEVBQTBCK0QsYUFBMUIsRUFBeUNDLE9BQXpDLENBQVg7QUFDQSxnQkFBSSxDQUFDUyxTQUFTMkIsR0FBVCxDQUFhekIsSUFBYixDQUFMLEVBQXlCO0FBQ3ZCaEIsOEJBQWdCVSxHQUFoQixDQUFvQk0sSUFBcEI7QUFDQTtBQUNEO0FBQ0Y7O0FBRURDLG9CQUFVckIsV0FBV3lCLEdBQVgsQ0FBZUwsSUFBZixDQUFWOztBQUVBLGNBQUksQ0FBQ0MsT0FBTCxFQUFjO0FBQ1pxRixvQkFBUUMsS0FBUixtQkFBd0J2RixJQUF4QjtBQUNEOztBQUVEO0FBQ0EsY0FBTUQsWUFBWUUsUUFBUUksR0FBUixDQUFZbkQsc0JBQVosQ0FBbEI7QUFDQSxjQUFJLE9BQU82QyxTQUFQLEtBQXFCLFdBQXJCLElBQW9DcUYsa0JBQWtCL0gsd0JBQTFELEVBQW9GO0FBQ2xGLGdCQUFJMEMsVUFBVWtCLFNBQVYsQ0FBb0IrRCxJQUFwQixHQUEyQixDQUEvQixFQUFrQztBQUNoQztBQUNEO0FBQ0Y7O0FBRUQ7QUFDQSxjQUFNRCxtQkFBbUI5RSxRQUFRSSxHQUFSLENBQVlqRCwwQkFBWixDQUF6QjtBQUNBLGNBQUksT0FBTzJILGdCQUFQLEtBQTRCLFdBQWhDLEVBQTZDO0FBQzNDLGdCQUFJQSxpQkFBaUI5RCxTQUFqQixDQUEyQitELElBQTNCLEdBQWtDLENBQXRDLEVBQXlDO0FBQ3ZDO0FBQ0Q7QUFDRjs7QUFFRDtBQUNBLGNBQU1RLGFBQWFKLGtCQUFrQnJILE9BQWxCLEdBQTRCVix3QkFBNUIsR0FBdUQrSCxhQUExRTs7QUFFQSxjQUFNcEQsa0JBQWtCL0IsUUFBUUksR0FBUixDQUFZbUYsVUFBWixDQUF4Qjs7QUFFQSxjQUFNekUsUUFBUXlFLGVBQWVuSSx3QkFBZixHQUEwQ1UsT0FBMUMsR0FBb0R5SCxVQUFsRTs7QUFFQSxjQUFJLE9BQU94RCxlQUFQLEtBQTJCLFdBQS9CLEVBQTRDO0FBQzFDLGdCQUFJQSxnQkFBZ0JmLFNBQWhCLENBQTBCK0QsSUFBMUIsR0FBaUMsQ0FBckMsRUFBd0M7QUFDdEMzRixzQkFBUTRGLE1BQVI7QUFDRUosa0JBREY7QUFFMkI5RCxtQkFGM0I7O0FBSUQ7QUFDRixXQVBELE1BT087QUFDTDFCLG9CQUFRNEYsTUFBUjtBQUNFSixnQkFERjtBQUUyQjlELGlCQUYzQjs7QUFJRDtBQUNGLFNBeEVLLHFCQUFOOztBQTBFQTs7Ozs7QUFLQSxVQUFNMEUsaUNBQW9CLFNBQXBCQSxpQkFBb0IsQ0FBQ1osSUFBRCxFQUFVO0FBQ2xDLGNBQUkvRixhQUFhMkMsR0FBYixDQUFpQnpCLElBQWpCLENBQUosRUFBNEI7QUFDMUI7QUFDRDs7QUFFRCxjQUFJQyxVQUFVckIsV0FBV3lCLEdBQVgsQ0FBZUwsSUFBZixDQUFkOztBQUVBO0FBQ0E7QUFDQSxjQUFJLE9BQU9DLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLHNCQUFVLElBQUl0QixHQUFKLEVBQVY7QUFDRDs7QUFFRCxjQUFNK0csYUFBYSxJQUFJL0csR0FBSixFQUFuQjtBQUNBLGNBQU1nSCx1QkFBdUIsSUFBSTVHLEdBQUosRUFBN0I7O0FBRUE4RixlQUFLSyxJQUFMLENBQVUxRyxPQUFWLENBQWtCLGtCQUF1QyxLQUFwQ0osSUFBb0MsVUFBcENBLElBQW9DLENBQTlCSCxXQUE4QixVQUE5QkEsV0FBOEIsQ0FBakIwRSxVQUFpQixVQUFqQkEsVUFBaUI7QUFDdkQsZ0JBQUl2RSxTQUFTcEIsMEJBQWIsRUFBeUM7QUFDdkMySSxtQ0FBcUJqRyxHQUFyQixDQUF5QnJDLHdCQUF6QjtBQUNEO0FBQ0QsZ0JBQUllLFNBQVNuQix3QkFBYixFQUF1QztBQUNyQyxrQkFBSTBGLFdBQVdsRCxNQUFYLEdBQW9CLENBQXhCLEVBQTJCO0FBQ3pCa0QsMkJBQVduRSxPQUFYLENBQW1CLFVBQUNnRCxTQUFELEVBQWU7QUFDaEMsc0JBQUlBLFVBQVVvRSxRQUFkLEVBQXdCO0FBQ3RCRCx5Q0FBcUJqRyxHQUFyQixDQUF5QjhCLFVBQVVvRSxRQUFWLENBQW1CdEgsSUFBbkIsSUFBMkJrRCxVQUFVb0UsUUFBVixDQUFtQjdFLEtBQXZFO0FBQ0Q7QUFDRixpQkFKRDtBQUtEO0FBQ0QvQywyQ0FBNkJDLFdBQTdCLEVBQTBDLFVBQUNLLElBQUQsRUFBVTtBQUNsRHFILHFDQUFxQmpHLEdBQXJCLENBQXlCcEIsSUFBekI7QUFDRCxlQUZEO0FBR0Q7QUFDRixXQWhCRDs7QUFrQkE7QUFDQTJCLGtCQUFRekIsT0FBUixDQUFnQixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQzlCLGdCQUFJMkUscUJBQXFCbEUsR0FBckIsQ0FBeUJULEdBQXpCLENBQUosRUFBbUM7QUFDakMwRSx5QkFBVy9FLEdBQVgsQ0FBZUssR0FBZixFQUFvQkQsS0FBcEI7QUFDRDtBQUNGLFdBSkQ7O0FBTUE7QUFDQTRFLCtCQUFxQm5ILE9BQXJCLENBQTZCLFVBQUN3QyxHQUFELEVBQVM7QUFDcEMsZ0JBQUksQ0FBQ2YsUUFBUXdCLEdBQVIsQ0FBWVQsR0FBWixDQUFMLEVBQXVCO0FBQ3JCMEUseUJBQVcvRSxHQUFYLENBQWVLLEdBQWYsRUFBb0IsRUFBRUMsV0FBVyxJQUFJbEMsR0FBSixFQUFiLEVBQXBCO0FBQ0Q7QUFDRixXQUpEOztBQU1BO0FBQ0EsY0FBTWdCLFlBQVlFLFFBQVFJLEdBQVIsQ0FBWW5ELHNCQUFaLENBQWxCO0FBQ0EsY0FBSTZILG1CQUFtQjlFLFFBQVFJLEdBQVIsQ0FBWWpELDBCQUFaLENBQXZCOztBQUVBLGNBQUksT0FBTzJILGdCQUFQLEtBQTRCLFdBQWhDLEVBQTZDO0FBQzNDQSwrQkFBbUIsRUFBRTlELFdBQVcsSUFBSWxDLEdBQUosRUFBYixFQUFuQjtBQUNEOztBQUVEMkcscUJBQVcvRSxHQUFYLENBQWV6RCxzQkFBZixFQUF1QzZDLFNBQXZDO0FBQ0EyRixxQkFBVy9FLEdBQVgsQ0FBZXZELDBCQUFmLEVBQTJDMkgsZ0JBQTNDO0FBQ0FuRyxxQkFBVytCLEdBQVgsQ0FBZVgsSUFBZixFQUFxQjBGLFVBQXJCO0FBQ0QsU0EzREssNEJBQU47O0FBNkRBOzs7OztBQUtBLFVBQU1HLGlDQUFvQixTQUFwQkEsaUJBQW9CLENBQUNoQixJQUFELEVBQVU7QUFDbEMsY0FBSSxDQUFDUixhQUFMLEVBQW9CO0FBQ2xCO0FBQ0Q7O0FBRUQsY0FBSXlCLGlCQUFpQnBILFdBQVcyQixHQUFYLENBQWVMLElBQWYsQ0FBckI7QUFDQSxjQUFJLE9BQU84RixjQUFQLEtBQTBCLFdBQTlCLEVBQTJDO0FBQ3pDQSw2QkFBaUIsSUFBSW5ILEdBQUosRUFBakI7QUFDRDs7QUFFRCxjQUFNb0gsc0JBQXNCLElBQUloSCxHQUFKLEVBQTVCO0FBQ0EsY0FBTWlILHNCQUFzQixJQUFJakgsR0FBSixFQUE1Qjs7QUFFQSxjQUFNa0gsZUFBZSxJQUFJbEgsR0FBSixFQUFyQjtBQUNBLGNBQU1tSCxlQUFlLElBQUluSCxHQUFKLEVBQXJCOztBQUVBLGNBQU1vSCxvQkFBb0IsSUFBSXBILEdBQUosRUFBMUI7QUFDQSxjQUFNcUgsb0JBQW9CLElBQUlySCxHQUFKLEVBQTFCOztBQUVBLGNBQU1zSCxhQUFhLElBQUkxSCxHQUFKLEVBQW5CO0FBQ0EsY0FBTTJILGFBQWEsSUFBSTNILEdBQUosRUFBbkI7QUFDQW1ILHlCQUFldEgsT0FBZixDQUF1QixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ3JDLGdCQUFJRCxNQUFNVSxHQUFOLENBQVV2RSxzQkFBVixDQUFKLEVBQXVDO0FBQ3JDK0ksMkJBQWF2RyxHQUFiLENBQWlCc0IsR0FBakI7QUFDRDtBQUNELGdCQUFJRCxNQUFNVSxHQUFOLENBQVVyRSwwQkFBVixDQUFKLEVBQTJDO0FBQ3pDMkksa0NBQW9CckcsR0FBcEIsQ0FBd0JzQixHQUF4QjtBQUNEO0FBQ0QsZ0JBQUlELE1BQU1VLEdBQU4sQ0FBVXBFLHdCQUFWLENBQUosRUFBeUM7QUFDdkM4SSxnQ0FBa0J6RyxHQUFsQixDQUFzQnNCLEdBQXRCO0FBQ0Q7QUFDREQsa0JBQU12QyxPQUFOLENBQWMsVUFBQ2tELEdBQUQsRUFBUztBQUNyQjtBQUNFQSxzQkFBUXRFLDBCQUFSO0FBQ0dzRSxzQkFBUXJFLHdCQUZiO0FBR0U7QUFDQWdKLDJCQUFXMUYsR0FBWCxDQUFlZSxHQUFmLEVBQW9CVixHQUFwQjtBQUNEO0FBQ0YsYUFQRDtBQVFELFdBbEJEOztBQW9CQSxtQkFBU3VGLG9CQUFULENBQThCQyxNQUE5QixFQUFzQztBQUNwQyxnQkFBSUEsT0FBT3BJLElBQVAsS0FBZ0IsU0FBcEIsRUFBK0I7QUFDN0IscUJBQU8sSUFBUDtBQUNEO0FBQ0QsZ0JBQU1xSSxJQUFJLDBCQUFRRCxPQUFPekYsS0FBZixFQUFzQjFCLE9BQXRCLENBQVY7QUFDQSxnQkFBSW9ILEtBQUssSUFBVCxFQUFlO0FBQ2IscUJBQU8sSUFBUDtBQUNEO0FBQ0RULGdDQUFvQnRHLEdBQXBCLENBQXdCK0csQ0FBeEI7QUFDRDs7QUFFRCxrQ0FBTTVCLElBQU4sRUFBWWhHLGNBQWN3QixHQUFkLENBQWtCTCxJQUFsQixDQUFaLEVBQXFDO0FBQ25DMEcsNEJBRG1DLHlDQUNsQkMsS0FEa0IsRUFDWDtBQUN0QkoscUNBQXFCSSxNQUFNSCxNQUEzQjtBQUNELGVBSGtDO0FBSW5DSSwwQkFKbUMsdUNBSXBCRCxLQUpvQixFQUliO0FBQ3BCLG9CQUFJQSxNQUFNRSxNQUFOLENBQWF6SSxJQUFiLEtBQXNCLFFBQTFCLEVBQW9DO0FBQ2xDbUksdUNBQXFCSSxNQUFNRyxTQUFOLENBQWdCLENBQWhCLENBQXJCO0FBQ0Q7QUFDRixlQVJrQywyQkFBckM7OztBQVdBakMsZUFBS0ssSUFBTCxDQUFVMUcsT0FBVixDQUFrQixVQUFDdUksT0FBRCxFQUFhO0FBQzdCLGdCQUFJQyxxQkFBSjs7QUFFQTtBQUNBLGdCQUFJRCxRQUFRM0ksSUFBUixLQUFpQm5CLHdCQUFyQixFQUErQztBQUM3QyxrQkFBSThKLFFBQVFQLE1BQVosRUFBb0I7QUFDbEJRLCtCQUFlLDBCQUFRRCxRQUFRUCxNQUFSLENBQWVTLEdBQWYsQ0FBbUJDLE9BQW5CLENBQTJCLFFBQTNCLEVBQXFDLEVBQXJDLENBQVIsRUFBa0Q3SCxPQUFsRCxDQUFmO0FBQ0EwSCx3QkFBUXBFLFVBQVIsQ0FBbUJuRSxPQUFuQixDQUEyQixVQUFDZ0QsU0FBRCxFQUFlO0FBQ3hDLHNCQUFNbEQsT0FBT2tELFVBQVVGLEtBQVYsQ0FBZ0JoRCxJQUFoQixJQUF3QmtELFVBQVVGLEtBQVYsQ0FBZ0JQLEtBQXJEO0FBQ0Esc0JBQUl6QyxTQUFTUCxPQUFiLEVBQXNCO0FBQ3BCcUksc0NBQWtCMUcsR0FBbEIsQ0FBc0JzSCxZQUF0QjtBQUNELG1CQUZELE1BRU87QUFDTFYsK0JBQVczRixHQUFYLENBQWVyQyxJQUFmLEVBQXFCMEksWUFBckI7QUFDRDtBQUNGLGlCQVBEO0FBUUQ7QUFDRjs7QUFFRCxnQkFBSUQsUUFBUTNJLElBQVIsS0FBaUJsQixzQkFBckIsRUFBNkM7QUFDM0M4Siw2QkFBZSwwQkFBUUQsUUFBUVAsTUFBUixDQUFlUyxHQUFmLENBQW1CQyxPQUFuQixDQUEyQixRQUEzQixFQUFxQyxFQUFyQyxDQUFSLEVBQWtEN0gsT0FBbEQsQ0FBZjtBQUNBNkcsMkJBQWF4RyxHQUFiLENBQWlCc0gsWUFBakI7QUFDRDs7QUFFRCxnQkFBSUQsUUFBUTNJLElBQVIsS0FBaUJqQixrQkFBckIsRUFBeUM7QUFDdkM2Siw2QkFBZSwwQkFBUUQsUUFBUVAsTUFBUixDQUFlUyxHQUFmLENBQW1CQyxPQUFuQixDQUEyQixRQUEzQixFQUFxQyxFQUFyQyxDQUFSLEVBQWtEN0gsT0FBbEQsQ0FBZjtBQUNBLGtCQUFJLENBQUMySCxZQUFMLEVBQW1CO0FBQ2pCO0FBQ0Q7O0FBRUQsa0JBQUkvSCxhQUFhK0gsWUFBYixDQUFKLEVBQWdDO0FBQzlCO0FBQ0Q7O0FBRUQsa0JBQUl0RSx5QkFBeUJxRSxRQUFRcEUsVUFBakMsQ0FBSixFQUFrRDtBQUNoRHFELG9DQUFvQnRHLEdBQXBCLENBQXdCc0gsWUFBeEI7QUFDRDs7QUFFRCxrQkFBSW5FLHVCQUF1QmtFLFFBQVFwRSxVQUEvQixDQUFKLEVBQWdEO0FBQzlDeUQsa0NBQWtCMUcsR0FBbEIsQ0FBc0JzSCxZQUF0QjtBQUNEOztBQUVERCxzQkFBUXBFLFVBQVI7QUFDRy9DLG9CQURILENBQ1UsVUFBQzRCLFNBQUQsVUFBZUEsVUFBVXBELElBQVYsS0FBbUJmLHdCQUFuQixJQUErQ21FLFVBQVVwRCxJQUFWLEtBQW1CaEIsMEJBQWpGLEVBRFY7QUFFR29CLHFCQUZILENBRVcsVUFBQ2dELFNBQUQsRUFBZTtBQUN0QjhFLDJCQUFXM0YsR0FBWCxDQUFlYSxVQUFVMkYsUUFBVixDQUFtQjdJLElBQW5CLElBQTJCa0QsVUFBVTJGLFFBQVYsQ0FBbUJwRyxLQUE3RCxFQUFvRWlHLFlBQXBFO0FBQ0QsZUFKSDtBQUtEO0FBQ0YsV0EvQ0Q7O0FBaURBZCx1QkFBYTFILE9BQWIsQ0FBcUIsVUFBQ3VDLEtBQUQsRUFBVztBQUM5QixnQkFBSSxDQUFDa0YsYUFBYXhFLEdBQWIsQ0FBaUJWLEtBQWpCLENBQUwsRUFBOEI7QUFDNUIsa0JBQUliLFVBQVU0RixlQUFlekYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUluQixHQUFKLEVBQVY7QUFDRDtBQUNEbUIsc0JBQVFSLEdBQVIsQ0FBWXhDLHNCQUFaO0FBQ0E0SSw2QkFBZW5GLEdBQWYsQ0FBbUJJLEtBQW5CLEVBQTBCYixPQUExQjs7QUFFQSxrQkFBSUQsV0FBVXJCLFdBQVd5QixHQUFYLENBQWVVLEtBQWYsQ0FBZDtBQUNBLGtCQUFJWSxzQkFBSjtBQUNBLGtCQUFJLE9BQU8xQixRQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDMEIsZ0NBQWdCMUIsU0FBUUksR0FBUixDQUFZbkQsc0JBQVosQ0FBaEI7QUFDRCxlQUZELE1BRU87QUFDTCtDLDJCQUFVLElBQUl0QixHQUFKLEVBQVY7QUFDQUMsMkJBQVcrQixHQUFYLENBQWVJLEtBQWYsRUFBc0JkLFFBQXRCO0FBQ0Q7O0FBRUQsa0JBQUksT0FBTzBCLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLDhCQUFjVixTQUFkLENBQXdCdkIsR0FBeEIsQ0FBNEJNLElBQTVCO0FBQ0QsZUFGRCxNQUVPO0FBQ0wsb0JBQU1pQixZQUFZLElBQUlsQyxHQUFKLEVBQWxCO0FBQ0FrQywwQkFBVXZCLEdBQVYsQ0FBY00sSUFBZDtBQUNBQyx5QkFBUVUsR0FBUixDQUFZekQsc0JBQVosRUFBb0MsRUFBRStELG9CQUFGLEVBQXBDO0FBQ0Q7QUFDRjtBQUNGLFdBMUJEOztBQTRCQWdGLHVCQUFhekgsT0FBYixDQUFxQixVQUFDdUMsS0FBRCxFQUFXO0FBQzlCLGdCQUFJLENBQUNtRixhQUFhekUsR0FBYixDQUFpQlYsS0FBakIsQ0FBTCxFQUE4QjtBQUM1QixrQkFBTWIsVUFBVTRGLGVBQWV6RixHQUFmLENBQW1CVSxLQUFuQixDQUFoQjtBQUNBYixnQ0FBZWhELHNCQUFmOztBQUVBLGtCQUFNK0MsWUFBVXJCLFdBQVd5QixHQUFYLENBQWVVLEtBQWYsQ0FBaEI7QUFDQSxrQkFBSSxPQUFPZCxTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDLG9CQUFNMEIsZ0JBQWdCMUIsVUFBUUksR0FBUixDQUFZbkQsc0JBQVosQ0FBdEI7QUFDQSxvQkFBSSxPQUFPeUUsYUFBUCxLQUF5QixXQUE3QixFQUEwQztBQUN4Q0EsZ0NBQWNWLFNBQWQsV0FBK0JqQixJQUEvQjtBQUNEO0FBQ0Y7QUFDRjtBQUNGLFdBYkQ7O0FBZUFvRyw0QkFBa0I1SCxPQUFsQixDQUEwQixVQUFDdUMsS0FBRCxFQUFXO0FBQ25DLGdCQUFJLENBQUNvRixrQkFBa0IxRSxHQUFsQixDQUFzQlYsS0FBdEIsQ0FBTCxFQUFtQztBQUNqQyxrQkFBSWIsVUFBVTRGLGVBQWV6RixHQUFmLENBQW1CVSxLQUFuQixDQUFkO0FBQ0Esa0JBQUksT0FBT2IsT0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQ0EsMEJBQVUsSUFBSW5CLEdBQUosRUFBVjtBQUNEO0FBQ0RtQixzQkFBUVIsR0FBUixDQUFZckMsd0JBQVo7QUFDQXlJLDZCQUFlbkYsR0FBZixDQUFtQkksS0FBbkIsRUFBMEJiLE9BQTFCOztBQUVBLGtCQUFJRCxZQUFVckIsV0FBV3lCLEdBQVgsQ0FBZVUsS0FBZixDQUFkO0FBQ0Esa0JBQUlZLHNCQUFKO0FBQ0Esa0JBQUksT0FBTzFCLFNBQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbEMwQixnQ0FBZ0IxQixVQUFRSSxHQUFSLENBQVloRCx3QkFBWixDQUFoQjtBQUNELGVBRkQsTUFFTztBQUNMNEMsNEJBQVUsSUFBSXRCLEdBQUosRUFBVjtBQUNBQywyQkFBVytCLEdBQVgsQ0FBZUksS0FBZixFQUFzQmQsU0FBdEI7QUFDRDs7QUFFRCxrQkFBSSxPQUFPMEIsYUFBUCxLQUF5QixXQUE3QixFQUEwQztBQUN4Q0EsOEJBQWNWLFNBQWQsQ0FBd0J2QixHQUF4QixDQUE0Qk0sSUFBNUI7QUFDRCxlQUZELE1BRU87QUFDTCxvQkFBTWlCLFlBQVksSUFBSWxDLEdBQUosRUFBbEI7QUFDQWtDLDBCQUFVdkIsR0FBVixDQUFjTSxJQUFkO0FBQ0FDLDBCQUFRVSxHQUFSLENBQVl0RCx3QkFBWixFQUFzQyxFQUFFNEQsb0JBQUYsRUFBdEM7QUFDRDtBQUNGO0FBQ0YsV0ExQkQ7O0FBNEJBa0YsNEJBQWtCM0gsT0FBbEIsQ0FBMEIsVUFBQ3VDLEtBQUQsRUFBVztBQUNuQyxnQkFBSSxDQUFDcUYsa0JBQWtCM0UsR0FBbEIsQ0FBc0JWLEtBQXRCLENBQUwsRUFBbUM7QUFDakMsa0JBQU1iLFVBQVU0RixlQUFlekYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBaEI7QUFDQWIsZ0NBQWU3Qyx3QkFBZjs7QUFFQSxrQkFBTTRDLFlBQVVyQixXQUFXeUIsR0FBWCxDQUFlVSxLQUFmLENBQWhCO0FBQ0Esa0JBQUksT0FBT2QsU0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQyxvQkFBTTBCLGdCQUFnQjFCLFVBQVFJLEdBQVIsQ0FBWWhELHdCQUFaLENBQXRCO0FBQ0Esb0JBQUksT0FBT3NFLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLGdDQUFjVixTQUFkLFdBQStCakIsSUFBL0I7QUFDRDtBQUNGO0FBQ0Y7QUFDRixXQWJEOztBQWVBZ0csOEJBQW9CeEgsT0FBcEIsQ0FBNEIsVUFBQ3VDLEtBQUQsRUFBVztBQUNyQyxnQkFBSSxDQUFDZ0Ysb0JBQW9CdEUsR0FBcEIsQ0FBd0JWLEtBQXhCLENBQUwsRUFBcUM7QUFDbkMsa0JBQUliLFVBQVU0RixlQUFlekYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUluQixHQUFKLEVBQVY7QUFDRDtBQUNEbUIsc0JBQVFSLEdBQVIsQ0FBWXRDLDBCQUFaO0FBQ0EwSSw2QkFBZW5GLEdBQWYsQ0FBbUJJLEtBQW5CLEVBQTBCYixPQUExQjs7QUFFQSxrQkFBSUQsWUFBVXJCLFdBQVd5QixHQUFYLENBQWVVLEtBQWYsQ0FBZDtBQUNBLGtCQUFJWSxzQkFBSjtBQUNBLGtCQUFJLE9BQU8xQixTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDMEIsZ0NBQWdCMUIsVUFBUUksR0FBUixDQUFZakQsMEJBQVosQ0FBaEI7QUFDRCxlQUZELE1BRU87QUFDTDZDLDRCQUFVLElBQUl0QixHQUFKLEVBQVY7QUFDQUMsMkJBQVcrQixHQUFYLENBQWVJLEtBQWYsRUFBc0JkLFNBQXRCO0FBQ0Q7O0FBRUQsa0JBQUksT0FBTzBCLGFBQVAsS0FBeUIsV0FBN0IsRUFBMEM7QUFDeENBLDhCQUFjVixTQUFkLENBQXdCdkIsR0FBeEIsQ0FBNEJNLElBQTVCO0FBQ0QsZUFGRCxNQUVPO0FBQ0wsb0JBQU1pQixZQUFZLElBQUlsQyxHQUFKLEVBQWxCO0FBQ0FrQywwQkFBVXZCLEdBQVYsQ0FBY00sSUFBZDtBQUNBQywwQkFBUVUsR0FBUixDQUFZdkQsMEJBQVosRUFBd0MsRUFBRTZELG9CQUFGLEVBQXhDO0FBQ0Q7QUFDRjtBQUNGLFdBMUJEOztBQTRCQThFLDhCQUFvQnZILE9BQXBCLENBQTRCLFVBQUN1QyxLQUFELEVBQVc7QUFDckMsZ0JBQUksQ0FBQ2lGLG9CQUFvQnZFLEdBQXBCLENBQXdCVixLQUF4QixDQUFMLEVBQXFDO0FBQ25DLGtCQUFNYixVQUFVNEYsZUFBZXpGLEdBQWYsQ0FBbUJVLEtBQW5CLENBQWhCO0FBQ0FiLGdDQUFlOUMsMEJBQWY7O0FBRUEsa0JBQU02QyxZQUFVckIsV0FBV3lCLEdBQVgsQ0FBZVUsS0FBZixDQUFoQjtBQUNBLGtCQUFJLE9BQU9kLFNBQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbEMsb0JBQU0wQixnQkFBZ0IxQixVQUFRSSxHQUFSLENBQVlqRCwwQkFBWixDQUF0QjtBQUNBLG9CQUFJLE9BQU91RSxhQUFQLEtBQXlCLFdBQTdCLEVBQTBDO0FBQ3hDQSxnQ0FBY1YsU0FBZCxXQUErQmpCLElBQS9CO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsV0FiRDs7QUFlQXNHLHFCQUFXOUgsT0FBWCxDQUFtQixVQUFDdUMsS0FBRCxFQUFRQyxHQUFSLEVBQWdCO0FBQ2pDLGdCQUFJLENBQUNxRixXQUFXNUUsR0FBWCxDQUFlVCxHQUFmLENBQUwsRUFBMEI7QUFDeEIsa0JBQUlkLFVBQVU0RixlQUFlekYsR0FBZixDQUFtQlUsS0FBbkIsQ0FBZDtBQUNBLGtCQUFJLE9BQU9iLE9BQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbENBLDBCQUFVLElBQUluQixHQUFKLEVBQVY7QUFDRDtBQUNEbUIsc0JBQVFSLEdBQVIsQ0FBWXNCLEdBQVo7QUFDQThFLDZCQUFlbkYsR0FBZixDQUFtQkksS0FBbkIsRUFBMEJiLE9BQTFCOztBQUVBLGtCQUFJRCxZQUFVckIsV0FBV3lCLEdBQVgsQ0FBZVUsS0FBZixDQUFkO0FBQ0Esa0JBQUlZLHNCQUFKO0FBQ0Esa0JBQUksT0FBTzFCLFNBQVAsS0FBbUIsV0FBdkIsRUFBb0M7QUFDbEMwQixnQ0FBZ0IxQixVQUFRSSxHQUFSLENBQVlXLEdBQVosQ0FBaEI7QUFDRCxlQUZELE1BRU87QUFDTGYsNEJBQVUsSUFBSXRCLEdBQUosRUFBVjtBQUNBQywyQkFBVytCLEdBQVgsQ0FBZUksS0FBZixFQUFzQmQsU0FBdEI7QUFDRDs7QUFFRCxrQkFBSSxPQUFPMEIsYUFBUCxLQUF5QixXQUE3QixFQUEwQztBQUN4Q0EsOEJBQWNWLFNBQWQsQ0FBd0J2QixHQUF4QixDQUE0Qk0sSUFBNUI7QUFDRCxlQUZELE1BRU87QUFDTCxvQkFBTWlCLFlBQVksSUFBSWxDLEdBQUosRUFBbEI7QUFDQWtDLDBCQUFVdkIsR0FBVixDQUFjTSxJQUFkO0FBQ0FDLDBCQUFRVSxHQUFSLENBQVlLLEdBQVosRUFBaUIsRUFBRUMsb0JBQUYsRUFBakI7QUFDRDtBQUNGO0FBQ0YsV0ExQkQ7O0FBNEJBb0YscUJBQVc3SCxPQUFYLENBQW1CLFVBQUN1QyxLQUFELEVBQVFDLEdBQVIsRUFBZ0I7QUFDakMsZ0JBQUksQ0FBQ3NGLFdBQVc3RSxHQUFYLENBQWVULEdBQWYsQ0FBTCxFQUEwQjtBQUN4QixrQkFBTWQsVUFBVTRGLGVBQWV6RixHQUFmLENBQW1CVSxLQUFuQixDQUFoQjtBQUNBYixnQ0FBZWMsR0FBZjs7QUFFQSxrQkFBTWYsWUFBVXJCLFdBQVd5QixHQUFYLENBQWVVLEtBQWYsQ0FBaEI7QUFDQSxrQkFBSSxPQUFPZCxTQUFQLEtBQW1CLFdBQXZCLEVBQW9DO0FBQ2xDLG9CQUFNMEIsZ0JBQWdCMUIsVUFBUUksR0FBUixDQUFZVyxHQUFaLENBQXRCO0FBQ0Esb0JBQUksT0FBT1csYUFBUCxLQUF5QixXQUE3QixFQUEwQztBQUN4Q0EsZ0NBQWNWLFNBQWQsV0FBK0JqQixJQUEvQjtBQUNEO0FBQ0Y7QUFDRjtBQUNGLFdBYkQ7QUFjRCxTQTNSSyw0QkFBTjs7QUE2UkEsYUFBTztBQUNMLHNCQURLLG9DQUNVNkUsSUFEVixFQUNnQjtBQUNuQlksOEJBQWtCWixJQUFsQjtBQUNBZ0IsOEJBQWtCaEIsSUFBbEI7QUFDQUQsZ0NBQW9CQyxJQUFwQjtBQUNELFdBTEk7QUFNTHVDLGdDQU5LLGlEQU1vQnZDLElBTnBCLEVBTTBCO0FBQzdCTSx1QkFBV04sSUFBWCxFQUFpQnhILHdCQUFqQixFQUEyQyxLQUEzQztBQUNELFdBUkk7QUFTTGdLLDhCQVRLLCtDQVNrQnhDLElBVGxCLEVBU3dCO0FBQzNCQSxpQkFBS2xDLFVBQUwsQ0FBZ0JuRSxPQUFoQixDQUF3QixVQUFDZ0QsU0FBRCxFQUFlO0FBQ3JDMkQseUJBQVczRCxTQUFYLEVBQXNCQSxVQUFVb0UsUUFBVixDQUFtQnRILElBQW5CLElBQTJCa0QsVUFBVW9FLFFBQVYsQ0FBbUI3RSxLQUFwRSxFQUEyRSxLQUEzRTtBQUNELGFBRkQ7QUFHQS9DLHlDQUE2QjZHLEtBQUs1RyxXQUFsQyxFQUErQyxVQUFDSyxJQUFELEVBQU8rRyxZQUFQLEVBQXdCO0FBQ3JFRix5QkFBV04sSUFBWCxFQUFpQnZHLElBQWpCLEVBQXVCK0csWUFBdkI7QUFDRCxhQUZEO0FBR0QsV0FoQkksbUNBQVA7O0FBa0JELEtBcGlCYyxtQkFBakIiLCJmaWxlIjoibm8tdW51c2VkLW1vZHVsZXMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlT3ZlcnZpZXcgRW5zdXJlcyB0aGF0IG1vZHVsZXMgY29udGFpbiBleHBvcnRzIGFuZC9vciBhbGxcbiAqIG1vZHVsZXMgYXJlIGNvbnN1bWVkIHdpdGhpbiBvdGhlciBtb2R1bGVzLlxuICogQGF1dGhvciBSZW7DqSBGZXJtYW5uXG4gKi9cblxuaW1wb3J0IHsgZ2V0UGh5c2ljYWxGaWxlbmFtZSB9IGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvY29udGV4dENvbXBhdCc7XG5pbXBvcnQgeyBnZXRGaWxlRXh0ZW5zaW9ucyB9IGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvaWdub3JlJztcbmltcG9ydCByZXNvbHZlIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvcmVzb2x2ZSc7XG5pbXBvcnQgdmlzaXQgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy92aXNpdCc7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgcmVhZFBrZ1VwIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvcmVhZFBrZ1VwJztcbmltcG9ydCB2YWx1ZXMgZnJvbSAnb2JqZWN0LnZhbHVlcyc7XG5pbXBvcnQgaW5jbHVkZXMgZnJvbSAnYXJyYXktaW5jbHVkZXMnO1xuaW1wb3J0IGZsYXRNYXAgZnJvbSAnYXJyYXkucHJvdG90eXBlLmZsYXRtYXAnO1xuXG5pbXBvcnQgRXhwb3J0TWFwQnVpbGRlciBmcm9tICcuLi9leHBvcnRNYXAvYnVpbGRlcic7XG5pbXBvcnQgcmVjdXJzaXZlUGF0dGVybkNhcHR1cmUgZnJvbSAnLi4vZXhwb3J0TWFwL3BhdHRlcm5DYXB0dXJlJztcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnO1xuXG4vKipcbiAqIEF0dGVtcHQgdG8gbG9hZCB0aGUgaW50ZXJuYWwgYEZpbGVFbnVtZXJhdG9yYCBjbGFzcywgd2hpY2ggaGFzIGV4aXN0ZWQgaW4gYSBjb3VwbGVcbiAqIG9mIGRpZmZlcmVudCBwbGFjZXMsIGRlcGVuZGluZyBvbiB0aGUgdmVyc2lvbiBvZiBgZXNsaW50YC4gIFRyeSByZXF1aXJpbmcgaXQgZnJvbSBib3RoXG4gKiBsb2NhdGlvbnMuXG4gKiBAcmV0dXJucyBSZXR1cm5zIHRoZSBgRmlsZUVudW1lcmF0b3JgIGNsYXNzIGlmIGl0cyByZXF1aXJhYmxlLCBvdGhlcndpc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIHJlcXVpcmVGaWxlRW51bWVyYXRvcigpIHtcbiAgbGV0IEZpbGVFbnVtZXJhdG9yO1xuXG4gIC8vIFRyeSBnZXR0aW5nIGl0IGZyb20gdGhlIGVzbGludCBwcml2YXRlIC8gZGVwcmVjYXRlZCBhcGlcbiAgdHJ5IHtcbiAgICAoeyBGaWxlRW51bWVyYXRvciB9ID0gcmVxdWlyZSgnZXNsaW50L3VzZS1hdC15b3VyLW93bi1yaXNrJykpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gQWJzb3JiIHRoaXMgaWYgaXQncyBNT0RVTEVfTk9UX0ZPVU5EXG4gICAgaWYgKGUuY29kZSAhPT0gJ01PRFVMRV9OT1RfRk9VTkQnKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIC8vIElmIG5vdCB0aGVyZSwgdGhlbiB0cnkgZ2V0dGluZyBpdCBmcm9tIGVzbGludC9saWIvY2xpLWVuZ2luZS9maWxlLWVudW1lcmF0b3IgKG1vdmVkIHRoZXJlIGluIHY2KVxuICAgIHRyeSB7XG4gICAgICAoeyBGaWxlRW51bWVyYXRvciB9ID0gcmVxdWlyZSgnZXNsaW50L2xpYi9jbGktZW5naW5lL2ZpbGUtZW51bWVyYXRvcicpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBBYnNvcmIgdGhpcyBpZiBpdCdzIE1PRFVMRV9OT1RfRk9VTkRcbiAgICAgIGlmIChlLmNvZGUgIT09ICdNT0RVTEVfTk9UX0ZPVU5EJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gRmlsZUVudW1lcmF0b3I7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBGaWxlRW51bWVyYXRvciBjbGFzcywgaW5zdGFudGlhdGUgYW5kIGxvYWQgdGhlIGxpc3Qgb2YgZmlsZXMuXG4gKiBAcGFyYW0gRmlsZUVudW1lcmF0b3IgdGhlIGBGaWxlRW51bWVyYXRvcmAgY2xhc3MgZnJvbSBgZXNsaW50YCdzIGludGVybmFsIGFwaVxuICogQHBhcmFtIHtzdHJpbmd9IHNyYyBwYXRoIHRvIHRoZSBzcmMgcm9vdFxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXh0ZW5zaW9ucyBsaXN0IG9mIHN1cHBvcnRlZCBleHRlbnNpb25zXG4gKiBAcmV0dXJucyB7eyBmaWxlbmFtZTogc3RyaW5nLCBpZ25vcmVkOiBib29sZWFuIH1bXX0gbGlzdCBvZiBmaWxlcyB0byBvcGVyYXRlIG9uXG4gKi9cbmZ1bmN0aW9uIGxpc3RGaWxlc1VzaW5nRmlsZUVudW1lcmF0b3IoRmlsZUVudW1lcmF0b3IsIHNyYywgZXh0ZW5zaW9ucykge1xuICAvLyBXZSBuZWVkIHRvIGtub3cgd2hldGhlciB0aGlzIGlzIGJlaW5nIHJ1biB3aXRoIGZsYXQgY29uZmlnIGluIG9yZGVyIHRvXG4gIC8vIGRldGVybWluZSBob3cgdG8gcmVwb3J0IGVycm9ycyBpZiBGaWxlRW51bWVyYXRvciB0aHJvd3MgZHVlIHRvIGEgbGFjayBvZiBlc2xpbnRyYy5cblxuICBjb25zdCB7IEVTTElOVF9VU0VfRkxBVF9DT05GSUcgfSA9IHByb2Nlc3MuZW52O1xuXG4gIC8vIFRoaXMgY29uZGl0aW9uIGlzIHN1ZmZpY2llbnQgdG8gdGVzdCBpbiB2OCwgc2luY2UgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5lY2Vzc2FyeSB0byB0dXJuIG9uIGZsYXQgY29uZmlnXG4gIGxldCBpc1VzaW5nRmxhdENvbmZpZyA9IEVTTElOVF9VU0VfRkxBVF9DT05GSUcgJiYgcHJvY2Vzcy5lbnYuRVNMSU5UX1VTRV9GTEFUX0NPTkZJRyAhPT0gJ2ZhbHNlJztcblxuICAvLyBJbiB0aGUgY2FzZSBvZiB1c2luZyB2OSwgd2UgY2FuIGNoZWNrIHRoZSBgc2hvdWxkVXNlRmxhdENvbmZpZ2AgZnVuY3Rpb25cbiAgLy8gSWYgdGhpcyBmdW5jdGlvbiBpcyBwcmVzZW50LCB0aGVuIHdlIGFzc3VtZSBpdCdzIHY5XG4gIHRyeSB7XG4gICAgY29uc3QgeyBzaG91bGRVc2VGbGF0Q29uZmlnIH0gPSByZXF1aXJlKCdlc2xpbnQvdXNlLWF0LXlvdXItb3duLXJpc2snKTtcbiAgICBpc1VzaW5nRmxhdENvbmZpZyA9IHNob3VsZFVzZUZsYXRDb25maWcgJiYgRVNMSU5UX1VTRV9GTEFUX0NPTkZJRyAhPT0gJ2ZhbHNlJztcbiAgfSBjYXRjaCAoXykge1xuICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gdGhyb3cgaGVyZSwgc2luY2Ugd2Ugb25seSB3YW50IHRvIHVwZGF0ZSB0aGVcbiAgICAvLyBib29sZWFuIGlmIHRoZSBmdW5jdGlvbiBpcyBhdmFpbGFibGUuXG4gIH1cblxuICBjb25zdCBlbnVtZXJhdG9yID0gbmV3IEZpbGVFbnVtZXJhdG9yKHtcbiAgICBleHRlbnNpb25zLFxuICB9KTtcblxuICB0cnkge1xuICAgIHJldHVybiBBcnJheS5mcm9tKFxuICAgICAgZW51bWVyYXRvci5pdGVyYXRlRmlsZXMoc3JjKSxcbiAgICAgICh7IGZpbGVQYXRoLCBpZ25vcmVkIH0pID0+ICh7IGZpbGVuYW1lOiBmaWxlUGF0aCwgaWdub3JlZCB9KSxcbiAgICApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSWYgd2UncmUgdXNpbmcgZmxhdCBjb25maWcsIGFuZCBGaWxlRW51bWVyYXRvciB0aHJvd3MgZHVlIHRvIGEgbGFjayBvZiBlc2xpbnRyYyxcbiAgICAvLyB0aGVuIHdlIHdhbnQgdG8gdGhyb3cgYW4gZXJyb3Igc28gdGhhdCB0aGUgdXNlciBrbm93cyBhYm91dCB0aGlzIHJ1bGUncyByZWxpYW5jZSBvblxuICAgIC8vIHRoZSBsZWdhY3kgY29uZmlnLlxuICAgIGlmIChcbiAgICAgIGlzVXNpbmdGbGF0Q29uZmlnXG4gICAgICAmJiBlLm1lc3NhZ2UuaW5jbHVkZXMoJ05vIEVTTGludCBjb25maWd1cmF0aW9uIGZvdW5kJylcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXG5EdWUgdG8gdGhlIGV4Y2x1c2lvbiBvZiBjZXJ0YWluIGludGVybmFsIEVTTGludCBBUElzIHdoZW4gdXNpbmcgZmxhdCBjb25maWcsXG50aGUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzIHJ1bGUgcmVxdWlyZXMgYW4gLmVzbGludHJjIGZpbGUgdG8ga25vdyB3aGljaFxuZmlsZXMgdG8gaWdub3JlIChldmVuIHdoZW4gdXNpbmcgZmxhdCBjb25maWcpLlxuVGhlIC5lc2xpbnRyYyBmaWxlIG9ubHkgbmVlZHMgdG8gY29udGFpbiBcImlnbm9yZVBhdHRlcm5zXCIsIG9yIGNhbiBiZSBlbXB0eSBpZlxueW91IGRvIG5vdCB3YW50IHRvIGlnbm9yZSBhbnkgZmlsZXMuXG5cblNlZSBodHRwczovL2dpdGh1Yi5jb20vaW1wb3J0LWpzL2VzbGludC1wbHVnaW4taW1wb3J0L2lzc3Vlcy8zMDc5XG5mb3IgYWRkaXRpb25hbCBjb250ZXh0LlxuYCk7XG4gICAgfVxuICAgIC8vIElmIHRoaXMgaXNuJ3QgdGhlIGNhc2UsIHRoZW4gd2UnbGwganVzdCBsZXQgdGhlIGVycm9yIGJ1YmJsZSB1cFxuICAgIHRocm93IGU7XG4gIH1cbn1cblxuLyoqXG4gKiBBdHRlbXB0IHRvIHJlcXVpcmUgb2xkIHZlcnNpb25zIG9mIHRoZSBmaWxlIGVudW1lcmF0aW9uIGNhcGFiaWxpdHkgZnJvbSB2NiBgZXNsaW50YCBhbmQgZWFybGllciwgYW5kIHVzZVxuICogdGhvc2UgZnVuY3Rpb25zIHRvIHByb3ZpZGUgdGhlIGxpc3Qgb2YgZmlsZXMgdG8gb3BlcmF0ZSBvblxuICogQHBhcmFtIHtzdHJpbmd9IHNyYyBwYXRoIHRvIHRoZSBzcmMgcm9vdFxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXh0ZW5zaW9ucyBsaXN0IG9mIHN1cHBvcnRlZCBleHRlbnNpb25zXG4gKiBAcmV0dXJucyB7c3RyaW5nW119IGxpc3Qgb2YgZmlsZXMgdG8gb3BlcmF0ZSBvblxuICovXG5mdW5jdGlvbiBsaXN0RmlsZXNXaXRoTGVnYWN5RnVuY3Rpb25zKHNyYywgZXh0ZW5zaW9ucykge1xuICB0cnkge1xuICAgIC8vIGVzbGludC9saWIvdXRpbC9nbG9iLXV0aWwgaGFzIGJlZW4gbW92ZWQgdG8gZXNsaW50L2xpYi91dGlsL2dsb2ItdXRpbHMgd2l0aCB2ZXJzaW9uIDUuM1xuICAgIGNvbnN0IHsgbGlzdEZpbGVzVG9Qcm9jZXNzOiBvcmlnaW5hbExpc3RGaWxlc1RvUHJvY2VzcyB9ID0gcmVxdWlyZSgnZXNsaW50L2xpYi91dGlsL2dsb2ItdXRpbHMnKTtcbiAgICAvLyBQcmV2ZW50IHBhc3NpbmcgaW52YWxpZCBvcHRpb25zIChleHRlbnNpb25zIGFycmF5KSB0byBvbGQgdmVyc2lvbnMgb2YgdGhlIGZ1bmN0aW9uLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9lc2xpbnQvZXNsaW50L2Jsb2IvdjUuMTYuMC9saWIvdXRpbC9nbG9iLXV0aWxzLmpzI0wxNzgtTDI4MFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9lc2xpbnQvZXNsaW50L2Jsb2IvdjUuMi4wL2xpYi91dGlsL2dsb2ItdXRpbC5qcyNMMTc0LUwyNjlcblxuICAgIHJldHVybiBvcmlnaW5hbExpc3RGaWxlc1RvUHJvY2VzcyhzcmMsIHtcbiAgICAgIGV4dGVuc2lvbnMsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBBYnNvcmIgdGhpcyBpZiBpdCdzIE1PRFVMRV9OT1RfRk9VTkRcbiAgICBpZiAoZS5jb2RlICE9PSAnTU9EVUxFX05PVF9GT1VORCcpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgLy8gTGFzdCBwbGFjZSB0byB0cnkgKHByZSB2NS4zKVxuICAgIGNvbnN0IHtcbiAgICAgIGxpc3RGaWxlc1RvUHJvY2Vzczogb3JpZ2luYWxMaXN0RmlsZXNUb1Byb2Nlc3MsXG4gICAgfSA9IHJlcXVpcmUoJ2VzbGludC9saWIvdXRpbC9nbG9iLXV0aWwnKTtcbiAgICBjb25zdCBwYXR0ZXJucyA9IHNyYy5jb25jYXQoXG4gICAgICBmbGF0TWFwKFxuICAgICAgICBzcmMsXG4gICAgICAgIChwYXR0ZXJuKSA9PiBleHRlbnNpb25zLm1hcCgoZXh0ZW5zaW9uKSA9PiAoL1xcKlxcKnxcXCpcXC4vKS50ZXN0KHBhdHRlcm4pID8gcGF0dGVybiA6IGAke3BhdHRlcm59LyoqLyoke2V4dGVuc2lvbn1gKSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIHJldHVybiBvcmlnaW5hbExpc3RGaWxlc1RvUHJvY2VzcyhwYXR0ZXJucyk7XG4gIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIHNyYyBwYXR0ZXJuIGFuZCBsaXN0IG9mIHN1cHBvcnRlZCBleHRlbnNpb25zLCByZXR1cm4gYSBsaXN0IG9mIGZpbGVzIHRvIHByb2Nlc3NcbiAqIHdpdGggdGhpcyBydWxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNyYyAtIGZpbGUsIGRpcmVjdG9yeSwgb3IgZ2xvYiBwYXR0ZXJuIG9mIGZpbGVzIHRvIGFjdCBvblxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXh0ZW5zaW9ucyAtIGxpc3Qgb2Ygc3VwcG9ydGVkIGZpbGUgZXh0ZW5zaW9uc1xuICogQHJldHVybnMge3N0cmluZ1tdIHwgeyBmaWxlbmFtZTogc3RyaW5nLCBpZ25vcmVkOiBib29sZWFuIH1bXX0gdGhlIGxpc3Qgb2YgZmlsZXMgdGhhdCB0aGlzIHJ1bGUgd2lsbCBldmFsdWF0ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdEZpbGVzVG9Qcm9jZXNzKHNyYywgZXh0ZW5zaW9ucykge1xuICBjb25zdCBGaWxlRW51bWVyYXRvciA9IHJlcXVpcmVGaWxlRW51bWVyYXRvcigpO1xuXG4gIC8vIElmIHdlIGdvdCB0aGUgRmlsZUVudW1lcmF0b3IsIHRoZW4gbGV0J3MgZ28gd2l0aCB0aGF0XG4gIGlmIChGaWxlRW51bWVyYXRvcikge1xuICAgIHJldHVybiBsaXN0RmlsZXNVc2luZ0ZpbGVFbnVtZXJhdG9yKEZpbGVFbnVtZXJhdG9yLCBzcmMsIGV4dGVuc2lvbnMpO1xuICB9XG4gIC8vIElmIG5vdCwgdGhlbiB3ZSBjYW4gdHJ5IGV2ZW4gb2xkZXIgdmVyc2lvbnMgb2YgdGhpcyBjYXBhYmlsaXR5IChsaXN0RmlsZXNUb1Byb2Nlc3MpXG4gIHJldHVybiBsaXN0RmlsZXNXaXRoTGVnYWN5RnVuY3Rpb25zKHNyYywgZXh0ZW5zaW9ucyk7XG59XG5cbmNvbnN0IEVYUE9SVF9ERUZBVUxUX0RFQ0xBUkFUSU9OID0gJ0V4cG9ydERlZmF1bHREZWNsYXJhdGlvbic7XG5jb25zdCBFWFBPUlRfTkFNRURfREVDTEFSQVRJT04gPSAnRXhwb3J0TmFtZWREZWNsYXJhdGlvbic7XG5jb25zdCBFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OID0gJ0V4cG9ydEFsbERlY2xhcmF0aW9uJztcbmNvbnN0IElNUE9SVF9ERUNMQVJBVElPTiA9ICdJbXBvcnREZWNsYXJhdGlvbic7XG5jb25zdCBJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiA9ICdJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXInO1xuY29uc3QgSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSID0gJ0ltcG9ydERlZmF1bHRTcGVjaWZpZXInO1xuY29uc3QgVkFSSUFCTEVfREVDTEFSQVRJT04gPSAnVmFyaWFibGVEZWNsYXJhdGlvbic7XG5jb25zdCBGVU5DVElPTl9ERUNMQVJBVElPTiA9ICdGdW5jdGlvbkRlY2xhcmF0aW9uJztcbmNvbnN0IENMQVNTX0RFQ0xBUkFUSU9OID0gJ0NsYXNzRGVjbGFyYXRpb24nO1xuY29uc3QgSURFTlRJRklFUiA9ICdJZGVudGlmaWVyJztcbmNvbnN0IE9CSkVDVF9QQVRURVJOID0gJ09iamVjdFBhdHRlcm4nO1xuY29uc3QgQVJSQVlfUEFUVEVSTiA9ICdBcnJheVBhdHRlcm4nO1xuY29uc3QgVFNfSU5URVJGQUNFX0RFQ0xBUkFUSU9OID0gJ1RTSW50ZXJmYWNlRGVjbGFyYXRpb24nO1xuY29uc3QgVFNfVFlQRV9BTElBU19ERUNMQVJBVElPTiA9ICdUU1R5cGVBbGlhc0RlY2xhcmF0aW9uJztcbmNvbnN0IFRTX0VOVU1fREVDTEFSQVRJT04gPSAnVFNFbnVtRGVjbGFyYXRpb24nO1xuY29uc3QgREVGQVVMVCA9ICdkZWZhdWx0JztcblxuZnVuY3Rpb24gZm9yRWFjaERlY2xhcmF0aW9uSWRlbnRpZmllcihkZWNsYXJhdGlvbiwgY2IpIHtcbiAgaWYgKGRlY2xhcmF0aW9uKSB7XG4gICAgY29uc3QgaXNUeXBlRGVjbGFyYXRpb24gPSBkZWNsYXJhdGlvbi50eXBlID09PSBUU19JTlRFUkZBQ0VfREVDTEFSQVRJT05cbiAgICAgIHx8IGRlY2xhcmF0aW9uLnR5cGUgPT09IFRTX1RZUEVfQUxJQVNfREVDTEFSQVRJT05cbiAgICAgIHx8IGRlY2xhcmF0aW9uLnR5cGUgPT09IFRTX0VOVU1fREVDTEFSQVRJT047XG5cbiAgICBpZiAoXG4gICAgICBkZWNsYXJhdGlvbi50eXBlID09PSBGVU5DVElPTl9ERUNMQVJBVElPTlxuICAgICAgfHwgZGVjbGFyYXRpb24udHlwZSA9PT0gQ0xBU1NfREVDTEFSQVRJT05cbiAgICAgIHx8IGlzVHlwZURlY2xhcmF0aW9uXG4gICAgKSB7XG4gICAgICBjYihkZWNsYXJhdGlvbi5pZC5uYW1lLCBpc1R5cGVEZWNsYXJhdGlvbik7XG4gICAgfSBlbHNlIGlmIChkZWNsYXJhdGlvbi50eXBlID09PSBWQVJJQUJMRV9ERUNMQVJBVElPTikge1xuICAgICAgZGVjbGFyYXRpb24uZGVjbGFyYXRpb25zLmZvckVhY2goKHsgaWQgfSkgPT4ge1xuICAgICAgICBpZiAoaWQudHlwZSA9PT0gT0JKRUNUX1BBVFRFUk4pIHtcbiAgICAgICAgICByZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZShpZCwgKHBhdHRlcm4pID0+IHtcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuLnR5cGUgPT09IElERU5USUZJRVIpIHtcbiAgICAgICAgICAgICAgY2IocGF0dGVybi5uYW1lLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaWQudHlwZSA9PT0gQVJSQVlfUEFUVEVSTikge1xuICAgICAgICAgIGlkLmVsZW1lbnRzLmZvckVhY2goKHsgbmFtZSB9KSA9PiB7XG4gICAgICAgICAgICBjYihuYW1lLCBmYWxzZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2IoaWQubmFtZSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBMaXN0IG9mIGltcG9ydHMgcGVyIGZpbGUuXG4gKlxuICogUmVwcmVzZW50ZWQgYnkgYSB0d28tbGV2ZWwgTWFwIHRvIGEgU2V0IG9mIGlkZW50aWZpZXJzLiBUaGUgdXBwZXItbGV2ZWwgTWFwXG4gKiBrZXlzIGFyZSB0aGUgcGF0aHMgdG8gdGhlIG1vZHVsZXMgY29udGFpbmluZyB0aGUgaW1wb3J0cywgd2hpbGUgdGhlXG4gKiBsb3dlci1sZXZlbCBNYXAga2V5cyBhcmUgdGhlIHBhdGhzIHRvIHRoZSBmaWxlcyB3aGljaCBhcmUgYmVpbmcgaW1wb3J0ZWRcbiAqIGZyb20uIExhc3RseSwgdGhlIFNldCBvZiBpZGVudGlmaWVycyBjb250YWlucyBlaXRoZXIgbmFtZXMgYmVpbmcgaW1wb3J0ZWRcbiAqIG9yIGEgc3BlY2lhbCBBU1Qgbm9kZSBuYW1lIGxpc3RlZCBhYm92ZSAoZS5nIEltcG9ydERlZmF1bHRTcGVjaWZpZXIpLlxuICpcbiAqIEZvciBleGFtcGxlLCBpZiB3ZSBoYXZlIGEgZmlsZSBuYW1lZCBmb28uanMgY29udGFpbmluZzpcbiAqXG4gKiAgIGltcG9ydCB7IG8yIH0gZnJvbSAnLi9iYXIuanMnO1xuICpcbiAqIFRoZW4gd2Ugd2lsbCBoYXZlIGEgc3RydWN0dXJlIHRoYXQgbG9va3MgbGlrZTpcbiAqXG4gKiAgIE1hcCB7ICdmb28uanMnID0+IE1hcCB7ICdiYXIuanMnID0+IFNldCB7ICdvMicgfSB9IH1cbiAqXG4gKiBAdHlwZSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgU2V0PHN0cmluZz4+Pn1cbiAqL1xuY29uc3QgaW1wb3J0TGlzdCA9IG5ldyBNYXAoKTtcblxuLyoqXG4gKiBMaXN0IG9mIGV4cG9ydHMgcGVyIGZpbGUuXG4gKlxuICogUmVwcmVzZW50ZWQgYnkgYSB0d28tbGV2ZWwgTWFwIHRvIGFuIG9iamVjdCBvZiBtZXRhZGF0YS4gVGhlIHVwcGVyLWxldmVsIE1hcFxuICoga2V5cyBhcmUgdGhlIHBhdGhzIHRvIHRoZSBtb2R1bGVzIGNvbnRhaW5pbmcgdGhlIGV4cG9ydHMsIHdoaWxlIHRoZVxuICogbG93ZXItbGV2ZWwgTWFwIGtleXMgYXJlIHRoZSBzcGVjaWZpYyBpZGVudGlmaWVycyBvciBzcGVjaWFsIEFTVCBub2RlIG5hbWVzXG4gKiBiZWluZyBleHBvcnRlZC4gVGhlIGxlYWYtbGV2ZWwgbWV0YWRhdGEgb2JqZWN0IGF0IHRoZSBtb21lbnQgb25seSBjb250YWlucyBhXG4gKiBgd2hlcmVVc2VkYCBwcm9wZXJ0eSwgd2hpY2ggY29udGFpbnMgYSBTZXQgb2YgcGF0aHMgdG8gbW9kdWxlcyB0aGF0IGltcG9ydFxuICogdGhlIG5hbWUuXG4gKlxuICogRm9yIGV4YW1wbGUsIGlmIHdlIGhhdmUgYSBmaWxlIG5hbWVkIGJhci5qcyBjb250YWluaW5nIHRoZSBmb2xsb3dpbmcgZXhwb3J0czpcbiAqXG4gKiAgIGNvbnN0IG8yID0gJ2Jhcic7XG4gKiAgIGV4cG9ydCB7IG8yIH07XG4gKlxuICogQW5kIGEgZmlsZSBuYW1lZCBmb28uanMgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIGltcG9ydDpcbiAqXG4gKiAgIGltcG9ydCB7IG8yIH0gZnJvbSAnLi9iYXIuanMnO1xuICpcbiAqIFRoZW4gd2Ugd2lsbCBoYXZlIGEgc3RydWN0dXJlIHRoYXQgbG9va3MgbGlrZTpcbiAqXG4gKiAgIE1hcCB7ICdiYXIuanMnID0+IE1hcCB7ICdvMicgPT4geyB3aGVyZVVzZWQ6IFNldCB7ICdmb28uanMnIH0gfSB9IH1cbiAqXG4gKiBAdHlwZSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgb2JqZWN0Pj59XG4gKi9cbmNvbnN0IGV4cG9ydExpc3QgPSBuZXcgTWFwKCk7XG5cbmNvbnN0IHZpc2l0b3JLZXlNYXAgPSBuZXcgTWFwKCk7XG5cbi8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG5jb25zdCBpZ25vcmVkRmlsZXMgPSBuZXcgU2V0KCk7XG5jb25zdCBmaWxlc091dHNpZGVTcmMgPSBuZXcgU2V0KCk7XG5cbmNvbnN0IGlzTm9kZU1vZHVsZSA9IChwYXRoKSA9PiAoL1xcLyhub2RlX21vZHVsZXMpXFwvLykudGVzdChwYXRoKTtcblxuLyoqXG4gKiByZWFkIGFsbCBmaWxlcyBtYXRjaGluZyB0aGUgcGF0dGVybnMgaW4gc3JjIGFuZCBpZ25vcmVFeHBvcnRzXG4gKlxuICogcmV0dXJuIGFsbCBmaWxlcyBtYXRjaGluZyBzcmMgcGF0dGVybiwgd2hpY2ggYXJlIG5vdCBtYXRjaGluZyB0aGUgaWdub3JlRXhwb3J0cyBwYXR0ZXJuXG4gKiBAdHlwZSB7KHNyYzogc3RyaW5nLCBpZ25vcmVFeHBvcnRzOiBzdHJpbmcsIGNvbnRleHQ6IGltcG9ydCgnZXNsaW50JykuUnVsZS5SdWxlQ29udGV4dCkgPT4gU2V0PHN0cmluZz59XG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGaWxlcyhzcmMsIGlnbm9yZUV4cG9ydHMsIGNvbnRleHQpIHtcbiAgY29uc3QgZXh0ZW5zaW9ucyA9IEFycmF5LmZyb20oZ2V0RmlsZUV4dGVuc2lvbnMoY29udGV4dC5zZXR0aW5ncykpO1xuXG4gIGNvbnN0IHNyY0ZpbGVMaXN0ID0gbGlzdEZpbGVzVG9Qcm9jZXNzKHNyYywgZXh0ZW5zaW9ucyk7XG5cbiAgLy8gcHJlcGFyZSBsaXN0IG9mIGlnbm9yZWQgZmlsZXNcbiAgY29uc3QgaWdub3JlZEZpbGVzTGlzdCA9IGxpc3RGaWxlc1RvUHJvY2VzcyhpZ25vcmVFeHBvcnRzLCBleHRlbnNpb25zKTtcblxuICAvLyBUaGUgbW9kZXJuIGFwaSB3aWxsIHJldHVybiBhIGxpc3Qgb2YgZmlsZSBwYXRocywgcmF0aGVyIHRoYW4gYW4gb2JqZWN0XG4gIGlmIChpZ25vcmVkRmlsZXNMaXN0Lmxlbmd0aCAmJiB0eXBlb2YgaWdub3JlZEZpbGVzTGlzdFswXSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZ25vcmVkRmlsZXNMaXN0LmZvckVhY2goKGZpbGVuYW1lKSA9PiBpZ25vcmVkRmlsZXMuYWRkKGZpbGVuYW1lKSk7XG4gIH0gZWxzZSB7XG4gICAgaWdub3JlZEZpbGVzTGlzdC5mb3JFYWNoKCh7IGZpbGVuYW1lIH0pID0+IGlnbm9yZWRGaWxlcy5hZGQoZmlsZW5hbWUpKTtcbiAgfVxuXG4gIC8vIHByZXBhcmUgbGlzdCBvZiBzb3VyY2UgZmlsZXMsIGRvbid0IGNvbnNpZGVyIGZpbGVzIGZyb20gbm9kZV9tb2R1bGVzXG4gIGNvbnN0IHJlc29sdmVkRmlsZXMgPSBzcmNGaWxlTGlzdC5sZW5ndGggJiYgdHlwZW9mIHNyY0ZpbGVMaXN0WzBdID09PSAnc3RyaW5nJ1xuICAgID8gc3JjRmlsZUxpc3QuZmlsdGVyKChmaWxlUGF0aCkgPT4gIWlzTm9kZU1vZHVsZShmaWxlUGF0aCkpXG4gICAgOiBmbGF0TWFwKHNyY0ZpbGVMaXN0LCAoeyBmaWxlbmFtZSB9KSA9PiBpc05vZGVNb2R1bGUoZmlsZW5hbWUpID8gW10gOiBmaWxlbmFtZSk7XG5cbiAgcmV0dXJuIG5ldyBTZXQocmVzb2x2ZWRGaWxlcyk7XG59XG5cbi8qKlxuICogcGFyc2UgYWxsIHNvdXJjZSBmaWxlcyBhbmQgYnVpbGQgdXAgMiBtYXBzIGNvbnRhaW5pbmcgdGhlIGV4aXN0aW5nIGltcG9ydHMgYW5kIGV4cG9ydHNcbiAqL1xuY29uc3QgcHJlcGFyZUltcG9ydHNBbmRFeHBvcnRzID0gKHNyY0ZpbGVzLCBjb250ZXh0KSA9PiB7XG4gIGNvbnN0IGV4cG9ydEFsbCA9IG5ldyBNYXAoKTtcbiAgc3JjRmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgIGNvbnN0IGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgaW1wb3J0cyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBjdXJyZW50RXhwb3J0cyA9IEV4cG9ydE1hcEJ1aWxkZXIuZ2V0KGZpbGUsIGNvbnRleHQpO1xuICAgIGlmIChjdXJyZW50RXhwb3J0cykge1xuICAgICAgY29uc3Qge1xuICAgICAgICBkZXBlbmRlbmNpZXMsXG4gICAgICAgIHJlZXhwb3J0cyxcbiAgICAgICAgaW1wb3J0czogbG9jYWxJbXBvcnRMaXN0LFxuICAgICAgICBuYW1lc3BhY2UsXG4gICAgICAgIHZpc2l0b3JLZXlzLFxuICAgICAgfSA9IGN1cnJlbnRFeHBvcnRzO1xuXG4gICAgICB2aXNpdG9yS2V5TWFwLnNldChmaWxlLCB2aXNpdG9yS2V5cyk7XG4gICAgICAvLyBkZXBlbmRlbmNpZXMgPT09IGV4cG9ydCAqIGZyb21cbiAgICAgIGNvbnN0IGN1cnJlbnRFeHBvcnRBbGwgPSBuZXcgU2V0KCk7XG4gICAgICBkZXBlbmRlbmNpZXMuZm9yRWFjaCgoZ2V0RGVwZW5kZW5jeSkgPT4ge1xuICAgICAgICBjb25zdCBkZXBlbmRlbmN5ID0gZ2V0RGVwZW5kZW5jeSgpO1xuICAgICAgICBpZiAoZGVwZW5kZW5jeSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRFeHBvcnRBbGwuYWRkKGRlcGVuZGVuY3kucGF0aCk7XG4gICAgICB9KTtcbiAgICAgIGV4cG9ydEFsbC5zZXQoZmlsZSwgY3VycmVudEV4cG9ydEFsbCk7XG5cbiAgICAgIHJlZXhwb3J0cy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09IERFRkFVTFQpIHtcbiAgICAgICAgICBleHBvcnRzLnNldChJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIsIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXhwb3J0cy5zZXQoa2V5LCB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlZXhwb3J0ID0gdmFsdWUuZ2V0SW1wb3J0KCk7XG4gICAgICAgIGlmICghcmVleHBvcnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxvY2FsSW1wb3J0ID0gaW1wb3J0cy5nZXQocmVleHBvcnQucGF0aCk7XG4gICAgICAgIGxldCBjdXJyZW50VmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZS5sb2NhbCA9PT0gREVGQVVMVCkge1xuICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50VmFsdWUgPSB2YWx1ZS5sb2NhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGxvY2FsSW1wb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGxvY2FsSW1wb3J0ID0gbmV3IFNldChbLi4ubG9jYWxJbXBvcnQsIGN1cnJlbnRWYWx1ZV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvY2FsSW1wb3J0ID0gbmV3IFNldChbY3VycmVudFZhbHVlXSk7XG4gICAgICAgIH1cbiAgICAgICAgaW1wb3J0cy5zZXQocmVleHBvcnQucGF0aCwgbG9jYWxJbXBvcnQpO1xuICAgICAgfSk7XG5cbiAgICAgIGxvY2FsSW1wb3J0TGlzdC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChpc05vZGVNb2R1bGUoa2V5KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsb2NhbEltcG9ydCA9IGltcG9ydHMuZ2V0KGtleSkgfHwgbmV3IFNldCgpO1xuICAgICAgICB2YWx1ZS5kZWNsYXJhdGlvbnMuZm9yRWFjaCgoeyBpbXBvcnRlZFNwZWNpZmllcnMgfSkgPT4ge1xuICAgICAgICAgIGltcG9ydGVkU3BlY2lmaWVycy5mb3JFYWNoKChzcGVjaWZpZXIpID0+IHtcbiAgICAgICAgICAgIGxvY2FsSW1wb3J0LmFkZChzcGVjaWZpZXIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgaW1wb3J0cy5zZXQoa2V5LCBsb2NhbEltcG9ydCk7XG4gICAgICB9KTtcbiAgICAgIGltcG9ydExpc3Quc2V0KGZpbGUsIGltcG9ydHMpO1xuXG4gICAgICAvLyBidWlsZCB1cCBleHBvcnQgbGlzdCBvbmx5LCBpZiBmaWxlIGlzIG5vdCBpZ25vcmVkXG4gICAgICBpZiAoaWdub3JlZEZpbGVzLmhhcyhmaWxlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBuYW1lc3BhY2UuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSBERUZBVUxUKSB7XG4gICAgICAgICAgZXhwb3J0cy5zZXQoSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSLCB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGV4cG9ydHMuc2V0KGtleSwgeyB3aGVyZVVzZWQ6IG5ldyBTZXQoKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGV4cG9ydHMuc2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04sIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgZXhwb3J0cy5zZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIsIHsgd2hlcmVVc2VkOiBuZXcgU2V0KCkgfSk7XG4gICAgZXhwb3J0TGlzdC5zZXQoZmlsZSwgZXhwb3J0cyk7XG4gIH0pO1xuICBleHBvcnRBbGwuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgIHZhbHVlLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudEV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWwpO1xuICAgICAgaWYgKGN1cnJlbnRFeHBvcnRzKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRFeHBvcnQgPSBjdXJyZW50RXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmFkZChrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn07XG5cbi8qKlxuICogdHJhdmVyc2UgdGhyb3VnaCBhbGwgaW1wb3J0cyBhbmQgYWRkIHRoZSByZXNwZWN0aXZlIHBhdGggdG8gdGhlIHdoZXJlVXNlZC1saXN0XG4gKiBvZiB0aGUgY29ycmVzcG9uZGluZyBleHBvcnRcbiAqL1xuY29uc3QgZGV0ZXJtaW5lVXNhZ2UgPSAoKSA9PiB7XG4gIGltcG9ydExpc3QuZm9yRWFjaCgobGlzdFZhbHVlLCBsaXN0S2V5KSA9PiB7XG4gICAgbGlzdFZhbHVlLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldChrZXkpO1xuICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKChjdXJyZW50SW1wb3J0KSA9PiB7XG4gICAgICAgICAgbGV0IHNwZWNpZmllcjtcbiAgICAgICAgICBpZiAoY3VycmVudEltcG9ydCA9PT0gSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpIHtcbiAgICAgICAgICAgIHNwZWNpZmllciA9IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudEltcG9ydCA9PT0gSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKSB7XG4gICAgICAgICAgICBzcGVjaWZpZXIgPSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNwZWNpZmllciA9IGN1cnJlbnRJbXBvcnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2Ygc3BlY2lmaWVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgZXhwb3J0U3RhdGVtZW50ID0gZXhwb3J0cy5nZXQoc3BlY2lmaWVyKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXhwb3J0U3RhdGVtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBjb25zdCB7IHdoZXJlVXNlZCB9ID0gZXhwb3J0U3RhdGVtZW50O1xuICAgICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGxpc3RLZXkpO1xuICAgICAgICAgICAgICBleHBvcnRzLnNldChzcGVjaWZpZXIsIHsgd2hlcmVVc2VkIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuY29uc3QgZ2V0U3JjID0gKHNyYykgPT4ge1xuICBpZiAoc3JjKSB7XG4gICAgcmV0dXJuIHNyYztcbiAgfVxuICByZXR1cm4gW3Byb2Nlc3MuY3dkKCldO1xufTtcblxuLyoqXG4gKiBwcmVwYXJlIHRoZSBsaXN0cyBvZiBleGlzdGluZyBpbXBvcnRzIGFuZCBleHBvcnRzIC0gc2hvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgb25jZSBhdFxuICogdGhlIHN0YXJ0IG9mIGEgbmV3IGVzbGludCBydW5cbiAqL1xuLyoqIEB0eXBlIHtTZXQ8c3RyaW5nPn0gKi9cbmxldCBzcmNGaWxlcztcbmxldCBsYXN0UHJlcGFyZUtleTtcbmNvbnN0IGRvUHJlcGFyYXRpb24gPSAoc3JjLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KSA9PiB7XG4gIGNvbnN0IHByZXBhcmVLZXkgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgc3JjOiAoc3JjIHx8IFtdKS5zb3J0KCksXG4gICAgaWdub3JlRXhwb3J0czogKGlnbm9yZUV4cG9ydHMgfHwgW10pLnNvcnQoKSxcbiAgICBleHRlbnNpb25zOiBBcnJheS5mcm9tKGdldEZpbGVFeHRlbnNpb25zKGNvbnRleHQuc2V0dGluZ3MpKS5zb3J0KCksXG4gIH0pO1xuICBpZiAocHJlcGFyZUtleSA9PT0gbGFzdFByZXBhcmVLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpbXBvcnRMaXN0LmNsZWFyKCk7XG4gIGV4cG9ydExpc3QuY2xlYXIoKTtcbiAgaWdub3JlZEZpbGVzLmNsZWFyKCk7XG4gIGZpbGVzT3V0c2lkZVNyYy5jbGVhcigpO1xuXG4gIHNyY0ZpbGVzID0gcmVzb2x2ZUZpbGVzKGdldFNyYyhzcmMpLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgcHJlcGFyZUltcG9ydHNBbmRFeHBvcnRzKHNyY0ZpbGVzLCBjb250ZXh0KTtcbiAgZGV0ZXJtaW5lVXNhZ2UoKTtcbiAgbGFzdFByZXBhcmVLZXkgPSBwcmVwYXJlS2V5O1xufTtcblxuY29uc3QgbmV3TmFtZXNwYWNlSW1wb3J0RXhpc3RzID0gKHNwZWNpZmllcnMpID0+IHNwZWNpZmllcnMuc29tZSgoeyB0eXBlIH0pID0+IHR5cGUgPT09IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcblxuY29uc3QgbmV3RGVmYXVsdEltcG9ydEV4aXN0cyA9IChzcGVjaWZpZXJzKSA9PiBzcGVjaWZpZXJzLnNvbWUoKHsgdHlwZSB9KSA9PiB0eXBlID09PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpO1xuXG5jb25zdCBmaWxlSXNJblBrZyA9IChmaWxlKSA9PiB7XG4gIGNvbnN0IHsgcGF0aCwgcGtnIH0gPSByZWFkUGtnVXAoeyBjd2Q6IGZpbGUgfSk7XG4gIGNvbnN0IGJhc2VQYXRoID0gZGlybmFtZShwYXRoKTtcblxuICBjb25zdCBjaGVja1BrZ0ZpZWxkU3RyaW5nID0gKHBrZ0ZpZWxkKSA9PiB7XG4gICAgaWYgKGpvaW4oYmFzZVBhdGgsIHBrZ0ZpZWxkKSA9PT0gZmlsZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGNoZWNrUGtnRmllbGRPYmplY3QgPSAocGtnRmllbGQpID0+IHtcbiAgICBjb25zdCBwa2dGaWVsZEZpbGVzID0gZmxhdE1hcCh2YWx1ZXMocGtnRmllbGQpLCAodmFsdWUpID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nID8gW10gOiBqb2luKGJhc2VQYXRoLCB2YWx1ZSkpO1xuXG4gICAgaWYgKGluY2x1ZGVzKHBrZ0ZpZWxkRmlsZXMsIGZpbGUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgY2hlY2tQa2dGaWVsZCA9IChwa2dGaWVsZCkgPT4ge1xuICAgIGlmICh0eXBlb2YgcGtnRmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gY2hlY2tQa2dGaWVsZFN0cmluZyhwa2dGaWVsZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwa2dGaWVsZCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBjaGVja1BrZ0ZpZWxkT2JqZWN0KHBrZ0ZpZWxkKTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKHBrZy5wcml2YXRlID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHBrZy5iaW4pIHtcbiAgICBpZiAoY2hlY2tQa2dGaWVsZChwa2cuYmluKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBrZy5icm93c2VyKSB7XG4gICAgaWYgKGNoZWNrUGtnRmllbGQocGtnLmJyb3dzZXIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAocGtnLm1haW4pIHtcbiAgICBpZiAoY2hlY2tQa2dGaWVsZFN0cmluZyhwa2cubWFpbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGNhdGVnb3J5OiAnSGVscGZ1bCB3YXJuaW5ncycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0ZvcmJpZCBtb2R1bGVzIHdpdGhvdXQgZXhwb3J0cywgb3IgZXhwb3J0cyB3aXRob3V0IG1hdGNoaW5nIGltcG9ydCBpbiBhbm90aGVyIG1vZHVsZS4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCduby11bnVzZWQtbW9kdWxlcycpLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbe1xuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBzcmM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ2ZpbGVzL3BhdGhzIHRvIGJlIGFuYWx5emVkIChvbmx5IGZvciB1bnVzZWQgZXhwb3J0cyknLFxuICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgdW5pcXVlSXRlbXM6IHRydWUsXG4gICAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgbWluTGVuZ3RoOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGlnbm9yZUV4cG9ydHM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ2ZpbGVzL3BhdGhzIGZvciB3aGljaCB1bnVzZWQgZXhwb3J0cyB3aWxsIG5vdCBiZSByZXBvcnRlZCAoZS5nIG1vZHVsZSBlbnRyeSBwb2ludHMpJyxcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBtaXNzaW5nRXhwb3J0czoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAncmVwb3J0IG1vZHVsZXMgd2l0aG91dCBhbnkgZXhwb3J0cycsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgICB1bnVzZWRFeHBvcnRzOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdyZXBvcnQgZXhwb3J0cyB3aXRob3V0IGFueSB1c2FnZScsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgICBpZ25vcmVVbnVzZWRUeXBlRXhwb3J0czoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnaWdub3JlIHR5cGUgZXhwb3J0cyB3aXRob3V0IGFueSB1c2FnZScsXG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFueU9mOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICB1bnVzZWRFeHBvcnRzOiB7IGVudW06IFt0cnVlXSB9LFxuICAgICAgICAgICAgc3JjOiB7XG4gICAgICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVpcmVkOiBbJ3VudXNlZEV4cG9ydHMnXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIG1pc3NpbmdFeHBvcnRzOiB7IGVudW06IFt0cnVlXSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVxdWlyZWQ6IFsnbWlzc2luZ0V4cG9ydHMnXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfV0sXG4gIH0sXG5cbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCB7XG4gICAgICBzcmMsXG4gICAgICBpZ25vcmVFeHBvcnRzID0gW10sXG4gICAgICBtaXNzaW5nRXhwb3J0cyxcbiAgICAgIHVudXNlZEV4cG9ydHMsXG4gICAgICBpZ25vcmVVbnVzZWRUeXBlRXhwb3J0cyxcbiAgICB9ID0gY29udGV4dC5vcHRpb25zWzBdIHx8IHt9O1xuXG4gICAgaWYgKHVudXNlZEV4cG9ydHMpIHtcbiAgICAgIGRvUHJlcGFyYXRpb24oc3JjLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlID0gZ2V0UGh5c2ljYWxGaWxlbmFtZShjb250ZXh0KTtcblxuICAgIGNvbnN0IGNoZWNrRXhwb3J0UHJlc2VuY2UgPSAobm9kZSkgPT4ge1xuICAgICAgaWYgKCFtaXNzaW5nRXhwb3J0cykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpZ25vcmVkRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhwb3J0Q291bnQgPSBleHBvcnRMaXN0LmdldChmaWxlKTtcbiAgICAgIGNvbnN0IGV4cG9ydEFsbCA9IGV4cG9ydENvdW50LmdldChFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcbiAgICAgIGNvbnN0IG5hbWVzcGFjZUltcG9ydHMgPSBleHBvcnRDb3VudC5nZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuXG4gICAgICBleHBvcnRDb3VudC5kZWxldGUoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICBleHBvcnRDb3VudC5kZWxldGUoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuICAgICAgaWYgKGV4cG9ydENvdW50LnNpemUgPCAxKSB7XG4gICAgICAgIC8vIG5vZGUuYm9keVswXSA9PT0gJ3VuZGVmaW5lZCcgb25seSBoYXBwZW5zLCBpZiBldmVyeXRoaW5nIGlzIGNvbW1lbnRlZCBvdXQgaW4gdGhlIGZpbGVcbiAgICAgICAgLy8gYmVpbmcgbGludGVkXG4gICAgICAgIGNvbnRleHQucmVwb3J0KG5vZGUuYm9keVswXSA/IG5vZGUuYm9keVswXSA6IG5vZGUsICdObyBleHBvcnRzIGZvdW5kJyk7XG4gICAgICB9XG4gICAgICBleHBvcnRDb3VudC5zZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTiwgZXhwb3J0QWxsKTtcbiAgICAgIGV4cG9ydENvdW50LnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgbmFtZXNwYWNlSW1wb3J0cyk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNoZWNrVXNhZ2UgPSAobm9kZSwgZXhwb3J0ZWRWYWx1ZSwgaXNUeXBlRXhwb3J0KSA9PiB7XG4gICAgICBpZiAoIXVudXNlZEV4cG9ydHMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNUeXBlRXhwb3J0ICYmIGlnbm9yZVVudXNlZFR5cGVFeHBvcnRzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlnbm9yZWRGaWxlcy5oYXMoZmlsZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZUlzSW5Qa2coZmlsZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmlsZXNPdXRzaWRlU3JjLmhhcyhmaWxlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIG1ha2Ugc3VyZSBmaWxlIHRvIGJlIGxpbnRlZCBpcyBpbmNsdWRlZCBpbiBzb3VyY2UgZmlsZXNcbiAgICAgIGlmICghc3JjRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHNyY0ZpbGVzID0gcmVzb2x2ZUZpbGVzKGdldFNyYyhzcmMpLCBpZ25vcmVFeHBvcnRzLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKCFzcmNGaWxlcy5oYXMoZmlsZSkpIHtcbiAgICAgICAgICBmaWxlc091dHNpZGVTcmMuYWRkKGZpbGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBleHBvcnRzID0gZXhwb3J0TGlzdC5nZXQoZmlsZSk7XG5cbiAgICAgIGlmICghZXhwb3J0cykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBmaWxlIFxcYCR7ZmlsZX1cXGAgaGFzIG5vIGV4cG9ydHMuIFBsZWFzZSB1cGRhdGUgdG8gdGhlIGxhdGVzdCwgYW5kIGlmIGl0IHN0aWxsIGhhcHBlbnMsIHJlcG9ydCB0aGlzIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9pbXBvcnQtanMvZXNsaW50LXBsdWdpbi1pbXBvcnQvaXNzdWVzLzI4NjYhYCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogZXhwb3J0ICogZnJvbVxuICAgICAgY29uc3QgZXhwb3J0QWxsID0gZXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICBpZiAodHlwZW9mIGV4cG9ydEFsbCAhPT0gJ3VuZGVmaW5lZCcgJiYgZXhwb3J0ZWRWYWx1ZSAhPT0gSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKSB7XG4gICAgICAgIGlmIChleHBvcnRBbGwud2hlcmVVc2VkLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogbmFtZXNwYWNlIGltcG9ydFxuICAgICAgY29uc3QgbmFtZXNwYWNlSW1wb3J0cyA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgIGlmICh0eXBlb2YgbmFtZXNwYWNlSW1wb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKG5hbWVzcGFjZUltcG9ydHMud2hlcmVVc2VkLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGV4cG9ydHNMaXN0IHdpbGwgYWx3YXlzIG1hcCBhbnkgaW1wb3J0ZWQgdmFsdWUgb2YgJ2RlZmF1bHQnIHRvICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJ1xuICAgICAgY29uc3QgZXhwb3J0c0tleSA9IGV4cG9ydGVkVmFsdWUgPT09IERFRkFVTFQgPyBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgOiBleHBvcnRlZFZhbHVlO1xuXG4gICAgICBjb25zdCBleHBvcnRTdGF0ZW1lbnQgPSBleHBvcnRzLmdldChleHBvcnRzS2V5KTtcblxuICAgICAgY29uc3QgdmFsdWUgPSBleHBvcnRzS2V5ID09PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgPyBERUZBVUxUIDogZXhwb3J0c0tleTtcblxuICAgICAgaWYgKHR5cGVvZiBleHBvcnRTdGF0ZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChleHBvcnRTdGF0ZW1lbnQud2hlcmVVc2VkLnNpemUgPCAxKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgYGV4cG9ydGVkIGRlY2xhcmF0aW9uICcke3ZhbHVlfScgbm90IHVzZWQgd2l0aGluIG90aGVyIG1vZHVsZXNgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgYGV4cG9ydGVkIGRlY2xhcmF0aW9uICcke3ZhbHVlfScgbm90IHVzZWQgd2l0aGluIG90aGVyIG1vZHVsZXNgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBvbmx5IHVzZWZ1bCBmb3IgdG9vbHMgbGlrZSB2c2NvZGUtZXNsaW50XG4gICAgICpcbiAgICAgKiB1cGRhdGUgbGlzdHMgb2YgZXhpc3RpbmcgZXhwb3J0cyBkdXJpbmcgcnVudGltZVxuICAgICAqL1xuICAgIGNvbnN0IHVwZGF0ZUV4cG9ydFVzYWdlID0gKG5vZGUpID0+IHtcbiAgICAgIGlmIChpZ25vcmVkRmlsZXMuaGFzKGZpbGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldChmaWxlKTtcblxuICAgICAgLy8gbmV3IG1vZHVsZSBoYXMgYmVlbiBjcmVhdGVkIGR1cmluZyBydW50aW1lXG4gICAgICAvLyBpbmNsdWRlIGl0IGluIGZ1cnRoZXIgcHJvY2Vzc2luZ1xuICAgICAgaWYgKHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdFeHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgY29uc3QgbmV3RXhwb3J0SWRlbnRpZmllcnMgPSBuZXcgU2V0KCk7XG5cbiAgICAgIG5vZGUuYm9keS5mb3JFYWNoKCh7IHR5cGUsIGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzIH0pID0+IHtcbiAgICAgICAgaWYgKHR5cGUgPT09IEVYUE9SVF9ERUZBVUxUX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgbmV3RXhwb3J0SWRlbnRpZmllcnMuYWRkKElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09IEVYUE9SVF9OQU1FRF9ERUNMQVJBVElPTikge1xuICAgICAgICAgIGlmIChzcGVjaWZpZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNwZWNpZmllcnMuZm9yRWFjaCgoc3BlY2lmaWVyKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChzcGVjaWZpZXIuZXhwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICBuZXdFeHBvcnRJZGVudGlmaWVycy5hZGQoc3BlY2lmaWVyLmV4cG9ydGVkLm5hbWUgfHwgc3BlY2lmaWVyLmV4cG9ydGVkLnZhbHVlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvckVhY2hEZWNsYXJhdGlvbklkZW50aWZpZXIoZGVjbGFyYXRpb24sIChuYW1lKSA9PiB7XG4gICAgICAgICAgICBuZXdFeHBvcnRJZGVudGlmaWVycy5hZGQobmFtZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBvbGQgZXhwb3J0cyBleGlzdCB3aXRoaW4gbGlzdCBvZiBuZXcgZXhwb3J0cyBpZGVudGlmaWVyczogYWRkIHRvIG1hcCBvZiBuZXcgZXhwb3J0c1xuICAgICAgZXhwb3J0cy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGlmIChuZXdFeHBvcnRJZGVudGlmaWVycy5oYXMoa2V5KSkge1xuICAgICAgICAgIG5ld0V4cG9ydHMuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gbmV3IGV4cG9ydCBpZGVudGlmaWVycyBhZGRlZDogYWRkIHRvIG1hcCBvZiBuZXcgZXhwb3J0c1xuICAgICAgbmV3RXhwb3J0SWRlbnRpZmllcnMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmICghZXhwb3J0cy5oYXMoa2V5KSkge1xuICAgICAgICAgIG5ld0V4cG9ydHMuc2V0KGtleSwgeyB3aGVyZVVzZWQ6IG5ldyBTZXQoKSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIHByZXNlcnZlIGluZm9ybWF0aW9uIGFib3V0IG5hbWVzcGFjZSBpbXBvcnRzXG4gICAgICBjb25zdCBleHBvcnRBbGwgPSBleHBvcnRzLmdldChFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcbiAgICAgIGxldCBuYW1lc3BhY2VJbXBvcnRzID0gZXhwb3J0cy5nZXQoSU1QT1JUX05BTUVTUEFDRV9TUEVDSUZJRVIpO1xuXG4gICAgICBpZiAodHlwZW9mIG5hbWVzcGFjZUltcG9ydHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG5hbWVzcGFjZUltcG9ydHMgPSB7IHdoZXJlVXNlZDogbmV3IFNldCgpIH07XG4gICAgICB9XG5cbiAgICAgIG5ld0V4cG9ydHMuc2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04sIGV4cG9ydEFsbCk7XG4gICAgICBuZXdFeHBvcnRzLnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgbmFtZXNwYWNlSW1wb3J0cyk7XG4gICAgICBleHBvcnRMaXN0LnNldChmaWxlLCBuZXdFeHBvcnRzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogb25seSB1c2VmdWwgZm9yIHRvb2xzIGxpa2UgdnNjb2RlLWVzbGludFxuICAgICAqXG4gICAgICogdXBkYXRlIGxpc3RzIG9mIGV4aXN0aW5nIGltcG9ydHMgZHVyaW5nIHJ1bnRpbWVcbiAgICAgKi9cbiAgICBjb25zdCB1cGRhdGVJbXBvcnRVc2FnZSA9IChub2RlKSA9PiB7XG4gICAgICBpZiAoIXVudXNlZEV4cG9ydHMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgb2xkSW1wb3J0UGF0aHMgPSBpbXBvcnRMaXN0LmdldChmaWxlKTtcbiAgICAgIGlmICh0eXBlb2Ygb2xkSW1wb3J0UGF0aHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIG9sZEltcG9ydFBhdGhzID0gbmV3IE1hcCgpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvbGROYW1lc3BhY2VJbXBvcnRzID0gbmV3IFNldCgpO1xuICAgICAgY29uc3QgbmV3TmFtZXNwYWNlSW1wb3J0cyA9IG5ldyBTZXQoKTtcblxuICAgICAgY29uc3Qgb2xkRXhwb3J0QWxsID0gbmV3IFNldCgpO1xuICAgICAgY29uc3QgbmV3RXhwb3J0QWxsID0gbmV3IFNldCgpO1xuXG4gICAgICBjb25zdCBvbGREZWZhdWx0SW1wb3J0cyA9IG5ldyBTZXQoKTtcbiAgICAgIGNvbnN0IG5ld0RlZmF1bHRJbXBvcnRzID0gbmV3IFNldCgpO1xuXG4gICAgICBjb25zdCBvbGRJbXBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgY29uc3QgbmV3SW1wb3J0cyA9IG5ldyBNYXAoKTtcbiAgICAgIG9sZEltcG9ydFBhdGhzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKHZhbHVlLmhhcyhFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKSkge1xuICAgICAgICAgIG9sZEV4cG9ydEFsbC5hZGQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUuaGFzKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKSkge1xuICAgICAgICAgIG9sZE5hbWVzcGFjZUltcG9ydHMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlLmhhcyhJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpKSB7XG4gICAgICAgICAgb2xkRGVmYXVsdEltcG9ydHMuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWUuZm9yRWFjaCgodmFsKSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdmFsICE9PSBJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUlxuICAgICAgICAgICAgJiYgdmFsICE9PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVJcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG9sZEltcG9ydHMuc2V0KHZhbCwga2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGZ1bmN0aW9uIHByb2Nlc3NEeW5hbWljSW1wb3J0KHNvdXJjZSkge1xuICAgICAgICBpZiAoc291cmNlLnR5cGUgIT09ICdMaXRlcmFsJykge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHAgPSByZXNvbHZlKHNvdXJjZS52YWx1ZSwgY29udGV4dCk7XG4gICAgICAgIGlmIChwID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBuZXdOYW1lc3BhY2VJbXBvcnRzLmFkZChwKTtcbiAgICAgIH1cblxuICAgICAgdmlzaXQobm9kZSwgdmlzaXRvcktleU1hcC5nZXQoZmlsZSksIHtcbiAgICAgICAgSW1wb3J0RXhwcmVzc2lvbihjaGlsZCkge1xuICAgICAgICAgIHByb2Nlc3NEeW5hbWljSW1wb3J0KGNoaWxkLnNvdXJjZSk7XG4gICAgICAgIH0sXG4gICAgICAgIENhbGxFeHByZXNzaW9uKGNoaWxkKSB7XG4gICAgICAgICAgaWYgKGNoaWxkLmNhbGxlZS50eXBlID09PSAnSW1wb3J0Jykge1xuICAgICAgICAgICAgcHJvY2Vzc0R5bmFtaWNJbXBvcnQoY2hpbGQuYXJndW1lbnRzWzBdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgbm9kZS5ib2R5LmZvckVhY2goKGFzdE5vZGUpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkUGF0aDtcblxuICAgICAgICAvLyBzdXBwb3J0IGZvciBleHBvcnQgeyB2YWx1ZSB9IGZyb20gJ21vZHVsZSdcbiAgICAgICAgaWYgKGFzdE5vZGUudHlwZSA9PT0gRVhQT1JUX05BTUVEX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgaWYgKGFzdE5vZGUuc291cmNlKSB7XG4gICAgICAgICAgICByZXNvbHZlZFBhdGggPSByZXNvbHZlKGFzdE5vZGUuc291cmNlLnJhdy5yZXBsYWNlKC8oJ3xcIikvZywgJycpLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGFzdE5vZGUuc3BlY2lmaWVycy5mb3JFYWNoKChzcGVjaWZpZXIpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHNwZWNpZmllci5sb2NhbC5uYW1lIHx8IHNwZWNpZmllci5sb2NhbC52YWx1ZTtcbiAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IERFRkFVTFQpIHtcbiAgICAgICAgICAgICAgICBuZXdEZWZhdWx0SW1wb3J0cy5hZGQocmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdJbXBvcnRzLnNldChuYW1lLCByZXNvbHZlZFBhdGgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXN0Tm9kZS50eXBlID09PSBFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShhc3ROb2RlLnNvdXJjZS5yYXcucmVwbGFjZSgvKCd8XCIpL2csICcnKSwgY29udGV4dCk7XG4gICAgICAgICAgbmV3RXhwb3J0QWxsLmFkZChyZXNvbHZlZFBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFzdE5vZGUudHlwZSA9PT0gSU1QT1JUX0RFQ0xBUkFUSU9OKSB7XG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZShhc3ROb2RlLnNvdXJjZS5yYXcucmVwbGFjZSgvKCd8XCIpL2csICcnKSwgY29udGV4dCk7XG4gICAgICAgICAgaWYgKCFyZXNvbHZlZFBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNOb2RlTW9kdWxlKHJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobmV3TmFtZXNwYWNlSW1wb3J0RXhpc3RzKGFzdE5vZGUuc3BlY2lmaWVycykpIHtcbiAgICAgICAgICAgIG5ld05hbWVzcGFjZUltcG9ydHMuYWRkKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5ld0RlZmF1bHRJbXBvcnRFeGlzdHMoYXN0Tm9kZS5zcGVjaWZpZXJzKSkge1xuICAgICAgICAgICAgbmV3RGVmYXVsdEltcG9ydHMuYWRkKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXN0Tm9kZS5zcGVjaWZpZXJzXG4gICAgICAgICAgICAuZmlsdGVyKChzcGVjaWZpZXIpID0+IHNwZWNpZmllci50eXBlICE9PSBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIgJiYgc3BlY2lmaWVyLnR5cGUgIT09IElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKVxuICAgICAgICAgICAgLmZvckVhY2goKHNwZWNpZmllcikgPT4ge1xuICAgICAgICAgICAgICBuZXdJbXBvcnRzLnNldChzcGVjaWZpZXIuaW1wb3J0ZWQubmFtZSB8fCBzcGVjaWZpZXIuaW1wb3J0ZWQudmFsdWUsIHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG5ld0V4cG9ydEFsbC5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoIW9sZEV4cG9ydEFsbC5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKEVYUE9SVF9BTExfREVDTEFSQVRJT04pO1xuICAgICAgICAgIG9sZEltcG9ydFBhdGhzLnNldCh2YWx1ZSwgaW1wb3J0cyk7XG5cbiAgICAgICAgICBsZXQgZXhwb3J0cyA9IGV4cG9ydExpc3QuZ2V0KHZhbHVlKTtcbiAgICAgICAgICBsZXQgY3VycmVudEV4cG9ydDtcbiAgICAgICAgICBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjdXJyZW50RXhwb3J0ID0gZXhwb3J0cy5nZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBleHBvcnRMaXN0LnNldCh2YWx1ZSwgZXhwb3J0cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3aGVyZVVzZWQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgICAgZXhwb3J0cy5zZXQoRVhQT1JUX0FMTF9ERUNMQVJBVElPTiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkRXhwb3J0QWxsLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICghbmV3RXhwb3J0QWxsLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICBjb25zdCBpbXBvcnRzID0gb2xkSW1wb3J0UGF0aHMuZ2V0KHZhbHVlKTtcbiAgICAgICAgICBpbXBvcnRzLmRlbGV0ZShFWFBPUlRfQUxMX0RFQ0xBUkFUSU9OKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KEVYUE9SVF9BTExfREVDTEFSQVRJT04pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICBjdXJyZW50RXhwb3J0LndoZXJlVXNlZC5kZWxldGUoZmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgbmV3RGVmYXVsdEltcG9ydHMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKCFvbGREZWZhdWx0SW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgICAgb2xkSW1wb3J0UGF0aHMuc2V0KHZhbHVlLCBpbXBvcnRzKTtcblxuICAgICAgICAgIGxldCBleHBvcnRzID0gZXhwb3J0TGlzdC5nZXQodmFsdWUpO1xuICAgICAgICAgIGxldCBjdXJyZW50RXhwb3J0O1xuICAgICAgICAgIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQgPSBleHBvcnRzLmdldChJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHBvcnRzID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgZXhwb3J0TGlzdC5zZXQodmFsdWUsIGV4cG9ydHMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudEV4cG9ydCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmFkZChmaWxlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgd2hlcmVVc2VkID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgd2hlcmVVc2VkLmFkZChmaWxlKTtcbiAgICAgICAgICAgIGV4cG9ydHMuc2V0KElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkRGVmYXVsdEltcG9ydHMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKCFuZXdEZWZhdWx0SW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgY29uc3QgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaW1wb3J0cy5kZWxldGUoSU1QT1JUX0RFRkFVTFRfU1BFQ0lGSUVSKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9ERUZBVUxUX1NQRUNJRklFUik7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmRlbGV0ZShmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBuZXdOYW1lc3BhY2VJbXBvcnRzLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICghb2xkTmFtZXNwYWNlSW1wb3J0cy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgbGV0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGlmICh0eXBlb2YgaW1wb3J0cyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGltcG9ydHMgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGltcG9ydHMuYWRkKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICBvbGRJbXBvcnRQYXRocy5zZXQodmFsdWUsIGltcG9ydHMpO1xuXG4gICAgICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgbGV0IGN1cnJlbnRFeHBvcnQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXhwb3J0cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGV4cG9ydExpc3Quc2V0KHZhbHVlLCBleHBvcnRzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjdXJyZW50RXhwb3J0LndoZXJlVXNlZC5hZGQoZmlsZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHdoZXJlVXNlZCA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIHdoZXJlVXNlZC5hZGQoZmlsZSk7XG4gICAgICAgICAgICBleHBvcnRzLnNldChJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiwgeyB3aGVyZVVzZWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb2xkTmFtZXNwYWNlSW1wb3J0cy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoIW5ld05hbWVzcGFjZUltcG9ydHMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgIGNvbnN0IGltcG9ydHMgPSBvbGRJbXBvcnRQYXRocy5nZXQodmFsdWUpO1xuICAgICAgICAgIGltcG9ydHMuZGVsZXRlKElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KElNUE9SVF9OQU1FU1BBQ0VfU1BFQ0lGSUVSKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudEV4cG9ydCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuZGVsZXRlKGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG5ld0ltcG9ydHMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICBpZiAoIW9sZEltcG9ydHMuaGFzKGtleSkpIHtcbiAgICAgICAgICBsZXQgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBpbXBvcnRzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgaW1wb3J0cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW1wb3J0cy5hZGQoa2V5KTtcbiAgICAgICAgICBvbGRJbXBvcnRQYXRocy5zZXQodmFsdWUsIGltcG9ydHMpO1xuXG4gICAgICAgICAgbGV0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgbGV0IGN1cnJlbnRFeHBvcnQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KGtleSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBleHBvcnRMaXN0LnNldCh2YWx1ZSwgZXhwb3J0cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50RXhwb3J0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3VycmVudEV4cG9ydC53aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB3aGVyZVVzZWQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICB3aGVyZVVzZWQuYWRkKGZpbGUpO1xuICAgICAgICAgICAgZXhwb3J0cy5zZXQoa2V5LCB7IHdoZXJlVXNlZCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBvbGRJbXBvcnRzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKCFuZXdJbXBvcnRzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgY29uc3QgaW1wb3J0cyA9IG9sZEltcG9ydFBhdGhzLmdldCh2YWx1ZSk7XG4gICAgICAgICAgaW1wb3J0cy5kZWxldGUoa2V5KTtcblxuICAgICAgICAgIGNvbnN0IGV4cG9ydHMgPSBleHBvcnRMaXN0LmdldCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEV4cG9ydCA9IGV4cG9ydHMuZ2V0KGtleSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRFeHBvcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGN1cnJlbnRFeHBvcnQud2hlcmVVc2VkLmRlbGV0ZShmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgJ1Byb2dyYW06ZXhpdCcobm9kZSkge1xuICAgICAgICB1cGRhdGVFeHBvcnRVc2FnZShub2RlKTtcbiAgICAgICAgdXBkYXRlSW1wb3J0VXNhZ2Uobm9kZSk7XG4gICAgICAgIGNoZWNrRXhwb3J0UHJlc2VuY2Uobm9kZSk7XG4gICAgICB9LFxuICAgICAgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgY2hlY2tVc2FnZShub2RlLCBJTVBPUlRfREVGQVVMVF9TUEVDSUZJRVIsIGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBFeHBvcnROYW1lZERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS5zcGVjaWZpZXJzLmZvckVhY2goKHNwZWNpZmllcikgPT4ge1xuICAgICAgICAgIGNoZWNrVXNhZ2Uoc3BlY2lmaWVyLCBzcGVjaWZpZXIuZXhwb3J0ZWQubmFtZSB8fCBzcGVjaWZpZXIuZXhwb3J0ZWQudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZvckVhY2hEZWNsYXJhdGlvbklkZW50aWZpZXIobm9kZS5kZWNsYXJhdGlvbiwgKG5hbWUsIGlzVHlwZUV4cG9ydCkgPT4ge1xuICAgICAgICAgIGNoZWNrVXNhZ2Uobm9kZSwgbmFtZSwgaXNUeXBlRXhwb3J0KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuIl19
index.d.ts +33 lines
--- +++ @@ -0,0 +1,33 @@+import { ESLint, Linter, Rule } from 'eslint';++declare const plugin: ESLint.Plugin & {+  meta: {+    name: string;+    version: string;+  };+  configs: {+    'recommended': Linter.LegacyConfig;+    'errors': Linter.LegacyConfig;+    'warnings': Linter.LegacyConfig;+    'stage-0': Linter.LegacyConfig;+    'react': Linter.LegacyConfig;+    'react-native': Linter.LegacyConfig;+    'electron': Linter.LegacyConfig;+    'typescript': Linter.LegacyConfig;+  };+  flatConfigs: {+    'recommended': Linter.FlatConfig;+    'errors': Linter.FlatConfig;+    'warnings': Linter.FlatConfig;+    'stage-0': Linter.FlatConfig;+    'react': Linter.FlatConfig;+    'react-native': Linter.FlatConfig;+    'electron': Linter.FlatConfig;+    'typescript': Linter.FlatConfig;+  };+  rules: {+    [key: string]: Rule.RuleModule;+  };+};++export = plugin;
lib/index.js +6 lines
--- +++ @@ -47,2 +47,3 @@   'no-empty-named-blocks': require('./rules/no-empty-named-blocks'),+  'enforce-node-protocol-usage': require('./rules/enforce-node-protocol-usage'), @@ -97,6 +98,6 @@   // useful stuff for folks using various environments-  react: require('../config/flat/react'),-  'react-native': configs['react-native'],-  electron: configs.electron,-  typescript: configs.typescript };-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJydWxlcyIsInJlcXVpcmUiLCJuYW1lZCIsIm5hbWVzcGFjZSIsImV4dGVuc2lvbnMiLCJmaXJzdCIsIm9yZGVyIiwidW5hbWJpZ3VvdXMiLCJjb25maWdzIiwicmVjb21tZW5kZWQiLCJlcnJvcnMiLCJ3YXJuaW5ncyIsInJlYWN0IiwiZWxlY3Ryb24iLCJ0eXBlc2NyaXB0IiwiaW1wb3J0UGx1Z2luIiwibWV0YSIsIm5hbWUiLCJ2ZXJzaW9uIiwiY3JlYXRlRmxhdENvbmZpZyIsImJhc2VDb25maWciLCJjb25maWdOYW1lIiwicGx1Z2lucyIsImZsYXRDb25maWdzIl0sIm1hcHBpbmdzIjoiNklBQUE7O0FBRU8sSUFBTUEsd0JBQVE7QUFDbkIsbUJBQWlCQyxRQUFRLHVCQUFSLENBREU7QUFFbkJDLFNBQU9ELFFBQVEsZUFBUixDQUZZO0FBR25CLGFBQVNBLFFBQVEsaUJBQVIsQ0FIVTtBQUluQkUsYUFBV0YsUUFBUSxtQkFBUixDQUpRO0FBS25CLGtCQUFnQkEsUUFBUSxzQkFBUixDQUxHO0FBTW5CLFlBQVFBLFFBQVEsZ0JBQVIsQ0FOVztBQU9uQix3QkFBc0JBLFFBQVEsNEJBQVIsQ0FQSDtBQVFuQkcsY0FBWUgsUUFBUSxvQkFBUixDQVJPO0FBU25CLHlCQUF1QkEsUUFBUSw2QkFBUixDQVRKO0FBVW5CLHlCQUF1QkEsUUFBUSw2QkFBUixDQVZKO0FBV25CLG1CQUFpQkEsUUFBUSx1QkFBUixDQVhFO0FBWW5CLDBCQUF3QkEsUUFBUSw4QkFBUixDQVpMO0FBYW5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQWJYO0FBY25CLHFDQUFtQ0EsUUFBUSx5Q0FBUixDQWRoQjs7QUFnQm5CLG9CQUFrQkEsUUFBUSx3QkFBUixDQWhCQztBQWlCbkIsY0FBWUEsUUFBUSxrQkFBUixDQWpCTztBQWtCbkIsc0JBQW9CQSxRQUFRLDBCQUFSLENBbEJEO0FBbUJuQix5QkFBdUJBLFFBQVEsNkJBQVIsQ0FuQko7QUFvQm5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQXBCWDtBQXFCbkIsaUNBQStCQSxRQUFRLHFDQUFSLENBckJaO0FBc0JuQix1QkFBcUJBLFFBQVEsMkJBQVIsQ0F0QkY7O0FBd0JuQixpQkFBZUEsUUFBUSxxQkFBUixDQXhCSTtBQXlCbkIsWUFBVUEsUUFBUSxnQkFBUixDQXpCUztBQTBCbkIsbUJBQWlCQSxRQUFRLHVCQUFSLENBMUJFO0FBMkJuQkksU0FBT0osUUFBUSxlQUFSLENBM0JZO0FBNEJuQixzQkFBb0JBLFFBQVEsMEJBQVIsQ0E1QkQ7QUE2Qm5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQTdCWDtBQThCbkIsc0JBQW9CQSxRQUFRLDBCQUFSLENBOUJEO0FBK0JuQix1QkFBcUJBLFFBQVEsMkJBQVIsQ0EvQkY7QUFnQ25CLDhCQUE0QkEsUUFBUSxrQ0FBUixDQWhDVDtBQWlDbkJLLFNBQU9MLFFBQVEsZUFBUixDQWpDWTtBQWtDbkIsMEJBQXdCQSxRQUFRLDhCQUFSLENBbENMO0FBbUNuQiwyQkFBeUJBLFFBQVEsK0JBQVIsQ0FuQ047QUFvQ25CLHVCQUFxQkEsUUFBUSwyQkFBUixDQXBDRjtBQXFDbkIscUJBQW1CQSxRQUFRLHlCQUFSLENBckNBO0FBc0NuQix3QkFBc0JBLFFBQVEsNEJBQVIsQ0F0Q0g7QUF1Q25CTSxlQUFhTixRQUFRLHFCQUFSLENBdkNNO0FBd0NuQiwwQkFBd0JBLFFBQVEsOEJBQVIsQ0F4Q0w7QUF5Q25CLDhCQUE0QkEsUUFBUSxrQ0FBUixDQXpDVDtBQTBDbkIsOEJBQTRCQSxRQUFRLGtDQUFSLENBMUNUO0FBMkNuQiw4QkFBNEJBLFFBQVEsa0NBQVIsQ0EzQ1Q7QUE0Q25CLDJCQUF5QkEsUUFBUSwrQkFBUixDQTVDTjs7QUE4Q25CO0FBQ0Esa0JBQWdCQSxRQUFRLHNCQUFSLENBL0NHOztBQWlEbkI7QUFDQSxtQkFBaUJBLFFBQVEsdUJBQVIsQ0FsREU7O0FBb0RuQjtBQUNBLG1CQUFpQkEsUUFBUSx1QkFBUixDQXJERSxFQUFkOzs7QUF3REEsSUFBTU8sNEJBQVU7QUFDckJDLGVBQWFSLFFBQVEsdUJBQVIsQ0FEUTs7QUFHckJTLFVBQVFULFFBQVEsa0JBQVIsQ0FIYTtBQUlyQlUsWUFBVVYsUUFBUSxvQkFBUixDQUpXOztBQU1yQjtBQUNBLGFBQVdBLFFBQVEsbUJBQVIsQ0FQVTs7QUFTckI7QUFDQVcsU0FBT1gsUUFBUSxpQkFBUixDQVZjO0FBV3JCLGtCQUFnQkEsUUFBUSx3QkFBUixDQVhLO0FBWXJCWSxZQUFVWixRQUFRLG9CQUFSLENBWlc7QUFhckJhLGNBQVliLFFBQVEsc0JBQVIsQ0FiUyxFQUFoQjs7O0FBZ0JQO0FBQ0EsSUFBTWMsZUFBZTtBQUNuQkMsUUFBTSxFQUFFQyxtQkFBRixFQUFRQyx5QkFBUixFQURhO0FBRW5CbEIsY0FGbUIsRUFBckI7OztBQUtBO0FBQ0EsSUFBTW1CLG1CQUFtQixTQUFuQkEsZ0JBQW1CLENBQUNDLFVBQUQsRUFBYUMsVUFBYjtBQUNwQkQsWUFEb0I7QUFFdkJILDZCQUFnQkksVUFBaEIsQ0FGdUI7QUFHdkJDLGFBQVMsRUFBRSxVQUFRUCxZQUFWLEVBSGMsS0FBekI7OztBQU1PLElBQU1RLG9DQUFjO0FBQ3pCZCxlQUFhVTtBQUNYbEIsVUFBUSw0QkFBUixDQURXO0FBRVgsZUFGVyxDQURZOzs7QUFNekJTLFVBQVFTLGlCQUFpQmxCLFFBQVEsdUJBQVIsQ0FBakIsRUFBbUQsUUFBbkQsQ0FOaUI7QUFPekJVLFlBQVVRLGlCQUFpQmxCLFFBQVEseUJBQVIsQ0FBakIsRUFBcUQsVUFBckQsQ0FQZTs7QUFTekI7QUFDQVcsU0FBT1gsUUFBUSxzQkFBUixDQVZrQjtBQVd6QixrQkFBZ0JPLFFBQVEsY0FBUixDQVhTO0FBWXpCSyxZQUFVTCxRQUFRSyxRQVpPO0FBYXpCQyxjQUFZTixRQUFRTSxVQWJLLEVBQXBCIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbmFtZSwgdmVyc2lvbiB9IGZyb20gJy4uL3BhY2thZ2UuanNvbic7XG5cbmV4cG9ydCBjb25zdCBydWxlcyA9IHtcbiAgJ25vLXVucmVzb2x2ZWQnOiByZXF1aXJlKCcuL3J1bGVzL25vLXVucmVzb2x2ZWQnKSxcbiAgbmFtZWQ6IHJlcXVpcmUoJy4vcnVsZXMvbmFtZWQnKSxcbiAgZGVmYXVsdDogcmVxdWlyZSgnLi9ydWxlcy9kZWZhdWx0JyksXG4gIG5hbWVzcGFjZTogcmVxdWlyZSgnLi9ydWxlcy9uYW1lc3BhY2UnKSxcbiAgJ25vLW5hbWVzcGFjZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tbmFtZXNwYWNlJyksXG4gIGV4cG9ydDogcmVxdWlyZSgnLi9ydWxlcy9leHBvcnQnKSxcbiAgJ25vLW11dGFibGUtZXhwb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tbXV0YWJsZS1leHBvcnRzJyksXG4gIGV4dGVuc2lvbnM6IHJlcXVpcmUoJy4vcnVsZXMvZXh0ZW5zaW9ucycpLFxuICAnbm8tcmVzdHJpY3RlZC1wYXRocyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tcmVzdHJpY3RlZC1wYXRocycpLFxuICAnbm8taW50ZXJuYWwtbW9kdWxlcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8taW50ZXJuYWwtbW9kdWxlcycpLFxuICAnZ3JvdXAtZXhwb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvZ3JvdXAtZXhwb3J0cycpLFxuICAnbm8tcmVsYXRpdmUtcGFja2FnZXMnOiByZXF1aXJlKCcuL3J1bGVzL25vLXJlbGF0aXZlLXBhY2thZ2VzJyksXG4gICduby1yZWxhdGl2ZS1wYXJlbnQtaW1wb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tcmVsYXRpdmUtcGFyZW50LWltcG9ydHMnKSxcbiAgJ2NvbnNpc3RlbnQtdHlwZS1zcGVjaWZpZXItc3R5bGUnOiByZXF1aXJlKCcuL3J1bGVzL2NvbnNpc3RlbnQtdHlwZS1zcGVjaWZpZXItc3R5bGUnKSxcblxuICAnbm8tc2VsZi1pbXBvcnQnOiByZXF1aXJlKCcuL3J1bGVzL25vLXNlbGYtaW1wb3J0JyksXG4gICduby1jeWNsZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tY3ljbGUnKSxcbiAgJ25vLW5hbWVkLWRlZmF1bHQnOiByZXF1aXJlKCcuL3J1bGVzL25vLW5hbWVkLWRlZmF1bHQnKSxcbiAgJ25vLW5hbWVkLWFzLWRlZmF1bHQnOiByZXF1aXJlKCcuL3J1bGVzL25vLW5hbWVkLWFzLWRlZmF1bHQnKSxcbiAgJ25vLW5hbWVkLWFzLWRlZmF1bHQtbWVtYmVyJzogcmVxdWlyZSgnLi9ydWxlcy9uby1uYW1lZC1hcy1kZWZhdWx0LW1lbWJlcicpLFxuICAnbm8tYW5vbnltb3VzLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1hbm9ueW1vdXMtZGVmYXVsdC1leHBvcnQnKSxcbiAgJ25vLXVudXNlZC1tb2R1bGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby11bnVzZWQtbW9kdWxlcycpLFxuXG4gICduby1jb21tb25qcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tY29tbW9uanMnKSxcbiAgJ25vLWFtZCc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tYW1kJyksXG4gICduby1kdXBsaWNhdGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1kdXBsaWNhdGVzJyksXG4gIGZpcnN0OiByZXF1aXJlKCcuL3J1bGVzL2ZpcnN0JyksXG4gICdtYXgtZGVwZW5kZW5jaWVzJzogcmVxdWlyZSgnLi9ydWxlcy9tYXgtZGVwZW5kZW5jaWVzJyksXG4gICduby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMnKSxcbiAgJ25vLWFic29sdXRlLXBhdGgnOiByZXF1aXJlKCcuL3J1bGVzL25vLWFic29sdXRlLXBhdGgnKSxcbiAgJ25vLW5vZGVqcy1tb2R1bGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1ub2RlanMtbW9kdWxlcycpLFxuICAnbm8td2VicGFjay1sb2FkZXItc3ludGF4JzogcmVxdWlyZSgnLi9ydWxlcy9uby13ZWJwYWNrLWxvYWRlci1zeW50YXgnKSxcbiAgb3JkZXI6IHJlcXVpcmUoJy4vcnVsZXMvb3JkZXInKSxcbiAgJ25ld2xpbmUtYWZ0ZXItaW1wb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uZXdsaW5lLWFmdGVyLWltcG9ydCcpLFxuICAncHJlZmVyLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9wcmVmZXItZGVmYXVsdC1leHBvcnQnKSxcbiAgJ25vLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1kZWZhdWx0LWV4cG9ydCcpLFxuICAnbm8tbmFtZWQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1uYW1lZC1leHBvcnQnKSxcbiAgJ25vLWR5bmFtaWMtcmVxdWlyZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZHluYW1pYy1yZXF1aXJlJyksXG4gIHVuYW1iaWd1b3VzOiByZXF1aXJlKCcuL3J1bGVzL3VuYW1iaWd1b3VzJyksXG4gICduby11bmFzc2lnbmVkLWltcG9ydCc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tdW5hc3NpZ25lZC1pbXBvcnQnKSxcbiAgJ25vLXVzZWxlc3MtcGF0aC1zZWdtZW50cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tdXNlbGVzcy1wYXRoLXNlZ21lbnRzJyksXG4gICdkeW5hbWljLWltcG9ydC1jaHVua25hbWUnOiByZXF1aXJlKCcuL3J1bGVzL2R5bmFtaWMtaW1wb3J0LWNodW5rbmFtZScpLFxuICAnbm8taW1wb3J0LW1vZHVsZS1leHBvcnRzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1pbXBvcnQtbW9kdWxlLWV4cG9ydHMnKSxcbiAgJ25vLWVtcHR5LW5hbWVkLWJsb2Nrcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZW1wdHktbmFtZWQtYmxvY2tzJyksXG5cbiAgLy8gZXhwb3J0XG4gICdleHBvcnRzLWxhc3QnOiByZXF1aXJlKCcuL3J1bGVzL2V4cG9ydHMtbGFzdCcpLFxuXG4gIC8vIG1ldGFkYXRhLWJhc2VkXG4gICduby1kZXByZWNhdGVkJzogcmVxdWlyZSgnLi9ydWxlcy9uby1kZXByZWNhdGVkJyksXG5cbiAgLy8gZGVwcmVjYXRlZCBhbGlhc2VzIHRvIHJ1bGVzXG4gICdpbXBvcnRzLWZpcnN0JzogcmVxdWlyZSgnLi9ydWxlcy9pbXBvcnRzLWZpcnN0JyksXG59O1xuXG5leHBvcnQgY29uc3QgY29uZmlncyA9IHtcbiAgcmVjb21tZW5kZWQ6IHJlcXVpcmUoJy4uL2NvbmZpZy9yZWNvbW1lbmRlZCcpLFxuXG4gIGVycm9yczogcmVxdWlyZSgnLi4vY29uZmlnL2Vycm9ycycpLFxuICB3YXJuaW5nczogcmVxdWlyZSgnLi4vY29uZmlnL3dhcm5pbmdzJyksXG5cbiAgLy8gc2hoaGguLi4gd29yayBpbiBwcm9ncmVzcyBcInNlY3JldFwiIHJ1bGVzXG4gICdzdGFnZS0wJzogcmVxdWlyZSgnLi4vY29uZmlnL3N0YWdlLTAnKSxcblxuICAvLyB1c2VmdWwgc3R1ZmYgZm9yIGZvbGtzIHVzaW5nIHZhcmlvdXMgZW52aXJvbm1lbnRzXG4gIHJlYWN0OiByZXF1aXJlKCcuLi9jb25maWcvcmVhY3QnKSxcbiAgJ3JlYWN0LW5hdGl2ZSc6IHJlcXVpcmUoJy4uL2NvbmZpZy9yZWFjdC1uYXRpdmUnKSxcbiAgZWxlY3Ryb246IHJlcXVpcmUoJy4uL2NvbmZpZy9lbGVjdHJvbicpLFxuICB0eXBlc2NyaXB0OiByZXF1aXJlKCcuLi9jb25maWcvdHlwZXNjcmlwdCcpLFxufTtcblxuLy8gQmFzZSBQbHVnaW4gT2JqZWN0XG5jb25zdCBpbXBvcnRQbHVnaW4gPSB7XG4gIG1ldGE6IHsgbmFtZSwgdmVyc2lvbiB9LFxuICBydWxlcyxcbn07XG5cbi8vIENyZWF0ZSBmbGF0IGNvbmZpZ3MgKE9ubHkgb25lcyB0aGF0IGRlY2xhcmUgcGx1Z2lucyBhbmQgcGFyc2VyIG9wdGlvbnMgbmVlZCB0byBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgbGVnYWN5IGNvbmZpZylcbmNvbnN0IGNyZWF0ZUZsYXRDb25maWcgPSAoYmFzZUNvbmZpZywgY29uZmlnTmFtZSkgPT4gKHtcbiAgLi4uYmFzZUNvbmZpZyxcbiAgbmFtZTogYGltcG9ydC8ke2NvbmZpZ05hbWV9YCxcbiAgcGx1Z2luczogeyBpbXBvcnQ6IGltcG9ydFBsdWdpbiB9LFxufSk7XG5cbmV4cG9ydCBjb25zdCBmbGF0Q29uZmlncyA9IHtcbiAgcmVjb21tZW5kZWQ6IGNyZWF0ZUZsYXRDb25maWcoXG4gICAgcmVxdWlyZSgnLi4vY29uZmlnL2ZsYXQvcmVjb21tZW5kZWQnKSxcbiAgICAncmVjb21tZW5kZWQnLFxuICApLFxuXG4gIGVycm9yczogY3JlYXRlRmxhdENvbmZpZyhyZXF1aXJlKCcuLi9jb25maWcvZmxhdC9lcnJvcnMnKSwgJ2Vycm9ycycpLFxuICB3YXJuaW5nczogY3JlYXRlRmxhdENvbmZpZyhyZXF1aXJlKCcuLi9jb25maWcvZmxhdC93YXJuaW5ncycpLCAnd2FybmluZ3MnKSxcblxuICAvLyB1c2VmdWwgc3R1ZmYgZm9yIGZvbGtzIHVzaW5nIHZhcmlvdXMgZW52aXJvbm1lbnRzXG4gIHJlYWN0OiByZXF1aXJlKCcuLi9jb25maWcvZmxhdC9yZWFjdCcpLFxuICAncmVhY3QtbmF0aXZlJzogY29uZmlnc1sncmVhY3QtbmF0aXZlJ10sXG4gIGVsZWN0cm9uOiBjb25maWdzLmVsZWN0cm9uLFxuICB0eXBlc2NyaXB0OiBjb25maWdzLnR5cGVzY3JpcHQsXG59O1xuIl19+  react: createFlatConfig(require('../config/flat/react'), 'react'),+  'react-native': createFlatConfig(configs['react-native'], 'react-native'),+  electron: createFlatConfig(configs.electron, 'electron'),+  typescript: createFlatConfig(configs.typescript, 'typescript') };+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJydWxlcyIsInJlcXVpcmUiLCJuYW1lZCIsIm5hbWVzcGFjZSIsImV4dGVuc2lvbnMiLCJmaXJzdCIsIm9yZGVyIiwidW5hbWJpZ3VvdXMiLCJjb25maWdzIiwicmVjb21tZW5kZWQiLCJlcnJvcnMiLCJ3YXJuaW5ncyIsInJlYWN0IiwiZWxlY3Ryb24iLCJ0eXBlc2NyaXB0IiwiaW1wb3J0UGx1Z2luIiwibWV0YSIsIm5hbWUiLCJ2ZXJzaW9uIiwiY3JlYXRlRmxhdENvbmZpZyIsImJhc2VDb25maWciLCJjb25maWdOYW1lIiwicGx1Z2lucyIsImZsYXRDb25maWdzIl0sIm1hcHBpbmdzIjoiNklBQUE7O0FBRU8sSUFBTUEsd0JBQVE7QUFDbkIsbUJBQWlCQyxRQUFRLHVCQUFSLENBREU7QUFFbkJDLFNBQU9ELFFBQVEsZUFBUixDQUZZO0FBR25CLGFBQVNBLFFBQVEsaUJBQVIsQ0FIVTtBQUluQkUsYUFBV0YsUUFBUSxtQkFBUixDQUpRO0FBS25CLGtCQUFnQkEsUUFBUSxzQkFBUixDQUxHO0FBTW5CLFlBQVFBLFFBQVEsZ0JBQVIsQ0FOVztBQU9uQix3QkFBc0JBLFFBQVEsNEJBQVIsQ0FQSDtBQVFuQkcsY0FBWUgsUUFBUSxvQkFBUixDQVJPO0FBU25CLHlCQUF1QkEsUUFBUSw2QkFBUixDQVRKO0FBVW5CLHlCQUF1QkEsUUFBUSw2QkFBUixDQVZKO0FBV25CLG1CQUFpQkEsUUFBUSx1QkFBUixDQVhFO0FBWW5CLDBCQUF3QkEsUUFBUSw4QkFBUixDQVpMO0FBYW5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQWJYO0FBY25CLHFDQUFtQ0EsUUFBUSx5Q0FBUixDQWRoQjs7QUFnQm5CLG9CQUFrQkEsUUFBUSx3QkFBUixDQWhCQztBQWlCbkIsY0FBWUEsUUFBUSxrQkFBUixDQWpCTztBQWtCbkIsc0JBQW9CQSxRQUFRLDBCQUFSLENBbEJEO0FBbUJuQix5QkFBdUJBLFFBQVEsNkJBQVIsQ0FuQko7QUFvQm5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQXBCWDtBQXFCbkIsaUNBQStCQSxRQUFRLHFDQUFSLENBckJaO0FBc0JuQix1QkFBcUJBLFFBQVEsMkJBQVIsQ0F0QkY7O0FBd0JuQixpQkFBZUEsUUFBUSxxQkFBUixDQXhCSTtBQXlCbkIsWUFBVUEsUUFBUSxnQkFBUixDQXpCUztBQTBCbkIsbUJBQWlCQSxRQUFRLHVCQUFSLENBMUJFO0FBMkJuQkksU0FBT0osUUFBUSxlQUFSLENBM0JZO0FBNEJuQixzQkFBb0JBLFFBQVEsMEJBQVIsQ0E1QkQ7QUE2Qm5CLGdDQUE4QkEsUUFBUSxvQ0FBUixDQTdCWDtBQThCbkIsc0JBQW9CQSxRQUFRLDBCQUFSLENBOUJEO0FBK0JuQix1QkFBcUJBLFFBQVEsMkJBQVIsQ0EvQkY7QUFnQ25CLDhCQUE0QkEsUUFBUSxrQ0FBUixDQWhDVDtBQWlDbkJLLFNBQU9MLFFBQVEsZUFBUixDQWpDWTtBQWtDbkIsMEJBQXdCQSxRQUFRLDhCQUFSLENBbENMO0FBbUNuQiwyQkFBeUJBLFFBQVEsK0JBQVIsQ0FuQ047QUFvQ25CLHVCQUFxQkEsUUFBUSwyQkFBUixDQXBDRjtBQXFDbkIscUJBQW1CQSxRQUFRLHlCQUFSLENBckNBO0FBc0NuQix3QkFBc0JBLFFBQVEsNEJBQVIsQ0F0Q0g7QUF1Q25CTSxlQUFhTixRQUFRLHFCQUFSLENBdkNNO0FBd0NuQiwwQkFBd0JBLFFBQVEsOEJBQVIsQ0F4Q0w7QUF5Q25CLDhCQUE0QkEsUUFBUSxrQ0FBUixDQXpDVDtBQTBDbkIsOEJBQTRCQSxRQUFRLGtDQUFSLENBMUNUO0FBMkNuQiw4QkFBNEJBLFFBQVEsa0NBQVIsQ0EzQ1Q7QUE0Q25CLDJCQUF5QkEsUUFBUSwrQkFBUixDQTVDTjtBQTZDbkIsaUNBQStCQSxRQUFRLHFDQUFSLENBN0NaOztBQStDbkI7QUFDQSxrQkFBZ0JBLFFBQVEsc0JBQVIsQ0FoREc7O0FBa0RuQjtBQUNBLG1CQUFpQkEsUUFBUSx1QkFBUixDQW5ERTs7QUFxRG5CO0FBQ0EsbUJBQWlCQSxRQUFRLHVCQUFSLENBdERFLEVBQWQ7OztBQXlEQSxJQUFNTyw0QkFBVTtBQUNyQkMsZUFBYVIsUUFBUSx1QkFBUixDQURROztBQUdyQlMsVUFBUVQsUUFBUSxrQkFBUixDQUhhO0FBSXJCVSxZQUFVVixRQUFRLG9CQUFSLENBSlc7O0FBTXJCO0FBQ0EsYUFBV0EsUUFBUSxtQkFBUixDQVBVOztBQVNyQjtBQUNBVyxTQUFPWCxRQUFRLGlCQUFSLENBVmM7QUFXckIsa0JBQWdCQSxRQUFRLHdCQUFSLENBWEs7QUFZckJZLFlBQVVaLFFBQVEsb0JBQVIsQ0FaVztBQWFyQmEsY0FBWWIsUUFBUSxzQkFBUixDQWJTLEVBQWhCOzs7QUFnQlA7QUFDQSxJQUFNYyxlQUFlO0FBQ25CQyxRQUFNLEVBQUVDLG1CQUFGLEVBQVFDLHlCQUFSLEVBRGE7QUFFbkJsQixjQUZtQixFQUFyQjs7O0FBS0E7QUFDQSxJQUFNbUIsbUJBQW1CLFNBQW5CQSxnQkFBbUIsQ0FBQ0MsVUFBRCxFQUFhQyxVQUFiO0FBQ3BCRCxZQURvQjtBQUV2QkgsNkJBQWdCSSxVQUFoQixDQUZ1QjtBQUd2QkMsYUFBUyxFQUFFLFVBQVFQLFlBQVYsRUFIYyxLQUF6Qjs7O0FBTU8sSUFBTVEsb0NBQWM7QUFDekJkLGVBQWFVO0FBQ1hsQixVQUFRLDRCQUFSLENBRFc7QUFFWCxlQUZXLENBRFk7OztBQU16QlMsVUFBUVMsaUJBQWlCbEIsUUFBUSx1QkFBUixDQUFqQixFQUFtRCxRQUFuRCxDQU5pQjtBQU96QlUsWUFBVVEsaUJBQWlCbEIsUUFBUSx5QkFBUixDQUFqQixFQUFxRCxVQUFyRCxDQVBlOztBQVN6QjtBQUNBVyxTQUFPTyxpQkFBaUJsQixRQUFRLHNCQUFSLENBQWpCLEVBQWtELE9BQWxELENBVmtCO0FBV3pCLGtCQUFnQmtCLGlCQUFpQlgsUUFBUSxjQUFSLENBQWpCLEVBQTBDLGNBQTFDLENBWFM7QUFZekJLLFlBQVVNLGlCQUFpQlgsUUFBUUssUUFBekIsRUFBbUMsVUFBbkMsQ0FaZTtBQWF6QkMsY0FBWUssaUJBQWlCWCxRQUFRTSxVQUF6QixFQUFxQyxZQUFyQyxDQWJhLEVBQXBCIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbmFtZSwgdmVyc2lvbiB9IGZyb20gJy4uL3BhY2thZ2UuanNvbic7XG5cbmV4cG9ydCBjb25zdCBydWxlcyA9IHtcbiAgJ25vLXVucmVzb2x2ZWQnOiByZXF1aXJlKCcuL3J1bGVzL25vLXVucmVzb2x2ZWQnKSxcbiAgbmFtZWQ6IHJlcXVpcmUoJy4vcnVsZXMvbmFtZWQnKSxcbiAgZGVmYXVsdDogcmVxdWlyZSgnLi9ydWxlcy9kZWZhdWx0JyksXG4gIG5hbWVzcGFjZTogcmVxdWlyZSgnLi9ydWxlcy9uYW1lc3BhY2UnKSxcbiAgJ25vLW5hbWVzcGFjZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tbmFtZXNwYWNlJyksXG4gIGV4cG9ydDogcmVxdWlyZSgnLi9ydWxlcy9leHBvcnQnKSxcbiAgJ25vLW11dGFibGUtZXhwb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tbXV0YWJsZS1leHBvcnRzJyksXG4gIGV4dGVuc2lvbnM6IHJlcXVpcmUoJy4vcnVsZXMvZXh0ZW5zaW9ucycpLFxuICAnbm8tcmVzdHJpY3RlZC1wYXRocyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tcmVzdHJpY3RlZC1wYXRocycpLFxuICAnbm8taW50ZXJuYWwtbW9kdWxlcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8taW50ZXJuYWwtbW9kdWxlcycpLFxuICAnZ3JvdXAtZXhwb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvZ3JvdXAtZXhwb3J0cycpLFxuICAnbm8tcmVsYXRpdmUtcGFja2FnZXMnOiByZXF1aXJlKCcuL3J1bGVzL25vLXJlbGF0aXZlLXBhY2thZ2VzJyksXG4gICduby1yZWxhdGl2ZS1wYXJlbnQtaW1wb3J0cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tcmVsYXRpdmUtcGFyZW50LWltcG9ydHMnKSxcbiAgJ2NvbnNpc3RlbnQtdHlwZS1zcGVjaWZpZXItc3R5bGUnOiByZXF1aXJlKCcuL3J1bGVzL2NvbnNpc3RlbnQtdHlwZS1zcGVjaWZpZXItc3R5bGUnKSxcblxuICAnbm8tc2VsZi1pbXBvcnQnOiByZXF1aXJlKCcuL3J1bGVzL25vLXNlbGYtaW1wb3J0JyksXG4gICduby1jeWNsZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tY3ljbGUnKSxcbiAgJ25vLW5hbWVkLWRlZmF1bHQnOiByZXF1aXJlKCcuL3J1bGVzL25vLW5hbWVkLWRlZmF1bHQnKSxcbiAgJ25vLW5hbWVkLWFzLWRlZmF1bHQnOiByZXF1aXJlKCcuL3J1bGVzL25vLW5hbWVkLWFzLWRlZmF1bHQnKSxcbiAgJ25vLW5hbWVkLWFzLWRlZmF1bHQtbWVtYmVyJzogcmVxdWlyZSgnLi9ydWxlcy9uby1uYW1lZC1hcy1kZWZhdWx0LW1lbWJlcicpLFxuICAnbm8tYW5vbnltb3VzLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1hbm9ueW1vdXMtZGVmYXVsdC1leHBvcnQnKSxcbiAgJ25vLXVudXNlZC1tb2R1bGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby11bnVzZWQtbW9kdWxlcycpLFxuXG4gICduby1jb21tb25qcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tY29tbW9uanMnKSxcbiAgJ25vLWFtZCc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tYW1kJyksXG4gICduby1kdXBsaWNhdGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1kdXBsaWNhdGVzJyksXG4gIGZpcnN0OiByZXF1aXJlKCcuL3J1bGVzL2ZpcnN0JyksXG4gICdtYXgtZGVwZW5kZW5jaWVzJzogcmVxdWlyZSgnLi9ydWxlcy9tYXgtZGVwZW5kZW5jaWVzJyksXG4gICduby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMnKSxcbiAgJ25vLWFic29sdXRlLXBhdGgnOiByZXF1aXJlKCcuL3J1bGVzL25vLWFic29sdXRlLXBhdGgnKSxcbiAgJ25vLW5vZGVqcy1tb2R1bGVzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1ub2RlanMtbW9kdWxlcycpLFxuICAnbm8td2VicGFjay1sb2FkZXItc3ludGF4JzogcmVxdWlyZSgnLi9ydWxlcy9uby13ZWJwYWNrLWxvYWRlci1zeW50YXgnKSxcbiAgb3JkZXI6IHJlcXVpcmUoJy4vcnVsZXMvb3JkZXInKSxcbiAgJ25ld2xpbmUtYWZ0ZXItaW1wb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uZXdsaW5lLWFmdGVyLWltcG9ydCcpLFxuICAncHJlZmVyLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9wcmVmZXItZGVmYXVsdC1leHBvcnQnKSxcbiAgJ25vLWRlZmF1bHQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1kZWZhdWx0LWV4cG9ydCcpLFxuICAnbm8tbmFtZWQtZXhwb3J0JzogcmVxdWlyZSgnLi9ydWxlcy9uby1uYW1lZC1leHBvcnQnKSxcbiAgJ25vLWR5bmFtaWMtcmVxdWlyZSc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZHluYW1pYy1yZXF1aXJlJyksXG4gIHVuYW1iaWd1b3VzOiByZXF1aXJlKCcuL3J1bGVzL3VuYW1iaWd1b3VzJyksXG4gICduby11bmFzc2lnbmVkLWltcG9ydCc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tdW5hc3NpZ25lZC1pbXBvcnQnKSxcbiAgJ25vLXVzZWxlc3MtcGF0aC1zZWdtZW50cyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tdXNlbGVzcy1wYXRoLXNlZ21lbnRzJyksXG4gICdkeW5hbWljLWltcG9ydC1jaHVua25hbWUnOiByZXF1aXJlKCcuL3J1bGVzL2R5bmFtaWMtaW1wb3J0LWNodW5rbmFtZScpLFxuICAnbm8taW1wb3J0LW1vZHVsZS1leHBvcnRzJzogcmVxdWlyZSgnLi9ydWxlcy9uby1pbXBvcnQtbW9kdWxlLWV4cG9ydHMnKSxcbiAgJ25vLWVtcHR5LW5hbWVkLWJsb2Nrcyc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZW1wdHktbmFtZWQtYmxvY2tzJyksXG4gICdlbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UnOiByZXF1aXJlKCcuL3J1bGVzL2VuZm9yY2Utbm9kZS1wcm90b2NvbC11c2FnZScpLFxuXG4gIC8vIGV4cG9ydFxuICAnZXhwb3J0cy1sYXN0JzogcmVxdWlyZSgnLi9ydWxlcy9leHBvcnRzLWxhc3QnKSxcblxuICAvLyBtZXRhZGF0YS1iYXNlZFxuICAnbm8tZGVwcmVjYXRlZCc6IHJlcXVpcmUoJy4vcnVsZXMvbm8tZGVwcmVjYXRlZCcpLFxuXG4gIC8vIGRlcHJlY2F0ZWQgYWxpYXNlcyB0byBydWxlc1xuICAnaW1wb3J0cy1maXJzdCc6IHJlcXVpcmUoJy4vcnVsZXMvaW1wb3J0cy1maXJzdCcpLFxufTtcblxuZXhwb3J0IGNvbnN0IGNvbmZpZ3MgPSB7XG4gIHJlY29tbWVuZGVkOiByZXF1aXJlKCcuLi9jb25maWcvcmVjb21tZW5kZWQnKSxcblxuICBlcnJvcnM6IHJlcXVpcmUoJy4uL2NvbmZpZy9lcnJvcnMnKSxcbiAgd2FybmluZ3M6IHJlcXVpcmUoJy4uL2NvbmZpZy93YXJuaW5ncycpLFxuXG4gIC8vIHNoaGhoLi4uIHdvcmsgaW4gcHJvZ3Jlc3MgXCJzZWNyZXRcIiBydWxlc1xuICAnc3RhZ2UtMCc6IHJlcXVpcmUoJy4uL2NvbmZpZy9zdGFnZS0wJyksXG5cbiAgLy8gdXNlZnVsIHN0dWZmIGZvciBmb2xrcyB1c2luZyB2YXJpb3VzIGVudmlyb25tZW50c1xuICByZWFjdDogcmVxdWlyZSgnLi4vY29uZmlnL3JlYWN0JyksXG4gICdyZWFjdC1uYXRpdmUnOiByZXF1aXJlKCcuLi9jb25maWcvcmVhY3QtbmF0aXZlJyksXG4gIGVsZWN0cm9uOiByZXF1aXJlKCcuLi9jb25maWcvZWxlY3Ryb24nKSxcbiAgdHlwZXNjcmlwdDogcmVxdWlyZSgnLi4vY29uZmlnL3R5cGVzY3JpcHQnKSxcbn07XG5cbi8vIEJhc2UgUGx1Z2luIE9iamVjdFxuY29uc3QgaW1wb3J0UGx1Z2luID0ge1xuICBtZXRhOiB7IG5hbWUsIHZlcnNpb24gfSxcbiAgcnVsZXMsXG59O1xuXG4vLyBDcmVhdGUgZmxhdCBjb25maWdzIChPbmx5IG9uZXMgdGhhdCBkZWNsYXJlIHBsdWdpbnMgYW5kIHBhcnNlciBvcHRpb25zIG5lZWQgdG8gYmUgZGlmZmVyZW50IGZyb20gdGhlIGxlZ2FjeSBjb25maWcpXG5jb25zdCBjcmVhdGVGbGF0Q29uZmlnID0gKGJhc2VDb25maWcsIGNvbmZpZ05hbWUpID0+ICh7XG4gIC4uLmJhc2VDb25maWcsXG4gIG5hbWU6IGBpbXBvcnQvJHtjb25maWdOYW1lfWAsXG4gIHBsdWdpbnM6IHsgaW1wb3J0OiBpbXBvcnRQbHVnaW4gfSxcbn0pO1xuXG5leHBvcnQgY29uc3QgZmxhdENvbmZpZ3MgPSB7XG4gIHJlY29tbWVuZGVkOiBjcmVhdGVGbGF0Q29uZmlnKFxuICAgIHJlcXVpcmUoJy4uL2NvbmZpZy9mbGF0L3JlY29tbWVuZGVkJyksXG4gICAgJ3JlY29tbWVuZGVkJyxcbiAgKSxcblxuICBlcnJvcnM6IGNyZWF0ZUZsYXRDb25maWcocmVxdWlyZSgnLi4vY29uZmlnL2ZsYXQvZXJyb3JzJyksICdlcnJvcnMnKSxcbiAgd2FybmluZ3M6IGNyZWF0ZUZsYXRDb25maWcocmVxdWlyZSgnLi4vY29uZmlnL2ZsYXQvd2FybmluZ3MnKSwgJ3dhcm5pbmdzJyksXG5cbiAgLy8gdXNlZnVsIHN0dWZmIGZvciBmb2xrcyB1c2luZyB2YXJpb3VzIGVudmlyb25tZW50c1xuICByZWFjdDogY3JlYXRlRmxhdENvbmZpZyhyZXF1aXJlKCcuLi9jb25maWcvZmxhdC9yZWFjdCcpLCAncmVhY3QnKSxcbiAgJ3JlYWN0LW5hdGl2ZSc6IGNyZWF0ZUZsYXRDb25maWcoY29uZmlnc1sncmVhY3QtbmF0aXZlJ10sICdyZWFjdC1uYXRpdmUnKSxcbiAgZWxlY3Ryb246IGNyZWF0ZUZsYXRDb25maWcoY29uZmlncy5lbGVjdHJvbiwgJ2VsZWN0cm9uJyksXG4gIHR5cGVzY3JpcHQ6IGNyZWF0ZUZsYXRDb25maWcoY29uZmlncy50eXBlc2NyaXB0LCAndHlwZXNjcmlwdCcpLFxufTtcbiJdfQ==
lib/rules/enforce-node-protocol-usage.js +147 lines
--- +++ @@ -0,0 +1,147 @@+'use strict';var _messages;function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}++var isCoreModule = require('is-core-module');var _require =+require('../docsUrl'),docsUrl = _require['default'];++var DO_PREFER_MESSAGE_ID = 'requireNodeProtocol';+var NEVER_PREFER_MESSAGE_ID = 'forbidNodeProtocol';+var messages = (_messages = {}, _defineProperty(_messages,+DO_PREFER_MESSAGE_ID, 'Prefer `node:{{moduleName}}` over `{{moduleName}}`.'), _defineProperty(_messages,+NEVER_PREFER_MESSAGE_ID, 'Prefer `{{moduleName}}` over `node:{{moduleName}}`.'), _messages);+++function replaceStringLiteral(+fixer,+node,+text,+relativeRangeStart,+relativeRangeEnd)+{+  var firstCharacterIndex = node.range[0] + 1;+  var start = Number.isInteger(relativeRangeEnd) ?+  relativeRangeStart + firstCharacterIndex :+  firstCharacterIndex;+  var end = Number.isInteger(relativeRangeEnd) ?+  relativeRangeEnd + firstCharacterIndex :+  node.range[1] - 1;++  return fixer.replaceTextRange([start, end], text);+}++function isStringLiteral(node) {+  return node && node.type === 'Literal' && typeof node.value === 'string';+}++function isStaticRequireWith1Param(node) {+  return !node.optional &&+  node.callee.type === 'Identifier' &&+  node.callee.name === 'require'+  // check for only 1 argument+  && node.arguments.length === 1 &&+  node.arguments[0] &&+  isStringLiteral(node.arguments[0]);+}++function checkAndReport(src, context) {+  // TODO use src.quasis[0].value.raw+  if (!src || src.type === 'TemplateLiteral') {return;}+  var moduleName = 'value' in src ? src.value : src.name;+  if (typeof moduleName !== 'string') {console.log(src, moduleName);}var+  settings = context.settings;+  var nodeVersion = settings && settings['import/node-version'];+  if (+  typeof nodeVersion !== 'undefined' && (++  typeof nodeVersion !== 'string' ||+  !/^[0-9]+\.[0-9]+\.[0-9]+$/.test(nodeVersion)))++  {+    throw new TypeError('`import/node-version` setting must be a string in the format "10.23.45" (a semver version, with no leading zero)');+  }++  if (context.options[0] === 'never') {+    if (!moduleName.startsWith('node:')) {return;}++    var actualModuleName = moduleName.slice(5);+    if (!isCoreModule(actualModuleName, nodeVersion || undefined)) {return;}++    context.report({+      node: src,+      message: messages[NEVER_PREFER_MESSAGE_ID],+      data: { moduleName: actualModuleName },+      /** @param {import('eslint').Rule.RuleFixer} fixer */+      fix: function () {function fix(fixer) {+          return replaceStringLiteral(fixer, src, '', 0, 5);+        }return fix;}() });++  } else if (context.options[0] === 'always') {+    if (+    moduleName.startsWith('node:') ||+    !isCoreModule(moduleName, nodeVersion || undefined) ||+    !isCoreModule('node:' + String(moduleName), nodeVersion || undefined))+    {+      return;+    }++    context.report({+      node: src,+      message: messages[DO_PREFER_MESSAGE_ID],+      data: { moduleName: moduleName },+      /** @param {import('eslint').Rule.RuleFixer} fixer */+      fix: function () {function fix(fixer) {+          return replaceStringLiteral(fixer, src, 'node:', 0, 0);+        }return fix;}() });++  } else if (typeof context.options[0] === 'undefined') {+    throw new Error('Missing option');+  } else {+    throw new Error('Unexpected option: ' + String(context.options[0]));+  }+}++/** @type {import('eslint').Rule.RuleModule} */+module.exports = {+  meta: {+    type: 'suggestion',+    docs: {+      description: 'Enforce either using, or omitting, the `node:` protocol when importing Node.js builtin modules.',+      recommended: true,+      category: 'Static analysis',+      url: docsUrl('enforce-node-protocol-usage') },++    fixable: 'code',+    schema: {+      type: 'array',+      minItems: 1,+      maxItems: 1,+      items: [+      {+        'enum': ['always', 'never'] }] },++++    messages: messages },++  create: function () {function create(context) {+      return {+        CallExpression: function () {function CallExpression(node) {+            if (!isStaticRequireWith1Param(node)) {return;}++            var arg = node.arguments[0];++            return checkAndReport(arg, context);+          }return CallExpression;}(),+        ExportNamedDeclaration: function () {function ExportNamedDeclaration(node) {+            return checkAndReport(node.source, context);+          }return ExportNamedDeclaration;}(),+        ImportDeclaration: function () {function ImportDeclaration(node) {+            return checkAndReport(node.source, context);+          }return ImportDeclaration;}(),+        ImportExpression: function () {function ImportExpression(node) {+            if (!isStringLiteral(node.source)) {return;}++            return checkAndReport(node.source, context);+          }return ImportExpression;}() };++    }return create;}() };+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9lbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UuanMiXSwibmFtZXMiOlsiaXNDb3JlTW9kdWxlIiwicmVxdWlyZSIsImRvY3NVcmwiLCJET19QUkVGRVJfTUVTU0FHRV9JRCIsIk5FVkVSX1BSRUZFUl9NRVNTQUdFX0lEIiwibWVzc2FnZXMiLCJyZXBsYWNlU3RyaW5nTGl0ZXJhbCIsImZpeGVyIiwibm9kZSIsInRleHQiLCJyZWxhdGl2ZVJhbmdlU3RhcnQiLCJyZWxhdGl2ZVJhbmdlRW5kIiwiZmlyc3RDaGFyYWN0ZXJJbmRleCIsInJhbmdlIiwic3RhcnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJlbmQiLCJyZXBsYWNlVGV4dFJhbmdlIiwiaXNTdHJpbmdMaXRlcmFsIiwidHlwZSIsInZhbHVlIiwiaXNTdGF0aWNSZXF1aXJlV2l0aDFQYXJhbSIsIm9wdGlvbmFsIiwiY2FsbGVlIiwibmFtZSIsImFyZ3VtZW50cyIsImxlbmd0aCIsImNoZWNrQW5kUmVwb3J0Iiwic3JjIiwiY29udGV4dCIsIm1vZHVsZU5hbWUiLCJjb25zb2xlIiwibG9nIiwic2V0dGluZ3MiLCJub2RlVmVyc2lvbiIsInRlc3QiLCJUeXBlRXJyb3IiLCJvcHRpb25zIiwic3RhcnRzV2l0aCIsImFjdHVhbE1vZHVsZU5hbWUiLCJzbGljZSIsInVuZGVmaW5lZCIsInJlcG9ydCIsIm1lc3NhZ2UiLCJkYXRhIiwiZml4IiwiRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJkZXNjcmlwdGlvbiIsInJlY29tbWVuZGVkIiwiY2F0ZWdvcnkiLCJ1cmwiLCJmaXhhYmxlIiwic2NoZW1hIiwibWluSXRlbXMiLCJtYXhJdGVtcyIsIml0ZW1zIiwiY3JlYXRlIiwiQ2FsbEV4cHJlc3Npb24iLCJhcmciLCJFeHBvcnROYW1lZERlY2xhcmF0aW9uIiwic291cmNlIiwiSW1wb3J0RGVjbGFyYXRpb24iLCJJbXBvcnRFeHByZXNzaW9uIl0sIm1hcHBpbmdzIjoiQUFBQSxhOztBQUVBLElBQU1BLGVBQWVDLFFBQVEsZ0JBQVIsQ0FBckIsQztBQUM2QkEsUUFBUSxZQUFSLEMsQ0FBWkMsTzs7QUFFakIsSUFBTUMsdUJBQXVCLHFCQUE3QjtBQUNBLElBQU1DLDBCQUEwQixvQkFBaEM7QUFDQSxJQUFNQztBQUNIRixvQkFERyxFQUNvQixxREFEcEI7QUFFSEMsdUJBRkcsRUFFdUIscURBRnZCLGFBQU47OztBQUtBLFNBQVNFLG9CQUFUO0FBQ0VDLEtBREY7QUFFRUMsSUFGRjtBQUdFQyxJQUhGO0FBSUVDLGtCQUpGO0FBS0VDLGdCQUxGO0FBTUU7QUFDQSxNQUFNQyxzQkFBc0JKLEtBQUtLLEtBQUwsQ0FBVyxDQUFYLElBQWdCLENBQTVDO0FBQ0EsTUFBTUMsUUFBUUMsT0FBT0MsU0FBUCxDQUFpQkwsZ0JBQWpCO0FBQ1ZELHVCQUFxQkUsbUJBRFg7QUFFVkEscUJBRko7QUFHQSxNQUFNSyxNQUFNRixPQUFPQyxTQUFQLENBQWlCTCxnQkFBakI7QUFDUkEscUJBQW1CQyxtQkFEWDtBQUVSSixPQUFLSyxLQUFMLENBQVcsQ0FBWCxJQUFnQixDQUZwQjs7QUFJQSxTQUFPTixNQUFNVyxnQkFBTixDQUF1QixDQUFDSixLQUFELEVBQVFHLEdBQVIsQ0FBdkIsRUFBcUNSLElBQXJDLENBQVA7QUFDRDs7QUFFRCxTQUFTVSxlQUFULENBQXlCWCxJQUF6QixFQUErQjtBQUM3QixTQUFPQSxRQUFRQSxLQUFLWSxJQUFMLEtBQWMsU0FBdEIsSUFBbUMsT0FBT1osS0FBS2EsS0FBWixLQUFzQixRQUFoRTtBQUNEOztBQUVELFNBQVNDLHlCQUFULENBQW1DZCxJQUFuQyxFQUF5QztBQUN2QyxTQUFPLENBQUNBLEtBQUtlLFFBQU47QUFDRmYsT0FBS2dCLE1BQUwsQ0FBWUosSUFBWixLQUFxQixZQURuQjtBQUVGWixPQUFLZ0IsTUFBTCxDQUFZQyxJQUFaLEtBQXFCO0FBQ3hCO0FBSEssS0FJRmpCLEtBQUtrQixTQUFMLENBQWVDLE1BQWYsS0FBMEIsQ0FKeEI7QUFLRm5CLE9BQUtrQixTQUFMLENBQWUsQ0FBZixDQUxFO0FBTUZQLGtCQUFnQlgsS0FBS2tCLFNBQUwsQ0FBZSxDQUFmLENBQWhCLENBTkw7QUFPRDs7QUFFRCxTQUFTRSxjQUFULENBQXdCQyxHQUF4QixFQUE2QkMsT0FBN0IsRUFBc0M7QUFDcEM7QUFDQSxNQUFJLENBQUNELEdBQUQsSUFBUUEsSUFBSVQsSUFBSixLQUFhLGlCQUF6QixFQUE0QyxDQUFFLE9BQVM7QUFDdkQsTUFBTVcsYUFBYSxXQUFXRixHQUFYLEdBQWlCQSxJQUFJUixLQUFyQixHQUE2QlEsSUFBSUosSUFBcEQ7QUFDQSxNQUFJLE9BQU9NLFVBQVAsS0FBc0IsUUFBMUIsRUFBb0MsQ0FBRUMsUUFBUUMsR0FBUixDQUFZSixHQUFaLEVBQWlCRSxVQUFqQixFQUErQixDQUpqQztBQUs1QkcsVUFMNEIsR0FLZkosT0FMZSxDQUs1QkksUUFMNEI7QUFNcEMsTUFBTUMsY0FBY0QsWUFBWUEsU0FBUyxxQkFBVCxDQUFoQztBQUNBO0FBQ0UsU0FBT0MsV0FBUCxLQUF1QixXQUF2Qjs7QUFFRSxTQUFPQSxXQUFQLEtBQXVCLFFBQXZCO0FBQ0csR0FBRSwwQkFBRCxDQUE2QkMsSUFBN0IsQ0FBa0NELFdBQWxDLENBSE4sQ0FERjs7QUFNRTtBQUNBLFVBQU0sSUFBSUUsU0FBSixDQUFjLGtIQUFkLENBQU47QUFDRDs7QUFFRCxNQUFJUCxRQUFRUSxPQUFSLENBQWdCLENBQWhCLE1BQXVCLE9BQTNCLEVBQW9DO0FBQ2xDLFFBQUksQ0FBQ1AsV0FBV1EsVUFBWCxDQUFzQixPQUF0QixDQUFMLEVBQXFDLENBQUUsT0FBUzs7QUFFaEQsUUFBTUMsbUJBQW1CVCxXQUFXVSxLQUFYLENBQWlCLENBQWpCLENBQXpCO0FBQ0EsUUFBSSxDQUFDekMsYUFBYXdDLGdCQUFiLEVBQStCTCxlQUFlTyxTQUE5QyxDQUFMLEVBQStELENBQUUsT0FBUzs7QUFFMUVaLFlBQVFhLE1BQVIsQ0FBZTtBQUNibkMsWUFBTXFCLEdBRE87QUFFYmUsZUFBU3ZDLFNBQVNELHVCQUFULENBRkk7QUFHYnlDLFlBQU0sRUFBRWQsWUFBWVMsZ0JBQWQsRUFITztBQUliO0FBQ0FNLFNBTGEsNEJBS1R2QyxLQUxTLEVBS0Y7QUFDVCxpQkFBT0QscUJBQXFCQyxLQUFyQixFQUE0QnNCLEdBQTVCLEVBQWlDLEVBQWpDLEVBQXFDLENBQXJDLEVBQXdDLENBQXhDLENBQVA7QUFDRCxTQVBZLGdCQUFmOztBQVNELEdBZkQsTUFlTyxJQUFJQyxRQUFRUSxPQUFSLENBQWdCLENBQWhCLE1BQXVCLFFBQTNCLEVBQXFDO0FBQzFDO0FBQ0VQLGVBQVdRLFVBQVgsQ0FBc0IsT0FBdEI7QUFDRyxLQUFDdkMsYUFBYStCLFVBQWIsRUFBeUJJLGVBQWVPLFNBQXhDLENBREo7QUFFRyxLQUFDMUMsOEJBQXFCK0IsVUFBckIsR0FBbUNJLGVBQWVPLFNBQWxELENBSE47QUFJRTtBQUNBO0FBQ0Q7O0FBRURaLFlBQVFhLE1BQVIsQ0FBZTtBQUNibkMsWUFBTXFCLEdBRE87QUFFYmUsZUFBU3ZDLFNBQVNGLG9CQUFULENBRkk7QUFHYjBDLFlBQU0sRUFBRWQsc0JBQUYsRUFITztBQUliO0FBQ0FlLFNBTGEsNEJBS1R2QyxLQUxTLEVBS0Y7QUFDVCxpQkFBT0QscUJBQXFCQyxLQUFyQixFQUE0QnNCLEdBQTVCLEVBQWlDLE9BQWpDLEVBQTBDLENBQTFDLEVBQTZDLENBQTdDLENBQVA7QUFDRCxTQVBZLGdCQUFmOztBQVNELEdBbEJNLE1Ba0JBLElBQUksT0FBT0MsUUFBUVEsT0FBUixDQUFnQixDQUFoQixDQUFQLEtBQThCLFdBQWxDLEVBQStDO0FBQ3BELFVBQU0sSUFBSVMsS0FBSixDQUFVLGdCQUFWLENBQU47QUFDRCxHQUZNLE1BRUE7QUFDTCxVQUFNLElBQUlBLEtBQUosZ0NBQWdDakIsUUFBUVEsT0FBUixDQUFnQixDQUFoQixDQUFoQyxFQUFOO0FBQ0Q7QUFDRjs7QUFFRDtBQUNBVSxPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZDLFFBQU07QUFDSjlCLFVBQU0sWUFERjtBQUVKK0IsVUFBTTtBQUNKQyxtQkFBYSxpR0FEVDtBQUVKQyxtQkFBYSxJQUZUO0FBR0pDLGdCQUFVLGlCQUhOO0FBSUpDLFdBQUtyRCxRQUFRLDZCQUFSLENBSkQsRUFGRjs7QUFRSnNELGFBQVMsTUFSTDtBQVNKQyxZQUFRO0FBQ05yQyxZQUFNLE9BREE7QUFFTnNDLGdCQUFVLENBRko7QUFHTkMsZ0JBQVUsQ0FISjtBQUlOQyxhQUFPO0FBQ0w7QUFDRSxnQkFBTSxDQUFDLFFBQUQsRUFBVyxPQUFYLENBRFIsRUFESyxDQUpELEVBVEo7Ozs7QUFtQkp2RCxzQkFuQkksRUFEUzs7QUFzQmZ3RCxRQXRCZSwrQkFzQlIvQixPQXRCUSxFQXNCQztBQUNkLGFBQU87QUFDTGdDLHNCQURLLHVDQUNVdEQsSUFEVixFQUNnQjtBQUNuQixnQkFBSSxDQUFDYywwQkFBMEJkLElBQTFCLENBQUwsRUFBc0MsQ0FBRSxPQUFTOztBQUVqRCxnQkFBTXVELE1BQU12RCxLQUFLa0IsU0FBTCxDQUFlLENBQWYsQ0FBWjs7QUFFQSxtQkFBT0UsZUFBZW1DLEdBQWYsRUFBb0JqQyxPQUFwQixDQUFQO0FBQ0QsV0FQSTtBQVFMa0MsOEJBUkssK0NBUWtCeEQsSUFSbEIsRUFRd0I7QUFDM0IsbUJBQU9vQixlQUFlcEIsS0FBS3lELE1BQXBCLEVBQTRCbkMsT0FBNUIsQ0FBUDtBQUNELFdBVkk7QUFXTG9DLHlCQVhLLDBDQVdhMUQsSUFYYixFQVdtQjtBQUN0QixtQkFBT29CLGVBQWVwQixLQUFLeUQsTUFBcEIsRUFBNEJuQyxPQUE1QixDQUFQO0FBQ0QsV0FiSTtBQWNMcUMsd0JBZEsseUNBY1kzRCxJQWRaLEVBY2tCO0FBQ3JCLGdCQUFJLENBQUNXLGdCQUFnQlgsS0FBS3lELE1BQXJCLENBQUwsRUFBbUMsQ0FBRSxPQUFTOztBQUU5QyxtQkFBT3JDLGVBQWVwQixLQUFLeUQsTUFBcEIsRUFBNEJuQyxPQUE1QixDQUFQO0FBQ0QsV0FsQkksNkJBQVA7O0FBb0JELEtBM0NjLG1CQUFqQiIsImZpbGUiOiJlbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGlzQ29yZU1vZHVsZSA9IHJlcXVpcmUoJ2lzLWNvcmUtbW9kdWxlJyk7XG5jb25zdCB7IGRlZmF1bHQ6IGRvY3NVcmwgfSA9IHJlcXVpcmUoJy4uL2RvY3NVcmwnKTtcblxuY29uc3QgRE9fUFJFRkVSX01FU1NBR0VfSUQgPSAncmVxdWlyZU5vZGVQcm90b2NvbCc7XG5jb25zdCBORVZFUl9QUkVGRVJfTUVTU0FHRV9JRCA9ICdmb3JiaWROb2RlUHJvdG9jb2wnO1xuY29uc3QgbWVzc2FnZXMgPSB7XG4gIFtET19QUkVGRVJfTUVTU0FHRV9JRF06ICdQcmVmZXIgYG5vZGU6e3ttb2R1bGVOYW1lfX1gIG92ZXIgYHt7bW9kdWxlTmFtZX19YC4nLFxuICBbTkVWRVJfUFJFRkVSX01FU1NBR0VfSURdOiAnUHJlZmVyIGB7e21vZHVsZU5hbWV9fWAgb3ZlciBgbm9kZTp7e21vZHVsZU5hbWV9fWAuJyxcbn07XG5cbmZ1bmN0aW9uIHJlcGxhY2VTdHJpbmdMaXRlcmFsKFxuICBmaXhlcixcbiAgbm9kZSxcbiAgdGV4dCxcbiAgcmVsYXRpdmVSYW5nZVN0YXJ0LFxuICByZWxhdGl2ZVJhbmdlRW5kLFxuKSB7XG4gIGNvbnN0IGZpcnN0Q2hhcmFjdGVySW5kZXggPSBub2RlLnJhbmdlWzBdICsgMTtcbiAgY29uc3Qgc3RhcnQgPSBOdW1iZXIuaXNJbnRlZ2VyKHJlbGF0aXZlUmFuZ2VFbmQpXG4gICAgPyByZWxhdGl2ZVJhbmdlU3RhcnQgKyBmaXJzdENoYXJhY3RlckluZGV4XG4gICAgOiBmaXJzdENoYXJhY3RlckluZGV4O1xuICBjb25zdCBlbmQgPSBOdW1iZXIuaXNJbnRlZ2VyKHJlbGF0aXZlUmFuZ2VFbmQpXG4gICAgPyByZWxhdGl2ZVJhbmdlRW5kICsgZmlyc3RDaGFyYWN0ZXJJbmRleFxuICAgIDogbm9kZS5yYW5nZVsxXSAtIDE7XG5cbiAgcmV0dXJuIGZpeGVyLnJlcGxhY2VUZXh0UmFuZ2UoW3N0YXJ0LCBlbmRdLCB0ZXh0KTtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmdMaXRlcmFsKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUgJiYgbm9kZS50eXBlID09PSAnTGl0ZXJhbCcgJiYgdHlwZW9mIG5vZGUudmFsdWUgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc1N0YXRpY1JlcXVpcmVXaXRoMVBhcmFtKG5vZGUpIHtcbiAgcmV0dXJuICFub2RlLm9wdGlvbmFsXG4gICAgJiYgbm9kZS5jYWxsZWUudHlwZSA9PT0gJ0lkZW50aWZpZXInXG4gICAgJiYgbm9kZS5jYWxsZWUubmFtZSA9PT0gJ3JlcXVpcmUnXG4gICAgLy8gY2hlY2sgZm9yIG9ubHkgMSBhcmd1bWVudFxuICAgICYmIG5vZGUuYXJndW1lbnRzLmxlbmd0aCA9PT0gMVxuICAgICYmIG5vZGUuYXJndW1lbnRzWzBdXG4gICAgJiYgaXNTdHJpbmdMaXRlcmFsKG5vZGUuYXJndW1lbnRzWzBdKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tBbmRSZXBvcnQoc3JjLCBjb250ZXh0KSB7XG4gIC8vIFRPRE8gdXNlIHNyYy5xdWFzaXNbMF0udmFsdWUucmF3XG4gIGlmICghc3JjIHx8IHNyYy50eXBlID09PSAnVGVtcGxhdGVMaXRlcmFsJykgeyByZXR1cm47IH1cbiAgY29uc3QgbW9kdWxlTmFtZSA9ICd2YWx1ZScgaW4gc3JjID8gc3JjLnZhbHVlIDogc3JjLm5hbWU7XG4gIGlmICh0eXBlb2YgbW9kdWxlTmFtZSAhPT0gJ3N0cmluZycpIHsgY29uc29sZS5sb2coc3JjLCBtb2R1bGVOYW1lKTsgfVxuICBjb25zdCB7IHNldHRpbmdzIH0gPSBjb250ZXh0O1xuICBjb25zdCBub2RlVmVyc2lvbiA9IHNldHRpbmdzICYmIHNldHRpbmdzWydpbXBvcnQvbm9kZS12ZXJzaW9uJ107XG4gIGlmIChcbiAgICB0eXBlb2Ygbm9kZVZlcnNpb24gIT09ICd1bmRlZmluZWQnXG4gICAgJiYgKFxuICAgICAgdHlwZW9mIG5vZGVWZXJzaW9uICE9PSAnc3RyaW5nJ1xuICAgICAgfHwgISgvXlswLTldK1xcLlswLTldK1xcLlswLTldKyQvKS50ZXN0KG5vZGVWZXJzaW9uKVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGltcG9ydC9ub2RlLXZlcnNpb25gIHNldHRpbmcgbXVzdCBiZSBhIHN0cmluZyBpbiB0aGUgZm9ybWF0IFwiMTAuMjMuNDVcIiAoYSBzZW12ZXIgdmVyc2lvbiwgd2l0aCBubyBsZWFkaW5nIHplcm8pJyk7XG4gIH1cblxuICBpZiAoY29udGV4dC5vcHRpb25zWzBdID09PSAnbmV2ZXInKSB7XG4gICAgaWYgKCFtb2R1bGVOYW1lLnN0YXJ0c1dpdGgoJ25vZGU6JykpIHsgcmV0dXJuOyB9XG5cbiAgICBjb25zdCBhY3R1YWxNb2R1bGVOYW1lID0gbW9kdWxlTmFtZS5zbGljZSg1KTtcbiAgICBpZiAoIWlzQ29yZU1vZHVsZShhY3R1YWxNb2R1bGVOYW1lLCBub2RlVmVyc2lvbiB8fCB1bmRlZmluZWQpKSB7IHJldHVybjsgfVxuXG4gICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgbm9kZTogc3JjLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZXNbTkVWRVJfUFJFRkVSX01FU1NBR0VfSURdLFxuICAgICAgZGF0YTogeyBtb2R1bGVOYW1lOiBhY3R1YWxNb2R1bGVOYW1lIH0sXG4gICAgICAvKiogQHBhcmFtIHtpbXBvcnQoJ2VzbGludCcpLlJ1bGUuUnVsZUZpeGVyfSBmaXhlciAqL1xuICAgICAgZml4KGZpeGVyKSB7XG4gICAgICAgIHJldHVybiByZXBsYWNlU3RyaW5nTGl0ZXJhbChmaXhlciwgc3JjLCAnJywgMCwgNSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKGNvbnRleHQub3B0aW9uc1swXSA9PT0gJ2Fsd2F5cycpIHtcbiAgICBpZiAoXG4gICAgICBtb2R1bGVOYW1lLnN0YXJ0c1dpdGgoJ25vZGU6JylcbiAgICAgIHx8ICFpc0NvcmVNb2R1bGUobW9kdWxlTmFtZSwgbm9kZVZlcnNpb24gfHwgdW5kZWZpbmVkKVxuICAgICAgfHwgIWlzQ29yZU1vZHVsZShgbm9kZToke21vZHVsZU5hbWV9YCwgbm9kZVZlcnNpb24gfHwgdW5kZWZpbmVkKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgIG5vZGU6IHNyYyxcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2VzW0RPX1BSRUZFUl9NRVNTQUdFX0lEXSxcbiAgICAgIGRhdGE6IHsgbW9kdWxlTmFtZSB9LFxuICAgICAgLyoqIEBwYXJhbSB7aW1wb3J0KCdlc2xpbnQnKS5SdWxlLlJ1bGVGaXhlcn0gZml4ZXIgKi9cbiAgICAgIGZpeChmaXhlcikge1xuICAgICAgICByZXR1cm4gcmVwbGFjZVN0cmluZ0xpdGVyYWwoZml4ZXIsIHNyYywgJ25vZGU6JywgMCwgMCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZXh0Lm9wdGlvbnNbMF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIG9wdGlvbicpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBvcHRpb246ICR7Y29udGV4dC5vcHRpb25zWzBdfWApO1xuICB9XG59XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCdlc2xpbnQnKS5SdWxlLlJ1bGVNb2R1bGV9ICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbWV0YToge1xuICAgIHR5cGU6ICdzdWdnZXN0aW9uJyxcbiAgICBkb2NzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0VuZm9yY2UgZWl0aGVyIHVzaW5nLCBvciBvbWl0dGluZywgdGhlIGBub2RlOmAgcHJvdG9jb2wgd2hlbiBpbXBvcnRpbmcgTm9kZS5qcyBidWlsdGluIG1vZHVsZXMuJyxcbiAgICAgIHJlY29tbWVuZGVkOiB0cnVlLFxuICAgICAgY2F0ZWdvcnk6ICdTdGF0aWMgYW5hbHlzaXMnLFxuICAgICAgdXJsOiBkb2NzVXJsKCdlbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UnKSxcbiAgICB9LFxuICAgIGZpeGFibGU6ICdjb2RlJyxcbiAgICBzY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogMSxcbiAgICAgIG1heEl0ZW1zOiAxLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGVudW06IFsnYWx3YXlzJywgJ25ldmVyJ10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0sXG4gICAgbWVzc2FnZXMsXG4gIH0sXG4gIGNyZWF0ZShjb250ZXh0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIENhbGxFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKCFpc1N0YXRpY1JlcXVpcmVXaXRoMVBhcmFtKG5vZGUpKSB7IHJldHVybjsgfVxuXG4gICAgICAgIGNvbnN0IGFyZyA9IG5vZGUuYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIHJldHVybiBjaGVja0FuZFJlcG9ydChhcmcsIGNvbnRleHQpO1xuICAgICAgfSxcbiAgICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICByZXR1cm4gY2hlY2tBbmRSZXBvcnQobm9kZS5zb3VyY2UsIGNvbnRleHQpO1xuICAgICAgfSxcbiAgICAgIEltcG9ydERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGNoZWNrQW5kUmVwb3J0KG5vZGUuc291cmNlLCBjb250ZXh0KTtcbiAgICAgIH0sXG4gICAgICBJbXBvcnRFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKCFpc1N0cmluZ0xpdGVyYWwobm9kZS5zb3VyY2UpKSB7IHJldHVybjsgfVxuXG4gICAgICAgIHJldHVybiBjaGVja0FuZFJlcG9ydChub2RlLnNvdXJjZSwgY29udGV4dCk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuIl19
lib/rules/extensions.js +49 lines
--- +++ @@ -2,2 +2,3 @@ +var _minimatch = require('minimatch');var _minimatch2 = _interopRequireDefault(_minimatch); var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);@@ -17,3 +18,23 @@     checkTypeImports: { type: 'boolean' },-    ignorePackages: { type: 'boolean' } } };+    ignorePackages: { type: 'boolean' },+    pathGroupOverrides: {+      type: 'array',+      items: {+        type: 'object',+        properties: {+          pattern: {+            type: 'string' },++          patternOptions: {+            type: 'object' },++          action: {+            type: 'string',+            'enum': ['enforce', 'ignore'] } },+++        additionalProperties: false,+        required: ['pattern', 'action'] } } } };++ @@ -55,2 +76,6 @@       result.checkTypeImports = obj.checkTypeImports;+    }++    if (obj.pathGroupOverrides !== undefined) {+      result.pathGroupOverrides = obj.pathGroupOverrides;     }@@ -145,2 +170,11 @@ +      function computeOverrideAction(pathGroupOverrides, path) {+        for (var i = 0, l = pathGroupOverrides.length; i < l; i++) {var _pathGroupOverrides$i =+          pathGroupOverrides[i],pattern = _pathGroupOverrides$i.pattern,patternOptions = _pathGroupOverrides$i.patternOptions,action = _pathGroupOverrides$i.action;+          if ((0, _minimatch2['default'])(path, pattern, patternOptions || { nocomment: true })) {+            return action;+          }+        }+      }+       function checkFileExtension(source, node) {@@ -151,4 +185,14 @@ +        // If not undefined, the user decided if rules are enforced on this import+        var overrideAction = computeOverrideAction(+        props.pathGroupOverrides || [],+        importPathWithQueryString);+++        if (overrideAction === 'ignore') {+          return;+        }+         // don't enforce anything on builtins-        if ((0, _importType.isBuiltIn)(importPathWithQueryString, context.settings)) {return;}+        if (!overrideAction && (0, _importType.isBuiltIn)(importPathWithQueryString, context.settings)) {return;} @@ -158,3 +202,3 @@         // Like `import Decimal from decimal.js`)-        if (isExternalRootModule(importPath)) {return;}+        if (!overrideAction && isExternalRootModule(importPath)) {return;} @@ -176,3 +220,3 @@           if (!props.checkTypeImports && (node.importKind === 'type' || node.exportKind === 'type')) {return;}-          var extensionRequired = isUseOfExtensionRequired(extension, isPackage);+          var extensionRequired = isUseOfExtensionRequired(extension, !overrideAction && isPackage);           var extensionForbidden = isUseOfExtensionForbidden(extension);@@ -197,2 +241,2 @@     }return create;}() };-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9leHRlbnNpb25zLmpzIl0sIm5hbWVzIjpbImVudW1WYWx1ZXMiLCJwYXR0ZXJuUHJvcGVydGllcyIsInR5cGUiLCJwcm9wZXJ0aWVzIiwicGF0dGVybiIsImNoZWNrVHlwZUltcG9ydHMiLCJpZ25vcmVQYWNrYWdlcyIsImJ1aWxkUHJvcGVydGllcyIsImNvbnRleHQiLCJyZXN1bHQiLCJkZWZhdWx0Q29uZmlnIiwib3B0aW9ucyIsImZvckVhY2giLCJvYmoiLCJ1bmRlZmluZWQiLCJPYmplY3QiLCJhc3NpZ24iLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwic2NoZW1hIiwiYW55T2YiLCJpdGVtcyIsImFkZGl0aW9uYWxJdGVtcyIsImNyZWF0ZSIsInByb3BzIiwiZ2V0TW9kaWZpZXIiLCJleHRlbnNpb24iLCJpc1VzZU9mRXh0ZW5zaW9uUmVxdWlyZWQiLCJpc1BhY2thZ2UiLCJpc1VzZU9mRXh0ZW5zaW9uRm9yYmlkZGVuIiwiaXNSZXNvbHZhYmxlV2l0aG91dEV4dGVuc2lvbiIsImZpbGUiLCJwYXRoIiwiZXh0bmFtZSIsImZpbGVXaXRob3V0RXh0ZW5zaW9uIiwic2xpY2UiLCJsZW5ndGgiLCJyZXNvbHZlZEZpbGVXaXRob3V0RXh0ZW5zaW9uIiwiaXNFeHRlcm5hbFJvb3RNb2R1bGUiLCJzbGFzaENvdW50Iiwic3BsaXQiLCJjaGVja0ZpbGVFeHRlbnNpb24iLCJzb3VyY2UiLCJub2RlIiwidmFsdWUiLCJpbXBvcnRQYXRoV2l0aFF1ZXJ5U3RyaW5nIiwic2V0dGluZ3MiLCJpbXBvcnRQYXRoIiwicmVwbGFjZSIsInJlc29sdmVkUGF0aCIsInN1YnN0cmluZyIsImVuZHNXaXRoIiwiaW1wb3J0S2luZCIsImV4cG9ydEtpbmQiLCJleHRlbnNpb25SZXF1aXJlZCIsImV4dGVuc2lvbkZvcmJpZGRlbiIsInJlcG9ydCIsIm1lc3NhZ2UiLCJjb21tb25qcyJdLCJtYXBwaW5ncyI6ImFBQUEsNEI7O0FBRUEsc0Q7QUFDQTtBQUNBLGtFO0FBQ0EscUM7O0FBRUEsSUFBTUEsYUFBYSxFQUFFLFFBQU0sQ0FBQyxRQUFELEVBQVcsZ0JBQVgsRUFBNkIsT0FBN0IsQ0FBUixFQUFuQjtBQUNBLElBQU1DLG9CQUFvQjtBQUN4QkMsUUFBTSxRQURrQjtBQUV4QkQscUJBQW1CLEVBQUUsTUFBTUQsVUFBUixFQUZLLEVBQTFCOztBQUlBLElBQU1HLGFBQWE7QUFDakJELFFBQU0sUUFEVztBQUVqQkMsY0FBWTtBQUNWQyxhQUFTSCxpQkFEQztBQUVWSSxzQkFBa0IsRUFBRUgsTUFBTSxTQUFSLEVBRlI7QUFHVkksb0JBQWdCLEVBQUVKLE1BQU0sU0FBUixFQUhOLEVBRkssRUFBbkI7Ozs7QUFTQSxTQUFTSyxlQUFULENBQXlCQyxPQUF6QixFQUFrQzs7QUFFaEMsTUFBTUMsU0FBUztBQUNiQyxtQkFBZSxPQURGO0FBRWJOLGFBQVMsRUFGSTtBQUdiRSxvQkFBZ0IsS0FISCxFQUFmOzs7QUFNQUUsVUFBUUcsT0FBUixDQUFnQkMsT0FBaEIsQ0FBd0IsVUFBQ0MsR0FBRCxFQUFTOztBQUUvQjtBQUNBLFFBQUksT0FBT0EsR0FBUCxLQUFlLFFBQW5CLEVBQTZCO0FBQzNCSixhQUFPQyxhQUFQLEdBQXVCRyxHQUF2QjtBQUNBO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJQSxJQUFJVCxPQUFKLEtBQWdCVSxTQUFoQixJQUE2QkQsSUFBSVAsY0FBSixLQUF1QlEsU0FBcEQsSUFBaUVELElBQUlSLGdCQUFKLEtBQXlCUyxTQUE5RixFQUF5RztBQUN2R0MsYUFBT0MsTUFBUCxDQUFjUCxPQUFPTCxPQUFyQixFQUE4QlMsR0FBOUI7QUFDQTtBQUNEOztBQUVEO0FBQ0EsUUFBSUEsSUFBSVQsT0FBSixLQUFnQlUsU0FBcEIsRUFBK0I7QUFDN0JDLGFBQU9DLE1BQVAsQ0FBY1AsT0FBT0wsT0FBckIsRUFBOEJTLElBQUlULE9BQWxDO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJUyxJQUFJUCxjQUFKLEtBQXVCUSxTQUEzQixFQUFzQztBQUNwQ0wsYUFBT0gsY0FBUCxHQUF3Qk8sSUFBSVAsY0FBNUI7QUFDRDs7QUFFRCxRQUFJTyxJQUFJUixnQkFBSixLQUF5QlMsU0FBN0IsRUFBd0M7QUFDdENMLGFBQU9KLGdCQUFQLEdBQTBCUSxJQUFJUixnQkFBOUI7QUFDRDtBQUNGLEdBM0JEOztBQTZCQSxNQUFJSSxPQUFPQyxhQUFQLEtBQXlCLGdCQUE3QixFQUErQztBQUM3Q0QsV0FBT0MsYUFBUCxHQUF1QixRQUF2QjtBQUNBRCxXQUFPSCxjQUFQLEdBQXdCLElBQXhCO0FBQ0Q7O0FBRUQsU0FBT0csTUFBUDtBQUNEOztBQUVEUSxPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZDLFFBQU07QUFDSmpCLFVBQU0sWUFERjtBQUVKa0IsVUFBTTtBQUNKQyxnQkFBVSxhQUROO0FBRUpDLG1CQUFhLGlFQUZUO0FBR0pDLFdBQUssMEJBQVEsWUFBUixDQUhELEVBRkY7OztBQVFKQyxZQUFRO0FBQ05DLGFBQU87QUFDTDtBQUNFdkIsY0FBTSxPQURSO0FBRUV3QixlQUFPLENBQUMxQixVQUFELENBRlQ7QUFHRTJCLHlCQUFpQixLQUhuQixFQURLOztBQU1MO0FBQ0V6QixjQUFNLE9BRFI7QUFFRXdCLGVBQU87QUFDTDFCLGtCQURLO0FBRUxHLGtCQUZLLENBRlQ7O0FBTUV3Qix5QkFBaUIsS0FObkIsRUFOSzs7QUFjTDtBQUNFekIsY0FBTSxPQURSO0FBRUV3QixlQUFPLENBQUN2QixVQUFELENBRlQ7QUFHRXdCLHlCQUFpQixLQUhuQixFQWRLOztBQW1CTDtBQUNFekIsY0FBTSxPQURSO0FBRUV3QixlQUFPLENBQUN6QixpQkFBRCxDQUZUO0FBR0UwQix5QkFBaUIsS0FIbkIsRUFuQks7O0FBd0JMO0FBQ0V6QixjQUFNLE9BRFI7QUFFRXdCLGVBQU87QUFDTDFCLGtCQURLO0FBRUxDLHlCQUZLLENBRlQ7O0FBTUUwQix5QkFBaUIsS0FObkIsRUF4QkssQ0FERCxFQVJKLEVBRFM7Ozs7OztBQThDZkMsUUE5Q2UsK0JBOENScEIsT0E5Q1EsRUE4Q0M7O0FBRWQsVUFBTXFCLFFBQVF0QixnQkFBZ0JDLE9BQWhCLENBQWQ7O0FBRUEsZUFBU3NCLFdBQVQsQ0FBcUJDLFNBQXJCLEVBQWdDO0FBQzlCLGVBQU9GLE1BQU16QixPQUFOLENBQWMyQixTQUFkLEtBQTRCRixNQUFNbkIsYUFBekM7QUFDRDs7QUFFRCxlQUFTc0Isd0JBQVQsQ0FBa0NELFNBQWxDLEVBQTZDRSxTQUE3QyxFQUF3RDtBQUN0RCxlQUFPSCxZQUFZQyxTQUFaLE1BQTJCLFFBQTNCLEtBQXdDLENBQUNGLE1BQU12QixjQUFQLElBQXlCLENBQUMyQixTQUFsRSxDQUFQO0FBQ0Q7O0FBRUQsZUFBU0MseUJBQVQsQ0FBbUNILFNBQW5DLEVBQThDO0FBQzVDLGVBQU9ELFlBQVlDLFNBQVosTUFBMkIsT0FBbEM7QUFDRDs7QUFFRCxlQUFTSSw0QkFBVCxDQUFzQ0MsSUFBdEMsRUFBNEM7QUFDMUMsWUFBTUwsWUFBWU0sa0JBQUtDLE9BQUwsQ0FBYUYsSUFBYixDQUFsQjtBQUNBLFlBQU1HLHVCQUF1QkgsS0FBS0ksS0FBTCxDQUFXLENBQVgsRUFBYyxDQUFDVCxVQUFVVSxNQUF6QixDQUE3QjtBQUNBLFlBQU1DLCtCQUErQiwwQkFBUUgsb0JBQVIsRUFBOEIvQixPQUE5QixDQUFyQzs7QUFFQSxlQUFPa0MsaUNBQWlDLDBCQUFRTixJQUFSLEVBQWM1QixPQUFkLENBQXhDO0FBQ0Q7O0FBRUQsZUFBU21DLG9CQUFULENBQThCUCxJQUE5QixFQUFvQztBQUNsQyxZQUFJQSxTQUFTLEdBQVQsSUFBZ0JBLFNBQVMsSUFBN0IsRUFBbUMsQ0FBRSxPQUFPLEtBQVAsQ0FBZTtBQUNwRCxZQUFNUSxhQUFhUixLQUFLUyxLQUFMLENBQVcsR0FBWCxFQUFnQkosTUFBaEIsR0FBeUIsQ0FBNUM7O0FBRUEsWUFBSUcsZUFBZSxDQUFuQixFQUF1QixDQUFFLE9BQU8sSUFBUCxDQUFjO0FBQ3ZDLFlBQUksMEJBQVNSLElBQVQsS0FBa0JRLGNBQWMsQ0FBcEMsRUFBdUMsQ0FBRSxPQUFPLElBQVAsQ0FBYztBQUN2RCxlQUFPLEtBQVA7QUFDRDs7QUFFRCxlQUFTRSxrQkFBVCxDQUE0QkMsTUFBNUIsRUFBb0NDLElBQXBDLEVBQTBDO0FBQ3hDO0FBQ0EsWUFBSSxDQUFDRCxNQUFELElBQVcsQ0FBQ0EsT0FBT0UsS0FBdkIsRUFBOEIsQ0FBRSxPQUFTOztBQUV6QyxZQUFNQyw0QkFBNEJILE9BQU9FLEtBQXpDOztBQUVBO0FBQ0EsWUFBSSwyQkFBVUMseUJBQVYsRUFBcUMxQyxRQUFRMkMsUUFBN0MsQ0FBSixFQUE0RCxDQUFFLE9BQVM7O0FBRXZFLFlBQU1DLGFBQWFGLDBCQUEwQkcsT0FBMUIsQ0FBa0MsU0FBbEMsRUFBNkMsRUFBN0MsQ0FBbkI7O0FBRUE7QUFDQTtBQUNBLFlBQUlWLHFCQUFxQlMsVUFBckIsQ0FBSixFQUFzQyxDQUFFLE9BQVM7O0FBRWpELFlBQU1FLGVBQWUsMEJBQVFGLFVBQVIsRUFBb0I1QyxPQUFwQixDQUFyQjs7QUFFQTtBQUNBO0FBQ0EsWUFBTXVCLFlBQVlNLGtCQUFLQyxPQUFMLENBQWFnQixnQkFBZ0JGLFVBQTdCLEVBQXlDRyxTQUF6QyxDQUFtRCxDQUFuRCxDQUFsQjs7QUFFQTtBQUNBLFlBQU10QixZQUFZO0FBQ2hCbUIsa0JBRGdCO0FBRWhCLGtDQUFRQSxVQUFSLEVBQW9CNUMsT0FBcEIsQ0FGZ0I7QUFHaEJBLGVBSGdCO0FBSWIsa0NBQVM0QyxVQUFULENBSkw7O0FBTUEsWUFBSSxDQUFDckIsU0FBRCxJQUFjLENBQUNxQixXQUFXSSxRQUFYLGNBQXdCekIsU0FBeEIsRUFBbkIsRUFBeUQ7QUFDdkQ7QUFDQSxjQUFJLENBQUNGLE1BQU14QixnQkFBUCxLQUE0QjJDLEtBQUtTLFVBQUwsS0FBb0IsTUFBcEIsSUFBOEJULEtBQUtVLFVBQUwsS0FBb0IsTUFBOUUsQ0FBSixFQUEyRixDQUFFLE9BQVM7QUFDdEcsY0FBTUMsb0JBQW9CM0IseUJBQXlCRCxTQUF6QixFQUFvQ0UsU0FBcEMsQ0FBMUI7QUFDQSxjQUFNMkIscUJBQXFCMUIsMEJBQTBCSCxTQUExQixDQUEzQjtBQUNBLGNBQUk0QixxQkFBcUIsQ0FBQ0Msa0JBQTFCLEVBQThDO0FBQzVDcEQsb0JBQVFxRCxNQUFSLENBQWU7QUFDYmIsb0JBQU1ELE1BRE87QUFFYmU7QUFDNEIvQix1Q0FBZ0JBLFNBQWhCLFdBQWdDLEVBRDVELHFCQUNzRW1CLHlCQUR0RSxPQUZhLEVBQWY7O0FBS0Q7QUFDRixTQVpELE1BWU8sSUFBSW5CLFNBQUosRUFBZTtBQUNwQixjQUFJRywwQkFBMEJILFNBQTFCLEtBQXdDSSw2QkFBNkJpQixVQUE3QixDQUE1QyxFQUFzRjtBQUNwRjVDLG9CQUFRcUQsTUFBUixDQUFlO0FBQ2JiLG9CQUFNRCxNQURPO0FBRWJlLHFFQUE4Qy9CLFNBQTlDLHVCQUFpRW1CLHlCQUFqRSxPQUZhLEVBQWY7O0FBSUQ7QUFDRjtBQUNGOztBQUVELGFBQU8sZ0NBQWNKLGtCQUFkLEVBQWtDLEVBQUVpQixVQUFVLElBQVosRUFBbEMsQ0FBUDtBQUNELEtBbEljLG1CQUFqQiIsImZpbGUiOiJleHRlbnNpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmltcG9ydCByZXNvbHZlIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvcmVzb2x2ZSc7XG5pbXBvcnQgeyBpc0J1aWx0SW4sIGlzRXh0ZXJuYWxNb2R1bGUsIGlzU2NvcGVkIH0gZnJvbSAnLi4vY29yZS9pbXBvcnRUeXBlJztcbmltcG9ydCBtb2R1bGVWaXNpdG9yIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvbW9kdWxlVmlzaXRvcic7XG5pbXBvcnQgZG9jc1VybCBmcm9tICcuLi9kb2NzVXJsJztcblxuY29uc3QgZW51bVZhbHVlcyA9IHsgZW51bTogWydhbHdheXMnLCAnaWdub3JlUGFja2FnZXMnLCAnbmV2ZXInXSB9O1xuY29uc3QgcGF0dGVyblByb3BlcnRpZXMgPSB7XG4gIHR5cGU6ICdvYmplY3QnLFxuICBwYXR0ZXJuUHJvcGVydGllczogeyAnLionOiBlbnVtVmFsdWVzIH0sXG59O1xuY29uc3QgcHJvcGVydGllcyA9IHtcbiAgdHlwZTogJ29iamVjdCcsXG4gIHByb3BlcnRpZXM6IHtcbiAgICBwYXR0ZXJuOiBwYXR0ZXJuUHJvcGVydGllcyxcbiAgICBjaGVja1R5cGVJbXBvcnRzOiB7IHR5cGU6ICdib29sZWFuJyB9LFxuICAgIGlnbm9yZVBhY2thZ2VzOiB7IHR5cGU6ICdib29sZWFuJyB9LFxuICB9LFxufTtcblxuZnVuY3Rpb24gYnVpbGRQcm9wZXJ0aWVzKGNvbnRleHQpIHtcblxuICBjb25zdCByZXN1bHQgPSB7XG4gICAgZGVmYXVsdENvbmZpZzogJ25ldmVyJyxcbiAgICBwYXR0ZXJuOiB7fSxcbiAgICBpZ25vcmVQYWNrYWdlczogZmFsc2UsXG4gIH07XG5cbiAgY29udGV4dC5vcHRpb25zLmZvckVhY2goKG9iaikgPT4ge1xuXG4gICAgLy8gSWYgdGhpcyBpcyBhIHN0cmluZywgc2V0IGRlZmF1bHRDb25maWcgdG8gaXRzIHZhbHVlXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXN1bHQuZGVmYXVsdENvbmZpZyA9IG9iajtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIGlzIG5vdCB0aGUgbmV3IHN0cnVjdHVyZSwgdHJhbnNmZXIgYWxsIHByb3BzIHRvIHJlc3VsdC5wYXR0ZXJuXG4gICAgaWYgKG9iai5wYXR0ZXJuID09PSB1bmRlZmluZWQgJiYgb2JqLmlnbm9yZVBhY2thZ2VzID09PSB1bmRlZmluZWQgJiYgb2JqLmNoZWNrVHlwZUltcG9ydHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQucGF0dGVybiwgb2JqKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiBwYXR0ZXJuIGlzIHByb3ZpZGVkLCB0cmFuc2ZlciBhbGwgcHJvcHNcbiAgICBpZiAob2JqLnBhdHRlcm4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQucGF0dGVybiwgb2JqLnBhdHRlcm4pO1xuICAgIH1cblxuICAgIC8vIElmIGlnbm9yZVBhY2thZ2VzIGlzIHByb3ZpZGVkLCB0cmFuc2ZlciBpdCB0byByZXN1bHRcbiAgICBpZiAob2JqLmlnbm9yZVBhY2thZ2VzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlc3VsdC5pZ25vcmVQYWNrYWdlcyA9IG9iai5pZ25vcmVQYWNrYWdlcztcbiAgICB9XG5cbiAgICBpZiAob2JqLmNoZWNrVHlwZUltcG9ydHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0LmNoZWNrVHlwZUltcG9ydHMgPSBvYmouY2hlY2tUeXBlSW1wb3J0cztcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChyZXN1bHQuZGVmYXVsdENvbmZpZyA9PT0gJ2lnbm9yZVBhY2thZ2VzJykge1xuICAgIHJlc3VsdC5kZWZhdWx0Q29uZmlnID0gJ2Fsd2F5cyc7XG4gICAgcmVzdWx0Lmlnbm9yZVBhY2thZ2VzID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGNhdGVnb3J5OiAnU3R5bGUgZ3VpZGUnLFxuICAgICAgZGVzY3JpcHRpb246ICdFbnN1cmUgY29uc2lzdGVudCB1c2Ugb2YgZmlsZSBleHRlbnNpb24gd2l0aGluIHRoZSBpbXBvcnQgcGF0aC4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCdleHRlbnNpb25zJyksXG4gICAgfSxcblxuICAgIHNjaGVtYToge1xuICAgICAgYW55T2Y6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgaXRlbXM6IFtlbnVtVmFsdWVzXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczogW1xuICAgICAgICAgICAgZW51bVZhbHVlcyxcbiAgICAgICAgICAgIHByb3BlcnRpZXMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczogW3Byb3BlcnRpZXNdLFxuICAgICAgICAgIGFkZGl0aW9uYWxJdGVtczogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiBbcGF0dGVyblByb3BlcnRpZXNdLFxuICAgICAgICAgIGFkZGl0aW9uYWxJdGVtczogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICBlbnVtVmFsdWVzLFxuICAgICAgICAgICAgcGF0dGVyblByb3BlcnRpZXMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9LFxuICB9LFxuXG4gIGNyZWF0ZShjb250ZXh0KSB7XG5cbiAgICBjb25zdCBwcm9wcyA9IGJ1aWxkUHJvcGVydGllcyhjb250ZXh0KTtcblxuICAgIGZ1bmN0aW9uIGdldE1vZGlmaWVyKGV4dGVuc2lvbikge1xuICAgICAgcmV0dXJuIHByb3BzLnBhdHRlcm5bZXh0ZW5zaW9uXSB8fCBwcm9wcy5kZWZhdWx0Q29uZmlnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXNlT2ZFeHRlbnNpb25SZXF1aXJlZChleHRlbnNpb24sIGlzUGFja2FnZSkge1xuICAgICAgcmV0dXJuIGdldE1vZGlmaWVyKGV4dGVuc2lvbikgPT09ICdhbHdheXMnICYmICghcHJvcHMuaWdub3JlUGFja2FnZXMgfHwgIWlzUGFja2FnZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVc2VPZkV4dGVuc2lvbkZvcmJpZGRlbihleHRlbnNpb24pIHtcbiAgICAgIHJldHVybiBnZXRNb2RpZmllcihleHRlbnNpb24pID09PSAnbmV2ZXInO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUmVzb2x2YWJsZVdpdGhvdXRFeHRlbnNpb24oZmlsZSkge1xuICAgICAgY29uc3QgZXh0ZW5zaW9uID0gcGF0aC5leHRuYW1lKGZpbGUpO1xuICAgICAgY29uc3QgZmlsZVdpdGhvdXRFeHRlbnNpb24gPSBmaWxlLnNsaWNlKDAsIC1leHRlbnNpb24ubGVuZ3RoKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkRmlsZVdpdGhvdXRFeHRlbnNpb24gPSByZXNvbHZlKGZpbGVXaXRob3V0RXh0ZW5zaW9uLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIHJlc29sdmVkRmlsZVdpdGhvdXRFeHRlbnNpb24gPT09IHJlc29sdmUoZmlsZSwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNFeHRlcm5hbFJvb3RNb2R1bGUoZmlsZSkge1xuICAgICAgaWYgKGZpbGUgPT09ICcuJyB8fCBmaWxlID09PSAnLi4nKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgY29uc3Qgc2xhc2hDb3VudCA9IGZpbGUuc3BsaXQoJy8nKS5sZW5ndGggLSAxO1xuXG4gICAgICBpZiAoc2xhc2hDb3VudCA9PT0gMCkgIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgIGlmIChpc1Njb3BlZChmaWxlKSAmJiBzbGFzaENvdW50IDw9IDEpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0ZpbGVFeHRlbnNpb24oc291cmNlLCBub2RlKSB7XG4gICAgICAvLyBiYWlsIGlmIHRoZSBkZWNsYXJhdGlvbiBkb2Vzbid0IGhhdmUgYSBzb3VyY2UsIGUuZy4gXCJleHBvcnQgeyBmb28gfTtcIiwgb3IgaWYgaXQncyBvbmx5IHBhcnRpYWxseSB0eXBlZCBsaWtlIGluIGFuIGVkaXRvclxuICAgICAgaWYgKCFzb3VyY2UgfHwgIXNvdXJjZS52YWx1ZSkgeyByZXR1cm47IH1cblxuICAgICAgY29uc3QgaW1wb3J0UGF0aFdpdGhRdWVyeVN0cmluZyA9IHNvdXJjZS52YWx1ZTtcblxuICAgICAgLy8gZG9uJ3QgZW5mb3JjZSBhbnl0aGluZyBvbiBidWlsdGluc1xuICAgICAgaWYgKGlzQnVpbHRJbihpbXBvcnRQYXRoV2l0aFF1ZXJ5U3RyaW5nLCBjb250ZXh0LnNldHRpbmdzKSkgeyByZXR1cm47IH1cblxuICAgICAgY29uc3QgaW1wb3J0UGF0aCA9IGltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmcucmVwbGFjZSgvXFw/KC4qKSQvLCAnJyk7XG5cbiAgICAgIC8vIGRvbid0IGVuZm9yY2UgaW4gcm9vdCBleHRlcm5hbCBwYWNrYWdlcyBhcyB0aGV5IG1heSBoYXZlIG5hbWVzIHdpdGggYC5qc2AuXG4gICAgICAvLyBMaWtlIGBpbXBvcnQgRGVjaW1hbCBmcm9tIGRlY2ltYWwuanNgKVxuICAgICAgaWYgKGlzRXh0ZXJuYWxSb290TW9kdWxlKGltcG9ydFBhdGgpKSB7IHJldHVybjsgfVxuXG4gICAgICBjb25zdCByZXNvbHZlZFBhdGggPSByZXNvbHZlKGltcG9ydFBhdGgsIGNvbnRleHQpO1xuXG4gICAgICAvLyBnZXQgZXh0ZW5zaW9uIGZyb20gcmVzb2x2ZWQgcGF0aCwgaWYgcG9zc2libGUuXG4gICAgICAvLyBmb3IgdW5yZXNvbHZlZCwgdXNlIHNvdXJjZSB2YWx1ZS5cbiAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IHBhdGguZXh0bmFtZShyZXNvbHZlZFBhdGggfHwgaW1wb3J0UGF0aCkuc3Vic3RyaW5nKDEpO1xuXG4gICAgICAvLyBkZXRlcm1pbmUgaWYgdGhpcyBpcyBhIG1vZHVsZVxuICAgICAgY29uc3QgaXNQYWNrYWdlID0gaXNFeHRlcm5hbE1vZHVsZShcbiAgICAgICAgaW1wb3J0UGF0aCxcbiAgICAgICAgcmVzb2x2ZShpbXBvcnRQYXRoLCBjb250ZXh0KSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICkgfHwgaXNTY29wZWQoaW1wb3J0UGF0aCk7XG5cbiAgICAgIGlmICghZXh0ZW5zaW9uIHx8ICFpbXBvcnRQYXRoLmVuZHNXaXRoKGAuJHtleHRlbnNpb259YCkpIHtcbiAgICAgICAgLy8gaWdub3JlIHR5cGUtb25seSBpbXBvcnRzIGFuZCBleHBvcnRzXG4gICAgICAgIGlmICghcHJvcHMuY2hlY2tUeXBlSW1wb3J0cyAmJiAobm9kZS5pbXBvcnRLaW5kID09PSAndHlwZScgfHwgbm9kZS5leHBvcnRLaW5kID09PSAndHlwZScpKSB7IHJldHVybjsgfVxuICAgICAgICBjb25zdCBleHRlbnNpb25SZXF1aXJlZCA9IGlzVXNlT2ZFeHRlbnNpb25SZXF1aXJlZChleHRlbnNpb24sIGlzUGFja2FnZSk7XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbkZvcmJpZGRlbiA9IGlzVXNlT2ZFeHRlbnNpb25Gb3JiaWRkZW4oZXh0ZW5zaW9uKTtcbiAgICAgICAgaWYgKGV4dGVuc2lvblJlcXVpcmVkICYmICFleHRlbnNpb25Gb3JiaWRkZW4pIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlOiBzb3VyY2UsXG4gICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICBgTWlzc2luZyBmaWxlIGV4dGVuc2lvbiAke2V4dGVuc2lvbiA/IGBcIiR7ZXh0ZW5zaW9ufVwiIGAgOiAnJ31mb3IgXCIke2ltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmd9XCJgLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGV4dGVuc2lvbikge1xuICAgICAgICBpZiAoaXNVc2VPZkV4dGVuc2lvbkZvcmJpZGRlbihleHRlbnNpb24pICYmIGlzUmVzb2x2YWJsZVdpdGhvdXRFeHRlbnNpb24oaW1wb3J0UGF0aCkpIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlOiBzb3VyY2UsXG4gICAgICAgICAgICBtZXNzYWdlOiBgVW5leHBlY3RlZCB1c2Ugb2YgZmlsZSBleHRlbnNpb24gXCIke2V4dGVuc2lvbn1cIiBmb3IgXCIke2ltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmd9XCJgLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZHVsZVZpc2l0b3IoY2hlY2tGaWxlRXh0ZW5zaW9uLCB7IGNvbW1vbmpzOiB0cnVlIH0pO1xuICB9LFxufTtcbiJdfQ==+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9leHRlbnNpb25zLmpzIl0sIm5hbWVzIjpbImVudW1WYWx1ZXMiLCJwYXR0ZXJuUHJvcGVydGllcyIsInR5cGUiLCJwcm9wZXJ0aWVzIiwicGF0dGVybiIsImNoZWNrVHlwZUltcG9ydHMiLCJpZ25vcmVQYWNrYWdlcyIsInBhdGhHcm91cE92ZXJyaWRlcyIsIml0ZW1zIiwicGF0dGVybk9wdGlvbnMiLCJhY3Rpb24iLCJhZGRpdGlvbmFsUHJvcGVydGllcyIsInJlcXVpcmVkIiwiYnVpbGRQcm9wZXJ0aWVzIiwiY29udGV4dCIsInJlc3VsdCIsImRlZmF1bHRDb25maWciLCJvcHRpb25zIiwiZm9yRWFjaCIsIm9iaiIsInVuZGVmaW5lZCIsIk9iamVjdCIsImFzc2lnbiIsIm1vZHVsZSIsImV4cG9ydHMiLCJtZXRhIiwiZG9jcyIsImNhdGVnb3J5IiwiZGVzY3JpcHRpb24iLCJ1cmwiLCJzY2hlbWEiLCJhbnlPZiIsImFkZGl0aW9uYWxJdGVtcyIsImNyZWF0ZSIsInByb3BzIiwiZ2V0TW9kaWZpZXIiLCJleHRlbnNpb24iLCJpc1VzZU9mRXh0ZW5zaW9uUmVxdWlyZWQiLCJpc1BhY2thZ2UiLCJpc1VzZU9mRXh0ZW5zaW9uRm9yYmlkZGVuIiwiaXNSZXNvbHZhYmxlV2l0aG91dEV4dGVuc2lvbiIsImZpbGUiLCJwYXRoIiwiZXh0bmFtZSIsImZpbGVXaXRob3V0RXh0ZW5zaW9uIiwic2xpY2UiLCJsZW5ndGgiLCJyZXNvbHZlZEZpbGVXaXRob3V0RXh0ZW5zaW9uIiwiaXNFeHRlcm5hbFJvb3RNb2R1bGUiLCJzbGFzaENvdW50Iiwic3BsaXQiLCJjb21wdXRlT3ZlcnJpZGVBY3Rpb24iLCJpIiwibCIsIm5vY29tbWVudCIsImNoZWNrRmlsZUV4dGVuc2lvbiIsInNvdXJjZSIsIm5vZGUiLCJ2YWx1ZSIsImltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmciLCJvdmVycmlkZUFjdGlvbiIsInNldHRpbmdzIiwiaW1wb3J0UGF0aCIsInJlcGxhY2UiLCJyZXNvbHZlZFBhdGgiLCJzdWJzdHJpbmciLCJlbmRzV2l0aCIsImltcG9ydEtpbmQiLCJleHBvcnRLaW5kIiwiZXh0ZW5zaW9uUmVxdWlyZWQiLCJleHRlbnNpb25Gb3JiaWRkZW4iLCJyZXBvcnQiLCJtZXNzYWdlIiwiY29tbW9uanMiXSwibWFwcGluZ3MiOiJhQUFBLDRCOztBQUVBLHNDO0FBQ0Esc0Q7QUFDQTtBQUNBLGtFO0FBQ0EscUM7O0FBRUEsSUFBTUEsYUFBYSxFQUFFLFFBQU0sQ0FBQyxRQUFELEVBQVcsZ0JBQVgsRUFBNkIsT0FBN0IsQ0FBUixFQUFuQjtBQUNBLElBQU1DLG9CQUFvQjtBQUN4QkMsUUFBTSxRQURrQjtBQUV4QkQscUJBQW1CLEVBQUUsTUFBTUQsVUFBUixFQUZLLEVBQTFCOztBQUlBLElBQU1HLGFBQWE7QUFDakJELFFBQU0sUUFEVztBQUVqQkMsY0FBWTtBQUNWQyxhQUFTSCxpQkFEQztBQUVWSSxzQkFBa0IsRUFBRUgsTUFBTSxTQUFSLEVBRlI7QUFHVkksb0JBQWdCLEVBQUVKLE1BQU0sU0FBUixFQUhOO0FBSVZLLHdCQUFvQjtBQUNsQkwsWUFBTSxPQURZO0FBRWxCTSxhQUFPO0FBQ0xOLGNBQU0sUUFERDtBQUVMQyxvQkFBWTtBQUNWQyxtQkFBUztBQUNQRixrQkFBTSxRQURDLEVBREM7O0FBSVZPLDBCQUFnQjtBQUNkUCxrQkFBTSxRQURRLEVBSk47O0FBT1ZRLGtCQUFRO0FBQ05SLGtCQUFNLFFBREE7QUFFTixvQkFBTSxDQUFDLFNBQUQsRUFBWSxRQUFaLENBRkEsRUFQRSxFQUZQOzs7QUFjTFMsOEJBQXNCLEtBZGpCO0FBZUxDLGtCQUFVLENBQUMsU0FBRCxFQUFZLFFBQVosQ0FmTCxFQUZXLEVBSlYsRUFGSyxFQUFuQjs7Ozs7O0FBNkJBLFNBQVNDLGVBQVQsQ0FBeUJDLE9BQXpCLEVBQWtDOztBQUVoQyxNQUFNQyxTQUFTO0FBQ2JDLG1CQUFlLE9BREY7QUFFYlosYUFBUyxFQUZJO0FBR2JFLG9CQUFnQixLQUhILEVBQWY7OztBQU1BUSxVQUFRRyxPQUFSLENBQWdCQyxPQUFoQixDQUF3QixVQUFDQyxHQUFELEVBQVM7O0FBRS9CO0FBQ0EsUUFBSSxPQUFPQSxHQUFQLEtBQWUsUUFBbkIsRUFBNkI7QUFDM0JKLGFBQU9DLGFBQVAsR0FBdUJHLEdBQXZCO0FBQ0E7QUFDRDs7QUFFRDtBQUNBLFFBQUlBLElBQUlmLE9BQUosS0FBZ0JnQixTQUFoQixJQUE2QkQsSUFBSWIsY0FBSixLQUF1QmMsU0FBcEQsSUFBaUVELElBQUlkLGdCQUFKLEtBQXlCZSxTQUE5RixFQUF5RztBQUN2R0MsYUFBT0MsTUFBUCxDQUFjUCxPQUFPWCxPQUFyQixFQUE4QmUsR0FBOUI7QUFDQTtBQUNEOztBQUVEO0FBQ0EsUUFBSUEsSUFBSWYsT0FBSixLQUFnQmdCLFNBQXBCLEVBQStCO0FBQzdCQyxhQUFPQyxNQUFQLENBQWNQLE9BQU9YLE9BQXJCLEVBQThCZSxJQUFJZixPQUFsQztBQUNEOztBQUVEO0FBQ0EsUUFBSWUsSUFBSWIsY0FBSixLQUF1QmMsU0FBM0IsRUFBc0M7QUFDcENMLGFBQU9ULGNBQVAsR0FBd0JhLElBQUliLGNBQTVCO0FBQ0Q7O0FBRUQsUUFBSWEsSUFBSWQsZ0JBQUosS0FBeUJlLFNBQTdCLEVBQXdDO0FBQ3RDTCxhQUFPVixnQkFBUCxHQUEwQmMsSUFBSWQsZ0JBQTlCO0FBQ0Q7O0FBRUQsUUFBSWMsSUFBSVosa0JBQUosS0FBMkJhLFNBQS9CLEVBQTBDO0FBQ3hDTCxhQUFPUixrQkFBUCxHQUE0QlksSUFBSVosa0JBQWhDO0FBQ0Q7QUFDRixHQS9CRDs7QUFpQ0EsTUFBSVEsT0FBT0MsYUFBUCxLQUF5QixnQkFBN0IsRUFBK0M7QUFDN0NELFdBQU9DLGFBQVAsR0FBdUIsUUFBdkI7QUFDQUQsV0FBT1QsY0FBUCxHQUF3QixJQUF4QjtBQUNEOztBQUVELFNBQU9TLE1BQVA7QUFDRDs7QUFFRFEsT0FBT0MsT0FBUCxHQUFpQjtBQUNmQyxRQUFNO0FBQ0p2QixVQUFNLFlBREY7QUFFSndCLFVBQU07QUFDSkMsZ0JBQVUsYUFETjtBQUVKQyxtQkFBYSxpRUFGVDtBQUdKQyxXQUFLLDBCQUFRLFlBQVIsQ0FIRCxFQUZGOzs7QUFRSkMsWUFBUTtBQUNOQyxhQUFPO0FBQ0w7QUFDRTdCLGNBQU0sT0FEUjtBQUVFTSxlQUFPLENBQUNSLFVBQUQsQ0FGVDtBQUdFZ0MseUJBQWlCLEtBSG5CLEVBREs7O0FBTUw7QUFDRTlCLGNBQU0sT0FEUjtBQUVFTSxlQUFPO0FBQ0xSLGtCQURLO0FBRUxHLGtCQUZLLENBRlQ7O0FBTUU2Qix5QkFBaUIsS0FObkIsRUFOSzs7QUFjTDtBQUNFOUIsY0FBTSxPQURSO0FBRUVNLGVBQU8sQ0FBQ0wsVUFBRCxDQUZUO0FBR0U2Qix5QkFBaUIsS0FIbkIsRUFkSzs7QUFtQkw7QUFDRTlCLGNBQU0sT0FEUjtBQUVFTSxlQUFPLENBQUNQLGlCQUFELENBRlQ7QUFHRStCLHlCQUFpQixLQUhuQixFQW5CSzs7QUF3Qkw7QUFDRTlCLGNBQU0sT0FEUjtBQUVFTSxlQUFPO0FBQ0xSLGtCQURLO0FBRUxDLHlCQUZLLENBRlQ7O0FBTUUrQix5QkFBaUIsS0FObkIsRUF4QkssQ0FERCxFQVJKLEVBRFM7Ozs7OztBQThDZkMsUUE5Q2UsK0JBOENSbkIsT0E5Q1EsRUE4Q0M7O0FBRWQsVUFBTW9CLFFBQVFyQixnQkFBZ0JDLE9BQWhCLENBQWQ7O0FBRUEsZUFBU3FCLFdBQVQsQ0FBcUJDLFNBQXJCLEVBQWdDO0FBQzlCLGVBQU9GLE1BQU05QixPQUFOLENBQWNnQyxTQUFkLEtBQTRCRixNQUFNbEIsYUFBekM7QUFDRDs7QUFFRCxlQUFTcUIsd0JBQVQsQ0FBa0NELFNBQWxDLEVBQTZDRSxTQUE3QyxFQUF3RDtBQUN0RCxlQUFPSCxZQUFZQyxTQUFaLE1BQTJCLFFBQTNCLEtBQXdDLENBQUNGLE1BQU01QixjQUFQLElBQXlCLENBQUNnQyxTQUFsRSxDQUFQO0FBQ0Q7O0FBRUQsZUFBU0MseUJBQVQsQ0FBbUNILFNBQW5DLEVBQThDO0FBQzVDLGVBQU9ELFlBQVlDLFNBQVosTUFBMkIsT0FBbEM7QUFDRDs7QUFFRCxlQUFTSSw0QkFBVCxDQUFzQ0MsSUFBdEMsRUFBNEM7QUFDMUMsWUFBTUwsWUFBWU0sa0JBQUtDLE9BQUwsQ0FBYUYsSUFBYixDQUFsQjtBQUNBLFlBQU1HLHVCQUF1QkgsS0FBS0ksS0FBTCxDQUFXLENBQVgsRUFBYyxDQUFDVCxVQUFVVSxNQUF6QixDQUE3QjtBQUNBLFlBQU1DLCtCQUErQiwwQkFBUUgsb0JBQVIsRUFBOEI5QixPQUE5QixDQUFyQzs7QUFFQSxlQUFPaUMsaUNBQWlDLDBCQUFRTixJQUFSLEVBQWMzQixPQUFkLENBQXhDO0FBQ0Q7O0FBRUQsZUFBU2tDLG9CQUFULENBQThCUCxJQUE5QixFQUFvQztBQUNsQyxZQUFJQSxTQUFTLEdBQVQsSUFBZ0JBLFNBQVMsSUFBN0IsRUFBbUMsQ0FBRSxPQUFPLEtBQVAsQ0FBZTtBQUNwRCxZQUFNUSxhQUFhUixLQUFLUyxLQUFMLENBQVcsR0FBWCxFQUFnQkosTUFBaEIsR0FBeUIsQ0FBNUM7O0FBRUEsWUFBSUcsZUFBZSxDQUFuQixFQUF1QixDQUFFLE9BQU8sSUFBUCxDQUFjO0FBQ3ZDLFlBQUksMEJBQVNSLElBQVQsS0FBa0JRLGNBQWMsQ0FBcEMsRUFBdUMsQ0FBRSxPQUFPLElBQVAsQ0FBYztBQUN2RCxlQUFPLEtBQVA7QUFDRDs7QUFFRCxlQUFTRSxxQkFBVCxDQUErQjVDLGtCQUEvQixFQUFtRG1DLElBQW5ELEVBQXlEO0FBQ3ZELGFBQUssSUFBSVUsSUFBSSxDQUFSLEVBQVdDLElBQUk5QyxtQkFBbUJ1QyxNQUF2QyxFQUErQ00sSUFBSUMsQ0FBbkQsRUFBc0RELEdBQXRELEVBQTJEO0FBQ2I3Qyw2QkFBbUI2QyxDQUFuQixDQURhLENBQ2pEaEQsT0FEaUQseUJBQ2pEQSxPQURpRCxDQUN4Q0ssY0FEd0MseUJBQ3hDQSxjQUR3QyxDQUN4QkMsTUFEd0IseUJBQ3hCQSxNQUR3QjtBQUV6RCxjQUFJLDRCQUFVZ0MsSUFBVixFQUFnQnRDLE9BQWhCLEVBQXlCSyxrQkFBa0IsRUFBRTZDLFdBQVcsSUFBYixFQUEzQyxDQUFKLEVBQXFFO0FBQ25FLG1CQUFPNUMsTUFBUDtBQUNEO0FBQ0Y7QUFDRjs7QUFFRCxlQUFTNkMsa0JBQVQsQ0FBNEJDLE1BQTVCLEVBQW9DQyxJQUFwQyxFQUEwQztBQUN4QztBQUNBLFlBQUksQ0FBQ0QsTUFBRCxJQUFXLENBQUNBLE9BQU9FLEtBQXZCLEVBQThCLENBQUUsT0FBUzs7QUFFekMsWUFBTUMsNEJBQTRCSCxPQUFPRSxLQUF6Qzs7QUFFQTtBQUNBLFlBQU1FLGlCQUFpQlQ7QUFDckJqQixjQUFNM0Isa0JBQU4sSUFBNEIsRUFEUDtBQUVyQm9ELGlDQUZxQixDQUF2Qjs7O0FBS0EsWUFBSUMsbUJBQW1CLFFBQXZCLEVBQWlDO0FBQy9CO0FBQ0Q7O0FBRUQ7QUFDQSxZQUFJLENBQUNBLGNBQUQsSUFBbUIsMkJBQVVELHlCQUFWLEVBQXFDN0MsUUFBUStDLFFBQTdDLENBQXZCLEVBQStFLENBQUUsT0FBUzs7QUFFMUYsWUFBTUMsYUFBYUgsMEJBQTBCSSxPQUExQixDQUFrQyxTQUFsQyxFQUE2QyxFQUE3QyxDQUFuQjs7QUFFQTtBQUNBO0FBQ0EsWUFBSSxDQUFDSCxjQUFELElBQW1CWixxQkFBcUJjLFVBQXJCLENBQXZCLEVBQXlELENBQUUsT0FBUzs7QUFFcEUsWUFBTUUsZUFBZSwwQkFBUUYsVUFBUixFQUFvQmhELE9BQXBCLENBQXJCOztBQUVBO0FBQ0E7QUFDQSxZQUFNc0IsWUFBWU0sa0JBQUtDLE9BQUwsQ0FBYXFCLGdCQUFnQkYsVUFBN0IsRUFBeUNHLFNBQXpDLENBQW1ELENBQW5ELENBQWxCOztBQUVBO0FBQ0EsWUFBTTNCLFlBQVk7QUFDaEJ3QixrQkFEZ0I7QUFFaEIsa0NBQVFBLFVBQVIsRUFBb0JoRCxPQUFwQixDQUZnQjtBQUdoQkEsZUFIZ0I7QUFJYixrQ0FBU2dELFVBQVQsQ0FKTDs7QUFNQSxZQUFJLENBQUMxQixTQUFELElBQWMsQ0FBQzBCLFdBQVdJLFFBQVgsY0FBd0I5QixTQUF4QixFQUFuQixFQUF5RDtBQUN2RDtBQUNBLGNBQUksQ0FBQ0YsTUFBTTdCLGdCQUFQLEtBQTRCb0QsS0FBS1UsVUFBTCxLQUFvQixNQUFwQixJQUE4QlYsS0FBS1csVUFBTCxLQUFvQixNQUE5RSxDQUFKLEVBQTJGLENBQUUsT0FBUztBQUN0RyxjQUFNQyxvQkFBb0JoQyx5QkFBeUJELFNBQXpCLEVBQW9DLENBQUN3QixjQUFELElBQW1CdEIsU0FBdkQsQ0FBMUI7QUFDQSxjQUFNZ0MscUJBQXFCL0IsMEJBQTBCSCxTQUExQixDQUEzQjtBQUNBLGNBQUlpQyxxQkFBcUIsQ0FBQ0Msa0JBQTFCLEVBQThDO0FBQzVDeEQsb0JBQVF5RCxNQUFSLENBQWU7QUFDYmQsb0JBQU1ELE1BRE87QUFFYmdCO0FBQzRCcEMsdUNBQWdCQSxTQUFoQixXQUFnQyxFQUQ1RCxxQkFDc0V1Qix5QkFEdEUsT0FGYSxFQUFmOztBQUtEO0FBQ0YsU0FaRCxNQVlPLElBQUl2QixTQUFKLEVBQWU7QUFDcEIsY0FBSUcsMEJBQTBCSCxTQUExQixLQUF3Q0ksNkJBQTZCc0IsVUFBN0IsQ0FBNUMsRUFBc0Y7QUFDcEZoRCxvQkFBUXlELE1BQVIsQ0FBZTtBQUNiZCxvQkFBTUQsTUFETztBQUViZ0IscUVBQThDcEMsU0FBOUMsdUJBQWlFdUIseUJBQWpFLE9BRmEsRUFBZjs7QUFJRDtBQUNGO0FBQ0Y7O0FBRUQsYUFBTyxnQ0FBY0osa0JBQWQsRUFBa0MsRUFBRWtCLFVBQVUsSUFBWixFQUFsQyxDQUFQO0FBQ0QsS0FySmMsbUJBQWpCIiwiZmlsZSI6ImV4dGVuc2lvbnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0IG1pbmltYXRjaCBmcm9tICdtaW5pbWF0Y2gnO1xuaW1wb3J0IHJlc29sdmUgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9yZXNvbHZlJztcbmltcG9ydCB7IGlzQnVpbHRJbiwgaXNFeHRlcm5hbE1vZHVsZSwgaXNTY29wZWQgfSBmcm9tICcuLi9jb3JlL2ltcG9ydFR5cGUnO1xuaW1wb3J0IG1vZHVsZVZpc2l0b3IgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9tb2R1bGVWaXNpdG9yJztcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnO1xuXG5jb25zdCBlbnVtVmFsdWVzID0geyBlbnVtOiBbJ2Fsd2F5cycsICdpZ25vcmVQYWNrYWdlcycsICduZXZlciddIH07XG5jb25zdCBwYXR0ZXJuUHJvcGVydGllcyA9IHtcbiAgdHlwZTogJ29iamVjdCcsXG4gIHBhdHRlcm5Qcm9wZXJ0aWVzOiB7ICcuKic6IGVudW1WYWx1ZXMgfSxcbn07XG5jb25zdCBwcm9wZXJ0aWVzID0ge1xuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIHBhdHRlcm46IHBhdHRlcm5Qcm9wZXJ0aWVzLFxuICAgIGNoZWNrVHlwZUltcG9ydHM6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgaWdub3JlUGFja2FnZXM6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgcGF0aEdyb3VwT3ZlcnJpZGVzOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgaXRlbXM6IHtcbiAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBwYXR0ZXJuOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBhdHRlcm5PcHRpb25zOiB7XG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICBlbnVtOiBbJ2VuZm9yY2UnLCAnaWdub3JlJ10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICByZXF1aXJlZDogWydwYXR0ZXJuJywgJ2FjdGlvbiddLFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxufTtcblxuZnVuY3Rpb24gYnVpbGRQcm9wZXJ0aWVzKGNvbnRleHQpIHtcblxuICBjb25zdCByZXN1bHQgPSB7XG4gICAgZGVmYXVsdENvbmZpZzogJ25ldmVyJyxcbiAgICBwYXR0ZXJuOiB7fSxcbiAgICBpZ25vcmVQYWNrYWdlczogZmFsc2UsXG4gIH07XG5cbiAgY29udGV4dC5vcHRpb25zLmZvckVhY2goKG9iaikgPT4ge1xuXG4gICAgLy8gSWYgdGhpcyBpcyBhIHN0cmluZywgc2V0IGRlZmF1bHRDb25maWcgdG8gaXRzIHZhbHVlXG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXN1bHQuZGVmYXVsdENvbmZpZyA9IG9iajtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIGlzIG5vdCB0aGUgbmV3IHN0cnVjdHVyZSwgdHJhbnNmZXIgYWxsIHByb3BzIHRvIHJlc3VsdC5wYXR0ZXJuXG4gICAgaWYgKG9iai5wYXR0ZXJuID09PSB1bmRlZmluZWQgJiYgb2JqLmlnbm9yZVBhY2thZ2VzID09PSB1bmRlZmluZWQgJiYgb2JqLmNoZWNrVHlwZUltcG9ydHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQucGF0dGVybiwgb2JqKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiBwYXR0ZXJuIGlzIHByb3ZpZGVkLCB0cmFuc2ZlciBhbGwgcHJvcHNcbiAgICBpZiAob2JqLnBhdHRlcm4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQucGF0dGVybiwgb2JqLnBhdHRlcm4pO1xuICAgIH1cblxuICAgIC8vIElmIGlnbm9yZVBhY2thZ2VzIGlzIHByb3ZpZGVkLCB0cmFuc2ZlciBpdCB0byByZXN1bHRcbiAgICBpZiAob2JqLmlnbm9yZVBhY2thZ2VzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlc3VsdC5pZ25vcmVQYWNrYWdlcyA9IG9iai5pZ25vcmVQYWNrYWdlcztcbiAgICB9XG5cbiAgICBpZiAob2JqLmNoZWNrVHlwZUltcG9ydHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0LmNoZWNrVHlwZUltcG9ydHMgPSBvYmouY2hlY2tUeXBlSW1wb3J0cztcbiAgICB9XG5cbiAgICBpZiAob2JqLnBhdGhHcm91cE92ZXJyaWRlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQucGF0aEdyb3VwT3ZlcnJpZGVzID0gb2JqLnBhdGhHcm91cE92ZXJyaWRlcztcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChyZXN1bHQuZGVmYXVsdENvbmZpZyA9PT0gJ2lnbm9yZVBhY2thZ2VzJykge1xuICAgIHJlc3VsdC5kZWZhdWx0Q29uZmlnID0gJ2Fsd2F5cyc7XG4gICAgcmVzdWx0Lmlnbm9yZVBhY2thZ2VzID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGNhdGVnb3J5OiAnU3R5bGUgZ3VpZGUnLFxuICAgICAgZGVzY3JpcHRpb246ICdFbnN1cmUgY29uc2lzdGVudCB1c2Ugb2YgZmlsZSBleHRlbnNpb24gd2l0aGluIHRoZSBpbXBvcnQgcGF0aC4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCdleHRlbnNpb25zJyksXG4gICAgfSxcblxuICAgIHNjaGVtYToge1xuICAgICAgYW55T2Y6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgaXRlbXM6IFtlbnVtVmFsdWVzXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczogW1xuICAgICAgICAgICAgZW51bVZhbHVlcyxcbiAgICAgICAgICAgIHByb3BlcnRpZXMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczogW3Byb3BlcnRpZXNdLFxuICAgICAgICAgIGFkZGl0aW9uYWxJdGVtczogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiBbcGF0dGVyblByb3BlcnRpZXNdLFxuICAgICAgICAgIGFkZGl0aW9uYWxJdGVtczogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICBlbnVtVmFsdWVzLFxuICAgICAgICAgICAgcGF0dGVyblByb3BlcnRpZXMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRpdGlvbmFsSXRlbXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9LFxuICB9LFxuXG4gIGNyZWF0ZShjb250ZXh0KSB7XG5cbiAgICBjb25zdCBwcm9wcyA9IGJ1aWxkUHJvcGVydGllcyhjb250ZXh0KTtcblxuICAgIGZ1bmN0aW9uIGdldE1vZGlmaWVyKGV4dGVuc2lvbikge1xuICAgICAgcmV0dXJuIHByb3BzLnBhdHRlcm5bZXh0ZW5zaW9uXSB8fCBwcm9wcy5kZWZhdWx0Q29uZmlnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXNlT2ZFeHRlbnNpb25SZXF1aXJlZChleHRlbnNpb24sIGlzUGFja2FnZSkge1xuICAgICAgcmV0dXJuIGdldE1vZGlmaWVyKGV4dGVuc2lvbikgPT09ICdhbHdheXMnICYmICghcHJvcHMuaWdub3JlUGFja2FnZXMgfHwgIWlzUGFja2FnZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVc2VPZkV4dGVuc2lvbkZvcmJpZGRlbihleHRlbnNpb24pIHtcbiAgICAgIHJldHVybiBnZXRNb2RpZmllcihleHRlbnNpb24pID09PSAnbmV2ZXInO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUmVzb2x2YWJsZVdpdGhvdXRFeHRlbnNpb24oZmlsZSkge1xuICAgICAgY29uc3QgZXh0ZW5zaW9uID0gcGF0aC5leHRuYW1lKGZpbGUpO1xuICAgICAgY29uc3QgZmlsZVdpdGhvdXRFeHRlbnNpb24gPSBmaWxlLnNsaWNlKDAsIC1leHRlbnNpb24ubGVuZ3RoKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkRmlsZVdpdGhvdXRFeHRlbnNpb24gPSByZXNvbHZlKGZpbGVXaXRob3V0RXh0ZW5zaW9uLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIHJlc29sdmVkRmlsZVdpdGhvdXRFeHRlbnNpb24gPT09IHJlc29sdmUoZmlsZSwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNFeHRlcm5hbFJvb3RNb2R1bGUoZmlsZSkge1xuICAgICAgaWYgKGZpbGUgPT09ICcuJyB8fCBmaWxlID09PSAnLi4nKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgY29uc3Qgc2xhc2hDb3VudCA9IGZpbGUuc3BsaXQoJy8nKS5sZW5ndGggLSAxO1xuXG4gICAgICBpZiAoc2xhc2hDb3VudCA9PT0gMCkgIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgIGlmIChpc1Njb3BlZChmaWxlKSAmJiBzbGFzaENvdW50IDw9IDEpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wdXRlT3ZlcnJpZGVBY3Rpb24ocGF0aEdyb3VwT3ZlcnJpZGVzLCBwYXRoKSB7XG4gICAgICBmb3IgKGxldCBpID0gMCwgbCA9IHBhdGhHcm91cE92ZXJyaWRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgY29uc3QgeyBwYXR0ZXJuLCBwYXR0ZXJuT3B0aW9ucywgYWN0aW9uIH0gPSBwYXRoR3JvdXBPdmVycmlkZXNbaV07XG4gICAgICAgIGlmIChtaW5pbWF0Y2gocGF0aCwgcGF0dGVybiwgcGF0dGVybk9wdGlvbnMgfHwgeyBub2NvbW1lbnQ6IHRydWUgfSkpIHtcbiAgICAgICAgICByZXR1cm4gYWN0aW9uO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tGaWxlRXh0ZW5zaW9uKHNvdXJjZSwgbm9kZSkge1xuICAgICAgLy8gYmFpbCBpZiB0aGUgZGVjbGFyYXRpb24gZG9lc24ndCBoYXZlIGEgc291cmNlLCBlLmcuIFwiZXhwb3J0IHsgZm9vIH07XCIsIG9yIGlmIGl0J3Mgb25seSBwYXJ0aWFsbHkgdHlwZWQgbGlrZSBpbiBhbiBlZGl0b3JcbiAgICAgIGlmICghc291cmNlIHx8ICFzb3VyY2UudmFsdWUpIHsgcmV0dXJuOyB9XG5cbiAgICAgIGNvbnN0IGltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmcgPSBzb3VyY2UudmFsdWU7XG5cbiAgICAgIC8vIElmIG5vdCB1bmRlZmluZWQsIHRoZSB1c2VyIGRlY2lkZWQgaWYgcnVsZXMgYXJlIGVuZm9yY2VkIG9uIHRoaXMgaW1wb3J0XG4gICAgICBjb25zdCBvdmVycmlkZUFjdGlvbiA9IGNvbXB1dGVPdmVycmlkZUFjdGlvbihcbiAgICAgICAgcHJvcHMucGF0aEdyb3VwT3ZlcnJpZGVzIHx8IFtdLFxuICAgICAgICBpbXBvcnRQYXRoV2l0aFF1ZXJ5U3RyaW5nLFxuICAgICAgKTtcblxuICAgICAgaWYgKG92ZXJyaWRlQWN0aW9uID09PSAnaWdub3JlJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGRvbid0IGVuZm9yY2UgYW55dGhpbmcgb24gYnVpbHRpbnNcbiAgICAgIGlmICghb3ZlcnJpZGVBY3Rpb24gJiYgaXNCdWlsdEluKGltcG9ydFBhdGhXaXRoUXVlcnlTdHJpbmcsIGNvbnRleHQuc2V0dGluZ3MpKSB7IHJldHVybjsgfVxuXG4gICAgICBjb25zdCBpbXBvcnRQYXRoID0gaW1wb3J0UGF0aFdpdGhRdWVyeVN0cmluZy5yZXBsYWNlKC9cXD8oLiopJC8sICcnKTtcblxuICAgICAgLy8gZG9uJ3QgZW5mb3JjZSBpbiByb290IGV4dGVybmFsIHBhY2thZ2VzIGFzIHRoZXkgbWF5IGhhdmUgbmFtZXMgd2l0aCBgLmpzYC5cbiAgICAgIC8vIExpa2UgYGltcG9ydCBEZWNpbWFsIGZyb20gZGVjaW1hbC5qc2ApXG4gICAgICBpZiAoIW92ZXJyaWRlQWN0aW9uICYmIGlzRXh0ZXJuYWxSb290TW9kdWxlKGltcG9ydFBhdGgpKSB7IHJldHVybjsgfVxuXG4gICAgICBjb25zdCByZXNvbHZlZFBhdGggPSByZXNvbHZlKGltcG9ydFBhdGgsIGNvbnRleHQpO1xuXG4gICAgICAvLyBnZXQgZXh0ZW5zaW9uIGZyb20gcmVzb2x2ZWQgcGF0aCwgaWYgcG9zc2libGUuXG4gICAgICAvLyBmb3IgdW5yZXNvbHZlZCwgdXNlIHNvdXJjZSB2YWx1ZS5cbiAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IHBhdGguZXh0bmFtZShyZXNvbHZlZFBhdGggfHwgaW1wb3J0UGF0aCkuc3Vic3RyaW5nKDEpO1xuXG4gICAgICAvLyBkZXRlcm1pbmUgaWYgdGhpcyBpcyBhIG1vZHVsZVxuICAgICAgY29uc3QgaXNQYWNrYWdlID0gaXNFeHRlcm5hbE1vZHVsZShcbiAgICAgICAgaW1wb3J0UGF0aCxcbiAgICAgICAgcmVzb2x2ZShpbXBvcnRQYXRoLCBjb250ZXh0KSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICkgfHwgaXNTY29wZWQoaW1wb3J0UGF0aCk7XG5cbiAgICAgIGlmICghZXh0ZW5zaW9uIHx8ICFpbXBvcnRQYXRoLmVuZHNXaXRoKGAuJHtleHRlbnNpb259YCkpIHtcbiAgICAgICAgLy8gaWdub3JlIHR5cGUtb25seSBpbXBvcnRzIGFuZCBleHBvcnRzXG4gICAgICAgIGlmICghcHJvcHMuY2hlY2tUeXBlSW1wb3J0cyAmJiAobm9kZS5pbXBvcnRLaW5kID09PSAndHlwZScgfHwgbm9kZS5leHBvcnRLaW5kID09PSAndHlwZScpKSB7IHJldHVybjsgfVxuICAgICAgICBjb25zdCBleHRlbnNpb25SZXF1aXJlZCA9IGlzVXNlT2ZFeHRlbnNpb25SZXF1aXJlZChleHRlbnNpb24sICFvdmVycmlkZUFjdGlvbiAmJiBpc1BhY2thZ2UpO1xuICAgICAgICBjb25zdCBleHRlbnNpb25Gb3JiaWRkZW4gPSBpc1VzZU9mRXh0ZW5zaW9uRm9yYmlkZGVuKGV4dGVuc2lvbik7XG4gICAgICAgIGlmIChleHRlbnNpb25SZXF1aXJlZCAmJiAhZXh0ZW5zaW9uRm9yYmlkZGVuKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgICAgbm9kZTogc291cmNlLFxuICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgYE1pc3NpbmcgZmlsZSBleHRlbnNpb24gJHtleHRlbnNpb24gPyBgXCIke2V4dGVuc2lvbn1cIiBgIDogJyd9Zm9yIFwiJHtpbXBvcnRQYXRoV2l0aFF1ZXJ5U3RyaW5nfVwiYCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChleHRlbnNpb24pIHtcbiAgICAgICAgaWYgKGlzVXNlT2ZFeHRlbnNpb25Gb3JiaWRkZW4oZXh0ZW5zaW9uKSAmJiBpc1Jlc29sdmFibGVXaXRob3V0RXh0ZW5zaW9uKGltcG9ydFBhdGgpKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgICAgbm9kZTogc291cmNlLFxuICAgICAgICAgICAgbWVzc2FnZTogYFVuZXhwZWN0ZWQgdXNlIG9mIGZpbGUgZXh0ZW5zaW9uIFwiJHtleHRlbnNpb259XCIgZm9yIFwiJHtpbXBvcnRQYXRoV2l0aFF1ZXJ5U3RyaW5nfVwiYCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtb2R1bGVWaXNpdG9yKGNoZWNrRmlsZUV4dGVuc2lvbiwgeyBjb21tb25qczogdHJ1ZSB9KTtcbiAgfSxcbn07XG4iXX0=
lib/rules/order.js +278 lines
--- +++ @@ -418,3 +418,3 @@ /** Some parsers (languages without types) don't provide ImportKind */-var DEAFULT_IMPORT_KIND = 'value';+var DEFAULT_IMPORT_KIND = 'value'; var getNormalizedValue = function getNormalizedValue(node, toLowerCase) {@@ -464,4 +464,4 @@         result = multiplierImportKind * compareString(-        nodeA.node.importKind || DEAFULT_IMPORT_KIND,-        nodeB.node.importKind || DEAFULT_IMPORT_KIND);+        nodeA.node.importKind || DEFAULT_IMPORT_KIND,+        nodeB.node.importKind || DEFAULT_IMPORT_KIND); @@ -515,8 +515,13 @@ -function computeRank(context, ranks, importEntry, excludedImportTypes) {+function computeRank(context, ranks, importEntry, excludedImportTypes, isSortingTypesGroup) {   var impType = void 0;   var rank = void 0;++  var isTypeGroupInGroups = ranks.omittedTypes.indexOf('type') === -1;+  var isTypeOnlyImport = importEntry.node.importKind === 'type';+  var isExcludedFromPathRank = isTypeOnlyImport && isTypeGroupInGroups && excludedImportTypes.has('type');+   if (importEntry.type === 'import:object') {     impType = 'object';-  } else if (importEntry.node.importKind === 'type' && ranks.omittedTypes.indexOf('type') === -1) {+  } else if (isTypeOnlyImport && isTypeGroupInGroups && !isSortingTypesGroup) {     impType = 'type';@@ -525,8 +530,19 @@   }-  if (!excludedImportTypes.has(impType)) {++  if (!excludedImportTypes.has(impType) && !isExcludedFromPathRank) {     rank = computePathRank(ranks.groups, ranks.pathGroups, importEntry.value, ranks.maxPosition);   }+   if (typeof rank === 'undefined') {     rank = ranks.groups[impType];-  }++    if (typeof rank === 'undefined') {+      return -1;+    }+  }++  if (isTypeOnlyImport && isSortingTypesGroup) {+    rank = ranks.groups.type + rank / 10;+  }+   if (importEntry.type !== 'import' && !importEntry.type.startsWith('import:')) {@@ -538,6 +554,16 @@ -function registerNode(context, importEntry, ranks, imported, excludedImportTypes) {-  var rank = computeRank(context, ranks, importEntry, excludedImportTypes);+function registerNode(context, importEntry, ranks, imported, excludedImportTypes, isSortingTypesGroup) {+  var rank = computeRank(context, ranks, importEntry, excludedImportTypes, isSortingTypesGroup);   if (rank !== -1) {-    imported.push(Object.assign({}, importEntry, { rank: rank }));+    var importNode = importEntry.node;++    if (importEntry.type === 'require' && importNode.parent.parent.type === 'VariableDeclaration') {+      importNode = importNode.parent.parent;+    }++    imported.push(Object.assign({},+    importEntry, {+      rank: rank,+      isMultiline: importNode.loc.end.line !== importNode.loc.start.line }));+   }@@ -566,5 +592,7 @@ -// Creates an object with type-rank pairs.-// Example: { index: 0, sibling: 1, parent: 1, external: 1, builtin: 2, internal: 2 }-// Will throw an error if it contains a type that does not exist, or has a duplicate+/**+                                                                                                             * Creates an object with type-rank pairs.+                                                                                                             *+                                                                                                             * Example: { index: 0, sibling: 1, parent: 1, external: 1, builtin: 2, internal: 2 }+                                                                                                             */ function convertGroupsToRanks(groups) {@@ -572,8 +600,2 @@     [].concat(group).forEach(function (groupItem) {-      if (types.indexOf(groupItem) === -1) {-        throw new Error('Incorrect configuration of the rule: Unknown type `' + String(JSON.stringify(groupItem)) + '`');-      }-      if (res[groupItem] !== undefined) {-        throw new Error('Incorrect configuration of the rule: `' + String(groupItem) + '` is duplicated');-      }       res[groupItem] = index * 2;@@ -667,3 +689,3 @@ -function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, distinctGroup) {+function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports_, newlinesBetweenTypeOnlyImports_, distinctGroup, isSortingTypesGroup, isConsolidatingSpaceBetweenImports) {   var getNumberOfEmptyLinesBetween = function getNumberOfEmptyLinesBetween(currentImport, previousImport) {@@ -680,21 +702,118 @@   imported.slice(1).forEach(function (currentImport) {-    var emptyLinesBetween = getNumberOfEmptyLinesBetween(currentImport, previousImport);-    var isStartOfDistinctGroup = getIsStartOfDistinctGroup(currentImport, previousImport);--    if (newlinesBetweenImports === 'always' ||-    newlinesBetweenImports === 'always-and-inside-groups') {-      if (currentImport.rank !== previousImport.rank && emptyLinesBetween === 0) {-        if (distinctGroup || !distinctGroup && isStartOfDistinctGroup) {+    var emptyLinesBetween = getNumberOfEmptyLinesBetween(+    currentImport,+    previousImport);+++    var isStartOfDistinctGroup = getIsStartOfDistinctGroup(+    currentImport,+    previousImport);+++    var isTypeOnlyImport = currentImport.node.importKind === 'type';+    var isPreviousImportTypeOnlyImport = previousImport.node.importKind === 'type';++    var isNormalImportNextToTypeOnlyImportAndRelevant = isTypeOnlyImport !== isPreviousImportTypeOnlyImport && isSortingTypesGroup;++    var isTypeOnlyImportAndRelevant = isTypeOnlyImport && isSortingTypesGroup;++    // In the special case where newlinesBetweenImports and consolidateIslands+    // want the opposite thing, consolidateIslands wins+    var newlinesBetweenImports = isSortingTypesGroup &&+    isConsolidatingSpaceBetweenImports && (+    previousImport.isMultiline || currentImport.isMultiline) &&+    newlinesBetweenImports_ === 'never' ?+    'always-and-inside-groups' :+    newlinesBetweenImports_;++    // In the special case where newlinesBetweenTypeOnlyImports and+    // consolidateIslands want the opposite thing, consolidateIslands wins+    var newlinesBetweenTypeOnlyImports = isSortingTypesGroup &&+    isConsolidatingSpaceBetweenImports && (+    isNormalImportNextToTypeOnlyImportAndRelevant ||+    previousImport.isMultiline ||+    currentImport.isMultiline) &&+    newlinesBetweenTypeOnlyImports_ === 'never' ?+    'always-and-inside-groups' :+    newlinesBetweenTypeOnlyImports_;++    var isNotIgnored = isTypeOnlyImportAndRelevant &&+    newlinesBetweenTypeOnlyImports !== 'ignore' ||+    !isTypeOnlyImportAndRelevant && newlinesBetweenImports !== 'ignore';++    if (isNotIgnored) {+      var shouldAssertNewlineBetweenGroups = (isTypeOnlyImportAndRelevant || isNormalImportNextToTypeOnlyImportAndRelevant) && (+      newlinesBetweenTypeOnlyImports === 'always' ||+      newlinesBetweenTypeOnlyImports === 'always-and-inside-groups') ||+      !isTypeOnlyImportAndRelevant && !isNormalImportNextToTypeOnlyImportAndRelevant && (+      newlinesBetweenImports === 'always' ||+      newlinesBetweenImports === 'always-and-inside-groups');++      var shouldAssertNoNewlineWithinGroup = (isTypeOnlyImportAndRelevant || isNormalImportNextToTypeOnlyImportAndRelevant) &&+      newlinesBetweenTypeOnlyImports !== 'always-and-inside-groups' ||+      !isTypeOnlyImportAndRelevant && !isNormalImportNextToTypeOnlyImportAndRelevant &&+      newlinesBetweenImports !== 'always-and-inside-groups';++      var shouldAssertNoNewlineBetweenGroup = !isSortingTypesGroup ||+      !isNormalImportNextToTypeOnlyImportAndRelevant ||+      newlinesBetweenTypeOnlyImports === 'never';++      var isTheNewlineBetweenImportsInTheSameGroup = distinctGroup && currentImport.rank === previousImport.rank ||+      !distinctGroup && !isStartOfDistinctGroup;++      // Let's try to cut down on linting errors sent to the user+      var alreadyReported = false;++      if (shouldAssertNewlineBetweenGroups) {+        if (currentImport.rank !== previousImport.rank && emptyLinesBetween === 0) {+          if (distinctGroup || isStartOfDistinctGroup) {+            alreadyReported = true;+            context.report({+              node: previousImport.node,+              message: 'There should be at least one empty line between import groups',+              fix: fixNewLineAfterImport(context, previousImport) });++          }+        } else if (emptyLinesBetween > 0 && shouldAssertNoNewlineWithinGroup) {+          if (isTheNewlineBetweenImportsInTheSameGroup) {+            alreadyReported = true;+            context.report({+              node: previousImport.node,+              message: 'There should be no empty line within import group',+              fix: removeNewLineAfterImport(context, currentImport, previousImport) });++          }+        }+      } else if (emptyLinesBetween > 0 && shouldAssertNoNewlineBetweenGroup) {+        alreadyReported = true;+        context.report({+          node: previousImport.node,+          message: 'There should be no empty line between import groups',+          fix: removeNewLineAfterImport(context, currentImport, previousImport) });++      }++      if (!alreadyReported && isConsolidatingSpaceBetweenImports) {+        if (emptyLinesBetween === 0 && currentImport.isMultiline) {           context.report({             node: previousImport.node,-            message: 'There should be at least one empty line between import groups',+            message: 'There should be at least one empty line between this import and the multi-line import that follows it',             fix: fixNewLineAfterImport(context, previousImport) }); -        }-      } else if (emptyLinesBetween > 0 &&-      newlinesBetweenImports !== 'always-and-inside-groups') {-        if (distinctGroup && currentImport.rank === previousImport.rank || !distinctGroup && !isStartOfDistinctGroup) {+        } else if (emptyLinesBetween === 0 && previousImport.isMultiline) {           context.report({             node: previousImport.node,-            message: 'There should be no empty line within import group',+            message: 'There should be at least one empty line between this multi-line import and the import that follows it',+            fix: fixNewLineAfterImport(context, previousImport) });++        } else if (+        emptyLinesBetween > 0 &&+        !previousImport.isMultiline &&+        !currentImport.isMultiline &&+        isTheNewlineBetweenImportsInTheSameGroup)+        {+          context.report({+            node: previousImport.node,+            message:+            'There should be no empty lines between this single-line import and the single-line import that follows it',             fix: removeNewLineAfterImport(context, currentImport, previousImport) });@@ -703,8 +822,2 @@       }-    } else if (emptyLinesBetween > 0) {-      context.report({-        node: previousImport.node,-        message: 'There should be no empty line between import groups',-        fix: removeNewLineAfterImport(context, currentImport, previousImport) });-     }@@ -742,3 +855,14 @@         groups: {-          type: 'array' },+          type: 'array',+          uniqueItems: true,+          items: {+            oneOf: [+            { 'enum': types },+            {+              type: 'array',+              uniqueItems: true,+              items: { 'enum': types } }] } },
… 156 more lines (truncated)
package.json +17 lines
--- +++ @@ -2,3 +2,3 @@   "name": "eslint-plugin-import",-  "version": "2.31.0",+  "version": "2.32.0",   "description": "Import with sanity.",@@ -8,2 +8,3 @@   "main": "lib/index.js",+  "types": "index.d.ts",   "directories": {@@ -18,3 +19,4 @@     "config",-    "memo-parser/{*.js,LICENSE,*.md}"+    "memo-parser/{*.js,LICENSE,*.md}",+    "index.d.ts"   ],@@ -33,5 +35,7 @@     "test-all": "node --require babel-register ./scripts/testAll",-    "test-examples": "npm run build && npm run test-example:legacy && npm run test-example:flat",+    "test-examples": "npm run build && npm run test-example:legacy && npm run test-example:flat && npm run test-example:v9",     "test-example:legacy": "cd examples/legacy && npm install && npm run lint",     "test-example:flat": "cd examples/flat && npm install && npm run lint",+    "test-example:v9": "cd examples/v9 && npm install && npm run lint",+    "test-types": "npx --package typescript@latest tsc --noEmit index.d.ts",     "prepublishOnly": "safe-publish-latest && npm run build",@@ -65,2 +69,3 @@     "@test-scope/some-module": "file:./tests/files/symlinked-module",+    "@types/eslint": "^8.56.12",     "@typescript-eslint/parser": "^2.23.0 || ^3.3.0 || ^4.29.3 || ^5.10.0",@@ -104,2 +109,3 @@     "sinon": "^2.4.1",+    "tmp": "^0.2.1",     "typescript": "^2.8.1 || ~3.9.5 || ~4.5.2",@@ -112,6 +118,6 @@     "@rtsao/scc": "^1.1.0",-    "array-includes": "^3.1.8",-    "array.prototype.findlastindex": "^1.2.5",-    "array.prototype.flat": "^1.3.2",-    "array.prototype.flatmap": "^1.3.2",+    "array-includes": "^3.1.9",+    "array.prototype.findlastindex": "^1.2.6",+    "array.prototype.flat": "^1.3.3",+    "array.prototype.flatmap": "^1.3.3",     "debug": "^3.2.7",@@ -119,5 +125,5 @@     "eslint-import-resolver-node": "^0.3.9",-    "eslint-module-utils": "^2.12.0",+    "eslint-module-utils": "^2.12.1",     "hasown": "^2.0.2",-    "is-core-module": "^2.15.1",+    "is-core-module": "^2.16.1",     "is-glob": "^4.0.3",@@ -126,5 +132,5 @@     "object.groupby": "^1.0.3",-    "object.values": "^1.2.0",+    "object.values": "^1.2.1",     "semver": "^6.3.1",-    "string.prototype.trimend": "^1.0.8",+    "string.prototype.trimend": "^1.0.9",     "tsconfig-paths": "^3.15.0"
event-stream npm
4.0.1 7y ago incident on record
DELETIONBURST ×10
latest 4.0.1 versions 84 maintainers 1
3.2.0
3.2.1
3.2.2
3.3.0
3.3.1
3.3.2
3.3.3
3.3.4
3.3.5
3.3.6
4.0.0
4.0.1
DELETION
3.3.6 published then removed
high · registry-verified · 2018-09-09 · 7y ago
BURST
2 releases in 43m: 0.5.2, 0.5.3
info · registry-verified · 2011-11-01 · 14y ago
BURST
8 releases in 0m: 0.1.0, 0.2.0, 0.2.1, 0.3.0, 0.4.0, 0.5.0, 0.5.1, 0.7.0
info · registry-verified · 2011-12-07 · 14y ago
BURST
2 releases in 10m: 0.9.0, 0.9.1
info · registry-verified · 2012-04-21 · 14y ago
BURST
3 releases in 39m: 0.9.4, 0.9.6, 0.9.7
info · registry-verified · 2012-04-25 · 14y ago
BURST
2 releases in 38m: 1.0.0, 1.1.0
info · registry-verified · 2012-05-21 · 14y ago
BURST
3 releases in 15m: 2.0.1, 2.0.2, 2.0.3
info · registry-verified · 2012-06-12 · 14y ago
BURST
2 releases in 41m: 2.1.3, 2.1.4
info · registry-verified · 2012-07-04 · 14y ago
BURST
2 releases in 28m: 2.2.3, 3.0.0
info · registry-verified · 2012-08-18 · 14y ago
BURST
2 releases in 4m: 3.0.6, 3.0.7
info · registry-verified · 2012-09-30 · 13y ago
BURST
2 releases in 16m: 3.0.17, 3.0.18
info · registry-verified · 2013-12-04 · 12y ago
release diff 4.0.0 → 4.0.1
+0 added · -0 removed · ~2 modified
package.json +4 lines
--- +++ @@ -2,3 +2,3 @@   "name": "event-stream",-  "version": "4.0.0",+  "version": "4.0.1",   "description": "construct pipes of streams of events",@@ -30,23 +30,5 @@   },-  "testling": {-    "files": "test/*.js",-    "browsers": {-      "ie": [-        8,-        9-      ],-      "firefox": [-        13-      ],-      "chrome": [-        20-      ],-      "safari": [-        5.1-      ],-      "opera": [-        12-      ]-    }-  },+  "keywords": [+    "stream", "map", "flatmap", "filter", "split", "join", "merge", "replace"+  ],   "license": "MIT",
husky npm
9.1.7 1y ago incident on record
DELETION ×13BURST ×13
latest 9.1.7 versions 215 maintainers 1
9.0.8
9.0.9
9.0.10
9.0.11
9.1.0
9.1.1
9.1.2
9.1.3
9.1.4
9.1.5
9.1.6
9.1.7
DELETION
0.1.0 published then removed
high · registry-verified · 2014-06-09 · 12y ago
DELETION
0.1.1 published then removed
high · registry-verified · 2014-06-09 · 12y ago
DELETION
0.1.2 published then removed
high · registry-verified · 2014-06-09 · 12y ago
DELETION
0.1.3 published then removed
high · registry-verified · 2014-06-09 · 12y ago
DELETION
0.1.4 published then removed
high · registry-verified · 2014-06-10 · 12y ago
DELETION
0.1.5 published then removed
high · registry-verified · 2014-06-10 · 12y ago
DELETION
0.2.0 published then removed
high · registry-verified · 2014-06-16 · 12y ago
DELETION
0.2.1 published then removed
high · registry-verified · 2014-06-16 · 12y ago
DELETION
0.2.3 published then removed
high · registry-verified · 2014-06-18 · 12y ago
DELETION
0.3.0 published then removed
high · registry-verified · 2014-06-23 · 12y ago
DELETION
0.3.1 published then removed
high · registry-verified · 2014-06-23 · 12y ago
DELETION
0.3.2 published then removed
high · registry-verified · 2014-06-23 · 12y ago
DELETION
0.3.3 published then removed
high · registry-verified · 2014-06-23 · 12y ago
BURST
4 releases in 20m: 0.1.0, 0.1.1, 0.1.2, 0.1.3
info · registry-verified · 2014-06-09 · 12y ago
BURST
2 releases in 8m: 0.3.0, 0.3.1
info · registry-verified · 2014-06-23 · 12y ago
BURST
2 releases in 10m: 0.3.3, 0.4.0
info · registry-verified · 2014-06-23 · 12y ago
BURST
3 releases in 49m: 0.4.1, 0.4.2, 0.4.3
info · registry-verified · 2014-06-23 · 12y ago
BURST
2 releases in 59m: 0.9.0, 0.9.1
info · registry-verified · 2015-07-22 · 11y ago
BURST
2 releases in 51m: 3.0.6, 3.0.7
info · registry-verified · 2019-09-28 · 6y ago
BURST
2 releases in 20m: 4.0.2, 4.0.3
info · registry-verified · 2020-01-09 · 6y ago
BURST
3 releases in 51m: 5.0.2, 5.0.3, 5.0.4
info · registry-verified · 2020-11-22 · 5y ago
BURST
2 releases in 2m: 4.3.2, 4.3.3
info · registry-verified · 2020-12-05 · 5y ago
BURST
2 releases in 9m: 5.0.5, 5.0.6
info · registry-verified · 2020-12-11 · 5y ago
BURST
2 releases in 9m: 7.0.3, 7.0.4
info · registry-verified · 2021-10-21 · 4y ago
BURST
2 releases in 48m: 9.0.3, 9.0.4
info · registry-verified · 2024-01-25 · 2y ago
BURST
2 releases in 42m: 9.0.8, 9.0.9
info · registry-verified · 2024-02-01 · 2y ago
release diff 9.1.6 → 9.1.7
+0 added · -0 removed · ~2 modified
bin.js +1 lines
--- +++ @@ -21,3 +21,3 @@ -d = c => console.error(`${c} command is DEPRECATED`)+d = c => console.error(`husky - ${c} command is DEPRECATED`) if (['add', 'set', 'uninstall'].includes(a)) { d(a); p.exit(1) }
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@ 	"name": "husky",-	"version": "9.1.6",+	"version": "9.1.7", 	"type": "module",
mocha npm
11.8.0 19d ago incident on record
critical-tier DELETIONBURST
latest 11.8.0 versions 247 maintainers 2 critical-tier (snapshotted)
11.3.0
11.4.0
11.5.0
11.6.0
11.7.0
11.7.1
11.7.2
11.7.3
11.7.4
11.7.5
11.7.6
11.8.0
DELETION
3.4.0 published then removed
high · registry-verified · 2017-05-14 · 9y ago
BURST
2 releases in 46m: 1.4.3, 1.5.0
info · registry-verified · 2012-09-21 · 13y ago
release diff 11.7.6 → 11.8.0
+0 added · -0 removed · ~8 modified
lib/cli/run-option-metadata.js +1 lines
--- +++ @@ -37,2 +37,3 @@     "exit",+    "fail-hook-affected-tests",     "pass-on-failing-test-suite",
lib/cli/run.js +5 lines
--- +++ @@ -103,2 +103,7 @@         description: "Not fail test run if tests were failed",+        group: GROUPS.RULES,+      },+      "fail-hook-affected-tests": {+        description:+          "Report tests as failed when affected by hook failures (before/beforeEach)",         group: GROUPS.RULES,
lib/mocha.js +15 lines
--- +++ @@ -841,2 +841,16 @@ /**+ * Reports tests as failed when they are skipped due to a hook failure.+ *+ * @public+ * @see [CLI option](../#-fail-hook-affected-tests)+ * @param {boolean} [failHookAffectedTests=true] - Whether to fail tests affected by hook failures.+ * @return {Mocha} this+ * @chainable+ */+Mocha.prototype.failHookAffectedTests = function (failHookAffectedTests) {+  this.options.failHookAffectedTests = failHookAffectedTests !== false;+  return this;+};++/**  * Fails test run if no tests encountered with exit-code 1.@@ -968,2 +982,3 @@     dryRun: options.dryRun,+    failHookAffectedTests: options.failHookAffectedTests,     failZero: options.failZero,
lib/nodejs/esm-utils.js +3 lines
--- +++ @@ -100,2 +100,5 @@     debug("requireModule caught err: %O", requireErr.message);+    if (requireErr.name === "TSError") {+      throw requireErr;+    }     try {
lib/runner.js +118 lines
--- +++ @@ -184,2 +184,3 @@    * @param {boolean} [opts.failZero] - Whether to fail test run if zero tests encountered.+   * @param {boolean} [opts.failHookAffectedTests] - Whether to fail all tests affected by hook failures.    */@@ -441,2 +442,69 @@   }+};++/**+ * Create an error object for a test that was skipped due to a hook failure.+ *+ * @private+ * @param {string} hookTitle - The title of the failed hook+ * @param {*} hookError - The error from the failed hook (may not be an Error object)+ * @returns {Error} The error object for the skipped test+ */+function createHookSkipError(hookTitle, hookError) {+  // Handle falsy or undefined exceptions+  if (!hookError) {+    hookError = createInvalidExceptionError(+      'Hook "' + hookTitle + '" failed with exception: ' + hookError,+      hookError,+    );+  }+  // Convert non-Error objects to Error+  else if (!isError(hookError)) {+    hookError = thrown2Error(hookError);+  }++  var errorMessage =+    'Test skipped due to failure in hook "' ++    hookTitle ++    '": ' ++    hookError.message;+  var testError = new Error(errorMessage);+  testError.stack = hookError.stack;+  return testError;+}++/**+ * Fail all tests that are affected by a hook failure.+ * This is used when the `failHookAffectedTests` option is enabled.+ *+ * @private+ * @param {Suite} suite - The suite containing the affected tests+ * @param {Error} hookError - The error from the failed hook+ * @param {string} hookTitle - The title of the failed hook+ */+Runner.prototype.failAffectedTests = function (suite, hookError, hookTitle) {+  if (!this._opts.failHookAffectedTests) {+    return;+  }++  var self = this;+  var testError = createHookSkipError(hookTitle, hookError);++  // Recursively fail all tests in this suite and its child suites+  function failTestsInSuite(s) {+    s.tests.forEach(function (test) {+      // Only fail tests that haven't been executed yet+      if (!test.state) {+        test.state = STATE_FAILED;+        self.failures++;+        self.emit(constants.EVENT_TEST_BEGIN, test);+        self.emit(constants.EVENT_TEST_FAIL, test, testError);+        self.emit(constants.EVENT_TEST_END, test);+      }+    });++    s.suites.forEach(failTestsInSuite);+  }++  failTestsInSuite(suite); };@@ -585,2 +653,24 @@         self.fail(hook, err);+        // If failHookAffectedTests is enabled, mark affected tests as failed+        if (self._opts.failHookAffectedTests) {+          if (name === HOOK_TYPE_BEFORE_ALL) {+            self.failAffectedTests(self.suite, err, hook.title);+          } else if (name === HOOK_TYPE_BEFORE_EACH) {+            // Fail the current test+            if (self.test && !self.test.state) {+              var testError = createHookSkipError(hook.title, err);++              self.test.state = STATE_FAILED;+              self.failures++;+              self.emit(constants.EVENT_TEST_BEGIN, self.test);+              self.emit(constants.EVENT_TEST_FAIL, self.test, testError);+              self.emit(constants.EVENT_TEST_END, self.test);+            }+            // Store the hook error info for remaining tests+            self._failedBeforeEachHook = {+              error: err,+              title: hook.title,+            };+          }+        }         // stop executing hooks, notify callee of hook err@@ -736,5 +826,32 @@ -  function hookErr(_, errSuite, after) {+  function hookErr(err, errSuite, after) {     // before/after Each hook for errSuite failed:     var orig = self.suite;++    // If failHookAffectedTests is enabled and this is a beforeEach failure,+    // mark remaining tests as failed+    if (+      self._opts.failHookAffectedTests &&+      !after &&+      self._failedBeforeEachHook+    ) {+      // Fail all remaining tests in the suite+      var remainingTests = tests.slice();+      remainingTests.forEach(function (t) {+        if (!t.state) {+          var testError = createHookSkipError(+            self._failedBeforeEachHook.title,+            self._failedBeforeEachHook.error,+          );++          t.state = STATE_FAILED;+          self.failures++;+          self.emit(constants.EVENT_TEST_BEGIN, t);+          self.emit(constants.EVENT_TEST_FAIL, t, testError);+          self.emit(constants.EVENT_TEST_END, t);+        }+      });+      // Clear the stored hook info+      delete self._failedBeforeEachHook;+    } 
mocha.js +135 lines
--- +++ @@ -1,2 +1,2 @@-// [email protected] in javascript ES2018+// [email protected] in javascript ES2018 (function (global, factory) {@@ -15157,2 +15157,3 @@      * @param {boolean} [opts.failZero] - Whether to fail test run if zero tests encountered.+     * @param {boolean} [opts.failHookAffectedTests] - Whether to fail all tests affected by hook failures.      */@@ -15414,2 +15415,69 @@     }+  };++  /**+   * Create an error object for a test that was skipped due to a hook failure.+   *+   * @private+   * @param {string} hookTitle - The title of the failed hook+   * @param {*} hookError - The error from the failed hook (may not be an Error object)+   * @returns {Error} The error object for the skipped test+   */+  function createHookSkipError(hookTitle, hookError) {+    // Handle falsy or undefined exceptions+    if (!hookError) {+      hookError = createInvalidExceptionError(+        'Hook "' + hookTitle + '" failed with exception: ' + hookError,+        hookError,+      );+    }+    // Convert non-Error objects to Error+    else if (!isError(hookError)) {+      hookError = thrown2Error(hookError);+    }++    var errorMessage =+      'Test skipped due to failure in hook "' ++      hookTitle ++      '": ' ++      hookError.message;+    var testError = new Error(errorMessage);+    testError.stack = hookError.stack;+    return testError;+  }++  /**+   * Fail all tests that are affected by a hook failure.+   * This is used when the `failHookAffectedTests` option is enabled.+   *+   * @private+   * @param {Suite} suite - The suite containing the affected tests+   * @param {Error} hookError - The error from the failed hook+   * @param {string} hookTitle - The title of the failed hook+   */+  Runner.prototype.failAffectedTests = function (suite, hookError, hookTitle) {+    if (!this._opts.failHookAffectedTests) {+      return;+    }++    var self = this;+    var testError = createHookSkipError(hookTitle, hookError);++    // Recursively fail all tests in this suite and its child suites+    function failTestsInSuite(s) {+      s.tests.forEach(function (test) {+        // Only fail tests that haven't been executed yet+        if (!test.state) {+          test.state = STATE_FAILED;+          self.failures++;+          self.emit(constants$1.EVENT_TEST_BEGIN, test);+          self.emit(constants$1.EVENT_TEST_FAIL, test, testError);+          self.emit(constants$1.EVENT_TEST_END, test);+        }+      });++      s.suites.forEach(failTestsInSuite);+    }++    failTestsInSuite(suite);   };@@ -15558,2 +15626,24 @@           self.fail(hook, err);+          // If failHookAffectedTests is enabled, mark affected tests as failed+          if (self._opts.failHookAffectedTests) {+            if (name === HOOK_TYPE_BEFORE_ALL) {+              self.failAffectedTests(self.suite, err, hook.title);+            } else if (name === HOOK_TYPE_BEFORE_EACH) {+              // Fail the current test+              if (self.test && !self.test.state) {+                var testError = createHookSkipError(hook.title, err);++                self.test.state = STATE_FAILED;+                self.failures++;+                self.emit(constants$1.EVENT_TEST_BEGIN, self.test);+                self.emit(constants$1.EVENT_TEST_FAIL, self.test, testError);+                self.emit(constants$1.EVENT_TEST_END, self.test);+              }+              // Store the hook error info for remaining tests+              self._failedBeforeEachHook = {+                error: err,+                title: hook.title,+              };+            }+          }           // stop executing hooks, notify callee of hook err@@ -15709,5 +15799,32 @@ -    function hookErr(_, errSuite, after) {+    function hookErr(err, errSuite, after) {       // before/after Each hook for errSuite failed:       var orig = self.suite;++      // If failHookAffectedTests is enabled and this is a beforeEach failure,+      // mark remaining tests as failed+      if (+        self._opts.failHookAffectedTests &&+        !after &&+        self._failedBeforeEachHook+      ) {+        // Fail all remaining tests in the suite+        var remainingTests = tests.slice();+        remainingTests.forEach(function (t) {+          if (!t.state) {+            var testError = createHookSkipError(+              self._failedBeforeEachHook.title,+              self._failedBeforeEachHook.error,+            );++            t.state = STATE_FAILED;+            self.failures++;+            self.emit(constants$1.EVENT_TEST_BEGIN, t);+            self.emit(constants$1.EVENT_TEST_FAIL, t, testError);+            self.emit(constants$1.EVENT_TEST_END, t);+          }+        });+        // Clear the stored hook info+        delete self._failedBeforeEachHook;+      } @@ -20133,3 +20250,3 @@   var name = "mocha";-  var version = "11.7.6";+  var version = "11.8.0";   var homepage = "https://mochajs.org/";@@ -20984,2 +21101,16 @@   /**+   * Reports tests as failed when they are skipped due to a hook failure.+   *+   * @public+   * @see [CLI option](../#-fail-hook-affected-tests)+   * @param {boolean} [failHookAffectedTests=true] - Whether to fail tests affected by hook failures.+   * @return {Mocha} this+   * @chainable+   */+  Mocha.prototype.failHookAffectedTests = function (failHookAffectedTests) {+    this.options.failHookAffectedTests = failHookAffectedTests !== false;+    return this;+  };++  /**    * Fails test run if no tests encountered with exit-code 1.@@ -21111,2 +21242,3 @@       dryRun: options.dryRun,+      failHookAffectedTests: options.failHookAffectedTests,       failZero: options.failZero,
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "mocha",-  "version": "11.7.6",+  "version": "11.8.0",   "type": "commonjs",@@ -51,3 +51,2 @@     "docs:build": "eleventy",-    "docs:build-new": "cd docs-next && npm i && npm run build-with-old",     "docs:preview": "http-server docs/_site -o",
rc npm
1.2.8 8y ago incident on record
DELETION ×3BURST ×3
latest 1.2.8 versions 48 maintainers 9
1.2.0
1.2.1
1.2.2
1.2.3
1.2.4
1.2.5
1.2.6
1.2.7
1.2.8
1.2.9
1.3.9
2.3.9
DELETION
1.2.9 published then removed
high · registry-verified · 2021-11-04 · 4y ago
DELETION
1.3.9 published then removed
high · registry-verified · 2021-11-04 · 4y ago
DELETION
2.3.9 published then removed
high · registry-verified · 2021-11-04 · 4y ago
BURST
2 releases in 1m: 0.1.2, 0.1.3
info · registry-verified · 2013-04-27 · 13y ago
BURST
2 releases in 1m: 1.1.3, 1.1.4
info · registry-verified · 2015-11-05 · 10y ago
BURST
3 releases in 0m: 1.2.9, 1.3.9, 2.3.9
info · registry-verified · 2021-11-04 · 4y ago
release diff 1.2.7 → 1.2.8
+0 added · -0 removed · ~1 modified
package.json +2 lines
--- +++ @@ -2,3 +2,3 @@   "name": "rc",-  "version": "1.2.7",+  "version": "1.2.8",   "description": "hardwired configuration loader",@@ -23,3 +23,3 @@   "dependencies": {-    "deep-extend": "^0.5.1",+    "deep-extend": "^0.6.0",     "ini": "~1.3.0",
rimraf npm
6.1.3 6mo ago incident on record
DELETIONBURST ×7
latest 6.1.3 versions 86 maintainers 1
5.0.5
5.0.6
5.0.7
5.0.8
5.0.9
6.0.0
6.0.1
5.0.10
6.1.0
6.1.1
6.1.2
6.1.3
DELETION
2.2.7 published then removed
high · registry-verified · 2014-05-05 · 12y ago
BURST
2 releases in 11m: 1.0.5, 1.0.6
info · registry-verified · 2011-09-03 · 14y ago
BURST
2 releases in 4m: 2.2.3, 2.2.4
info · registry-verified · 2013-11-29 · 12y ago
BURST
2 releases in 24m: 4.0.0, 4.0.1
info · registry-verified · 2023-01-13 · 3y ago
BURST
3 releases in 9m: 4.0.2, 4.0.3, 4.0.4
info · registry-verified · 2023-01-13 · 3y ago
BURST
2 releases in 10m: 5.0.3, 5.0.4
info · registry-verified · 2023-09-25 · 2y ago
BURST
2 releases in 2m: 5.0.9, 6.0.0
info · registry-verified · 2024-07-08 · 2y ago
BURST
2 releases in 24m: 6.1.1, 6.1.2
info · registry-verified · 2025-11-19 · 9mo ago
release diff 6.1.2 → 6.1.3
+0 added · -0 removed · ~45 modified
dist/commonjs/fs.d.ts +9 lines
--- +++ @@ -1,2 +1,3 @@ import fs, { Dirent } from 'fs';+import fsPromises from 'fs/promises'; export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs';@@ -4,11 +5,11 @@ export declare const promises: {-    chmod: typeof fs.promises.chmod;-    mkdir: typeof fs.promises.mkdir;+    chmod: typeof fsPromises.chmod;+    mkdir: typeof fsPromises.mkdir;     readdir: (path: fs.PathLike) => Promise<fs.Dirent<string>[]>;-    rename: typeof fs.promises.rename;-    rm: typeof fs.promises.rm;-    rmdir: typeof fs.promises.rmdir;-    stat: typeof fs.promises.stat;-    lstat: typeof fs.promises.lstat;-    unlink: typeof fs.promises.unlink;+    rename: typeof fsPromises.rename;+    rm: typeof fsPromises.rm;+    rmdir: typeof fsPromises.rmdir;+    stat: typeof fsPromises.stat;+    lstat: typeof fsPromises.lstat;+    unlink: typeof fsPromises.unlink; };
dist/commonjs/index.js +9 lines
--- +++ @@ -45,7 +45,13 @@ exports.nativeSync = wrapSync(rimraf_native_js_1.rimrafNativeSync);-exports.native = Object.assign(wrap(rimraf_native_js_1.rimrafNative), { sync: exports.nativeSync });+exports.native = Object.assign(wrap(rimraf_native_js_1.rimrafNative), {+    sync: exports.nativeSync,+}); exports.manualSync = wrapSync(rimraf_manual_js_1.rimrafManualSync);-exports.manual = Object.assign(wrap(rimraf_manual_js_1.rimrafManual), { sync: exports.manualSync });+exports.manual = Object.assign(wrap(rimraf_manual_js_1.rimrafManual), {+    sync: exports.manualSync,+}); exports.windowsSync = wrapSync(rimraf_windows_js_1.rimrafWindowsSync);-exports.windows = Object.assign(wrap(rimraf_windows_js_1.rimrafWindows), { sync: exports.windowsSync });+exports.windows = Object.assign(wrap(rimraf_windows_js_1.rimrafWindows), {+    sync: exports.windowsSync,+}); exports.posixSync = wrapSync(rimraf_posix_js_1.rimrafPosixSync);
dist/commonjs/opt-arg.js +2 lines
--- +++ @@ -12,3 +12,4 @@     typeOrUndef(o.maxBackoff, 'number') &&-    (typeOrUndef(o.glob, 'boolean') || (o.glob && typeof o.glob === 'object')) &&+    (typeOrUndef(o.glob, 'boolean') ||+        (o.glob && typeof o.glob === 'object')) &&     typeOrUndef(o.filter, 'function');
dist/commonjs/path-arg.js +2 lines
--- +++ @@ -11,3 +11,4 @@                 : `type ${type} ${path}`;-        const msg = 'The "path" argument must be of type string. ' + `Received ${received}`;+        const msg = 'The "path" argument must be of type string. ' ++            `Received ${received}`;         throw Object.assign(new TypeError(msg), {
dist/commonjs/readdir-or-error.d.ts +2 lines
--- +++ @@ -1,3 +1,3 @@-export declare const readdirOrError: (path: string) => Promise<import("fs").Dirent<string>[] | Error>;-export declare const readdirOrErrorSync: (path: string) => import("fs").Dirent<string>[] | Error;+export declare const readdirOrError: (path: string) => Promise<import("node:fs").Dirent<string>[] | Error>;+export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent<string>[] | Error; //# sourceMappingURL=readdir-or-error.d.ts.map
dist/commonjs/rimraf-posix.js +1 lines
--- +++ @@ -21,4 +21,3 @@     opt?.signal?.throwIfAborted();-    return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafPosixDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ??-        true);+    return ((0, ignore_enoent_js_1.ignoreENOENTSync)(() => rimrafPosixDirSync(path, opt, (0, fs_js_1.lstatSync)(path))) ?? true); };
dist/esm/fs.d.ts +9 lines
--- +++ @@ -1,2 +1,3 @@ import fs, { Dirent } from 'fs';+import fsPromises from 'fs/promises'; export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs';@@ -4,11 +5,11 @@ export declare const promises: {-    chmod: typeof fs.promises.chmod;-    mkdir: typeof fs.promises.mkdir;+    chmod: typeof fsPromises.chmod;+    mkdir: typeof fsPromises.mkdir;     readdir: (path: fs.PathLike) => Promise<fs.Dirent<string>[]>;-    rename: typeof fs.promises.rename;-    rm: typeof fs.promises.rm;-    rmdir: typeof fs.promises.rmdir;-    stat: typeof fs.promises.stat;-    lstat: typeof fs.promises.lstat;-    unlink: typeof fs.promises.unlink;+    rename: typeof fsPromises.rename;+    rm: typeof fsPromises.rm;+    rmdir: typeof fsPromises.rmdir;+    stat: typeof fsPromises.stat;+    lstat: typeof fsPromises.lstat;+    unlink: typeof fsPromises.unlink; };
dist/esm/index.js +10 lines
--- +++ @@ -4,3 +4,3 @@ import { rimrafManual, rimrafManualSync } from './rimraf-manual.js';-import { rimrafMoveRemove, rimrafMoveRemoveSync } from './rimraf-move-remove.js';+import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; import { rimrafNative, rimrafNativeSync } from './rimraf-native.js';@@ -37,7 +37,13 @@ export const nativeSync = wrapSync(rimrafNativeSync);-export const native = Object.assign(wrap(rimrafNative), { sync: nativeSync });+export const native = Object.assign(wrap(rimrafNative), {+    sync: nativeSync,+}); export const manualSync = wrapSync(rimrafManualSync);-export const manual = Object.assign(wrap(rimrafManual), { sync: manualSync });+export const manual = Object.assign(wrap(rimrafManual), {+    sync: manualSync,+}); export const windowsSync = wrapSync(rimrafWindowsSync);-export const windows = Object.assign(wrap(rimrafWindows), { sync: windowsSync });+export const windows = Object.assign(wrap(rimrafWindows), {+    sync: windowsSync,+}); export const posixSync = wrapSync(rimrafPosixSync);
dist/esm/opt-arg.js +2 lines
--- +++ @@ -9,3 +9,4 @@     typeOrUndef(o.maxBackoff, 'number') &&-    (typeOrUndef(o.glob, 'boolean') || (o.glob && typeof o.glob === 'object')) &&+    (typeOrUndef(o.glob, 'boolean') ||+        (o.glob && typeof o.glob === 'object')) &&     typeOrUndef(o.filter, 'function');
dist/esm/path-arg.js +2 lines
--- +++ @@ -9,3 +9,4 @@                 : `type ${type} ${path}`;-        const msg = 'The "path" argument must be of type string. ' + `Received ${received}`;+        const msg = 'The "path" argument must be of type string. ' ++            `Received ${received}`;         throw Object.assign(new TypeError(msg), {
dist/esm/readdir-or-error.d.ts +2 lines
--- +++ @@ -1,3 +1,3 @@-export declare const readdirOrError: (path: string) => Promise<import("fs").Dirent<string>[] | Error>;-export declare const readdirOrErrorSync: (path: string) => import("fs").Dirent<string>[] | Error;+export declare const readdirOrError: (path: string) => Promise<import("node:fs").Dirent<string>[] | Error>;+export declare const readdirOrErrorSync: (path: string) => import("node:fs").Dirent<string>[] | Error; //# sourceMappingURL=readdir-or-error.d.ts.map
dist/esm/rimraf-move-remove.js +1 lines
--- +++ @@ -15,3 +15,3 @@ import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js';-import { lstatSync, promises, renameSync, rmdirSync, unlinkSync } from './fs.js';+import { lstatSync, promises, renameSync, rmdirSync, unlinkSync, } from './fs.js'; import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js';
dist/esm/rimraf-posix.js +1 lines
--- +++ @@ -17,4 +17,3 @@     opt?.signal?.throwIfAborted();-    return (ignoreENOENTSync(() => rimrafPosixDirSync(path, opt, lstatSync(path))) ??-        true);+    return (ignoreENOENTSync(() => rimrafPosixDirSync(path, opt, lstatSync(path))) ?? true); };
dist/esm/rimraf-windows.js +1 lines
--- +++ @@ -15,3 +15,3 @@ import { retryBusy, retryBusySync } from './retry-busy.js';-import { rimrafMoveRemove, rimrafMoveRemoveSync } from './rimraf-move-remove.js';+import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js'; import { errorCode } from './error.js';
package.json +4 lines
--- +++ @@ -2,3 +2,3 @@   "name": "rimraf",-  "version": "6.1.2",+  "version": "6.1.3",   "type": "module",@@ -47,16 +47,4 @@   },-  "prettier": {-    "experimentalTernaries": true,-    "semi": false,-    "printWidth": 80,-    "tabWidth": 2,-    "useTabs": false,-    "singleQuote": true,-    "jsxSingleQuote": false,-    "bracketSameLine": true,-    "arrowParens": "avoid",-    "endOfLine": "lf"-  },   "devDependencies": {-    "@types/node": "^24.9.2",+    "@types/node": "^25.2.0",     "mkdirp": "^3.0.1",@@ -74,3 +62,3 @@   "dependencies": {-    "glob": "^13.0.0",+    "glob": "^13.0.3",     "package-json-from-dist": "^1.0.1"@@ -87,6 +75,3 @@   ],-  "module": "./dist/esm/index.js",-  "tap": {-    "coverage-map": "map.js"-  }+  "module": "./dist/esm/index.js" }
ts-jest npm
29.4.12 1mo ago incident on record
DELETIONBURST ×5
latest 29.4.12 versions 218 maintainers 3
29.4.1
29.4.2
29.4.3
29.4.4
29.4.5
29.4.6
29.4.7
29.4.8
29.4.9
29.4.10
29.4.11
29.4.12
DELETION
0.1.12 published then removed
high · registry-verified · 2016-11-03 · 9y ago
BURST
3 releases in 44m: 0.0.1, 0.1.0, 0.1.1
info · registry-verified · 2016-08-31 · 9y ago
BURST
2 releases in 2m: 0.1.2, 0.1.3
info · registry-verified · 2016-08-31 · 9y ago
BURST
2 releases in 47m: 17.0.2, 17.0.3
info · registry-verified · 2016-12-01 · 9y ago
BURST
2 releases in 59m: 19.0.12, 19.0.13
info · registry-verified · 2017-04-26 · 9y ago
BURST
3 releases in 49m: 29.4.7, 29.4.8, 29.4.9
info · registry-verified · 2026-04-01 · 4mo ago
release diff 29.4.11 → 29.4.12
+0 added · -0 removed · ~8 modified
dist/legacy/compiler/ts-compiler.d.ts +7 lines
--- +++ @@ -126,2 +126,9 @@     protected _transpileOutput(fileContent: string, fileName: string): TranspileOutput;+    /**+     * TypeScript 6 reports TS5107 when ts-jest's historical default of+     * `moduleResolution: Node10` is passed to `transpileModule`. The diagnostic+     * is an implementation detail when ts-jest injected that value, but remains+     * actionable when the user selected Node10 themselves.+     */+    private _filterDiagnosticsFromTsJestDefaults;     protected _makeTransformers(customTransformers: TsJestAstTransformer): CustomTransformers;
dist/legacy/compiler/ts-compiler.js +21 lines
--- +++ @@ -378,3 +378,3 @@         if (!(0, transpile_module_1.isModernNodeModuleKind)(this._initialCompilerOptions.module)) {-            return this._ts.transpileModule(fileContent, {+            const result = this._ts.transpileModule(fileContent, {                 fileName,@@ -384,2 +384,4 @@             });+            const diagnostics = this._filterDiagnosticsFromTsJestDefaults(result.diagnostics);+            return diagnostics === result.diagnostics ? result : { ...result, diagnostics };         }@@ -394,2 +396,20 @@         });+    }+    /**+     * TypeScript 6 reports TS5107 when ts-jest's historical default of+     * `moduleResolution: Node10` is passed to `transpileModule`. The diagnostic+     * is an implementation detail when ts-jest injected that value, but remains+     * actionable when the user selected Node10 themselves.+     */+    _filterDiagnosticsFromTsJestDefaults(diagnostics) {+        // `Node10` was exposed as `NodeJs` (with the same value) by older supported TypeScript releases.+        const node10 = this._ts.ModuleResolutionKind.Node10 ?? 2;+        const tsMajor = Number.parseInt(this._ts.version.split('.')[0], 10);+        const hasInjectedNode10 = tsMajor >= 6 &&+            this._initialCompilerOptions.moduleResolution === undefined &&+            this._compilerOptions.moduleResolution === node10;+        if (!hasInjectedNode10 || !diagnostics?.some((diagnostic) => diagnostic.code === 5107)) {+            return diagnostics;+        }+        return diagnostics.filter((diagnostic) => diagnostic.code !== 5107);     }
dist/utils/importer.js +11 lines
--- +++ @@ -29,3 +29,13 @@     typescript(why, which) {-        return this._import(why, which);+        const compilerModule = this._import(why, which);+        const hasRequiredCompilerApi = typeof compilerModule.createLanguageService === 'function' &&+            typeof compilerModule.parseJsonConfigFileContent === 'function' &&+            typeof compilerModule.transpileModule === 'function';+        if (!hasRequiredCompilerApi) {+            throw new Error((0, messages_1.interpolate)("The TypeScript compiler \"{{module}}\" (version {{version}}) does not expose the JavaScript compiler API required by ts-jest. To use TypeScript 7 for project type-checking, install it as \"@typescript/native\" and alias \"@typescript/typescript6\" as \"typescript\" for ts-jest." /* Errors.TypeScriptCompilerApiUnavailable */, {+                module: which,+                version: compilerModule.version ?? 'unknown',+            }));+        }+        return compilerModule;     }
package.json +14 lines
--- +++ @@ -2,3 +2,3 @@   "name": "ts-jest",-  "version": "29.4.11",+  "version": "29.4.12",   "main": "dist/index.js",@@ -59,3 +59,3 @@     "make-error": "^1.3.6",-    "semver": "^7.8.0",+    "semver": "^7.8.5",     "type-fest": "^4.41.0",@@ -96,4 +96,4 @@     "@eslint/compat": "^1.4.1",-    "@eslint/eslintrc": "^3.3.5",-    "@eslint/js": "^9.39.4",+    "@eslint/eslintrc": "^3.3.6",+    "@eslint/js": "^9.39.5",     "@jest/globals": "^30.4.1",@@ -109,3 +109,3 @@     "@types/micromatch": "^4.0.10",-    "@types/node": "20.19.41",+    "@types/node": "20.19.43",     "@types/semver": "^7.7.1",@@ -113,9 +113,9 @@     "@types/yargs-parser": "21.0.3",-    "@typescript-eslint/eslint-plugin": "^8.59.3",-    "@typescript-eslint/parser": "^8.59.3",+    "@typescript-eslint/eslint-plugin": "^8.64.0",+    "@typescript-eslint/parser": "^8.64.0",     "babel-jest": "^30.4.1",     "conventional-changelog-angular": "^8.3.1",-    "conventional-changelog": "^7.2.0",-    "esbuild": "~0.28.0",-    "eslint": "^9.39.4",+    "conventional-changelog": "^7.2.1",+    "esbuild": "~0.28.1",+    "eslint": "^9.39.5",     "eslint-config-prettier": "^10.1.8",@@ -127,3 +127,3 @@     "fast-glob": "^3.3.3",-    "fs-extra": "^11.3.5",+    "fs-extra": "^11.3.6",     "globals": "^16.5.0",@@ -131,5 +131,5 @@     "jest": "^30.4.2",-    "js-yaml": "^4.1.1",+    "js-yaml": "^4.3.0",     "lint-staged": "^15.5.2",-    "memfs": "^4.57.2",+    "memfs": "^4.64.0",     "prettier": "^2.8.8",@@ -138,3 +138,3 @@     "typescript": "~5.9.3",-    "typescript-eslint": "^8.59.3"+    "typescript-eslint": "^8.64.0"   },
tslib npm
2.8.1 1y ago incident on record
DELETION ×2BURST ×3
latest 2.8.1 versions 46 maintainers 7
2.4.1
2.5.0
2.5.1
2.5.2
2.5.3
2.6.0
2.6.1
2.6.2
2.6.3
2.7.0
2.8.0
2.8.1
DELETION
0.0.1 published then removed
high · registry-verified · 2014-12-30 · 11y ago
DELETION
0.0.2 published then removed
high · registry-verified · 2014-12-30 · 11y ago
BURST
2 releases in 13m: 1.13.0, 2.0.0
info · registry-verified · 2020-05-13 · 6y ago
BURST
2 releases in 3m: 1.14.0, 2.0.2
info · registry-verified · 2020-10-06 · 5y ago
BURST
2 releases in 1m: 1.14.1, 2.0.3
info · registry-verified · 2020-10-09 · 5y ago
release diff 2.8.0 → 2.8.1
+0 added · -0 removed · ~4 modified
package.json +1 lines
--- +++ @@ -4,3 +4,3 @@     "homepage": "https://www.typescriptlang.org/",-    "version": "2.8.0",+    "version": "2.8.1",     "license": "0BSD",
tslib.es6.js +10 lines
--- +++ @@ -265,2 +265,11 @@ +var ownKeys = function(o) {+    ownKeys = Object.getOwnPropertyNames || function (o) {+        var ar = [];+        for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;+        return ar;+    };+    return ownKeys(o);+};+ export function __importStar(mod) {@@ -268,3 +277,3 @@     var result = {};-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);+    if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);     __setModuleDefault(result, mod);
tslib.es6.mjs +10 lines
--- +++ @@ -265,2 +265,11 @@ +var ownKeys = function(o) {+  ownKeys = Object.getOwnPropertyNames || function (o) {+    var ar = [];+    for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;+    return ar;+  };+  return ownKeys(o);+};+ export function __importStar(mod) {@@ -268,3 +277,3 @@   var result = {};-  if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);+  if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);   __setModuleDefault(result, mod);
tslib.js +42 lines
--- +++ @@ -314,2 +314,11 @@ +    var ownKeys = function(o) {+        ownKeys = Object.getOwnPropertyNames || function (o) {+            var ar = [];+            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;+            return ar;+        };+        return ownKeys(o);+    };+     __importStar = function (mod) {@@ -317,3 +326,3 @@         var result = {};-        if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);+        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);         __setModuleDefault(result, mod);@@ -442,34 +451,34 @@ 0 && (module.exports = {-    __extends,-    __assign,-    __rest,-    __decorate,-    __param,-    __esDecorate,-    __runInitializers,-    __propKey,-    __setFunctionName,-    __metadata,-    __awaiter,-    __generator,-    __exportStar,-    __createBinding,-    __values,-    __read,-    __spread,-    __spreadArrays,-    __spreadArray,-    __await,-    __asyncGenerator,-    __asyncDelegator,-    __asyncValues,-    __makeTemplateObject,-    __importStar,-    __importDefault,-    __classPrivateFieldGet,-    __classPrivateFieldSet,-    __classPrivateFieldIn,-    __addDisposableResource,-    __disposeResources,-    __rewriteRelativeImportExtension,+    __extends: __extends,+    __assign: __assign,+    __rest: __rest,+    __decorate: __decorate,+    __param: __param,+    __esDecorate: __esDecorate,+    __runInitializers: __runInitializers,+    __propKey: __propKey,+    __setFunctionName: __setFunctionName,+    __metadata: __metadata,+    __awaiter: __awaiter,+    __generator: __generator,+    __exportStar: __exportStar,+    __createBinding: __createBinding,+    __values: __values,+    __read: __read,+    __spread: __spread,+    __spreadArrays: __spreadArrays,+    __spreadArray: __spreadArray,+    __await: __await,+    __asyncGenerator: __asyncGenerator,+    __asyncDelegator: __asyncDelegator,+    __asyncValues: __asyncValues,+    __makeTemplateObject: __makeTemplateObject,+    __importStar: __importStar,+    __importDefault: __importDefault,+    __classPrivateFieldGet: __classPrivateFieldGet,+    __classPrivateFieldSet: __classPrivateFieldSet,+    __classPrivateFieldIn: __classPrivateFieldIn,+    __addDisposableResource: __addDisposableResource,+    __disposeResources: __disposeResources,+    __rewriteRelativeImportExtension: __rewriteRelativeImportExtension, });
ts-node npm
10.9.2 2y ago incident on record
DELETIONBURST ×10
latest 10.9.2 versions 128 maintainers 2
10.3.0
10.3.1
10.4.0
10.5.0
10.6.0
10.7.0
10.8.0
10.8.1
10.8.2
10.9.0
10.9.1
10.9.2
DELETION
8.5.1 published then removed
high · registry-verified · 2019-11-15 · 6y ago
BURST
2 releases in 10m: 0.2.1, 0.2.2
info · registry-verified · 2015-09-22 · 10y ago
BURST
2 releases in 18m: 1.2.0, 1.2.1
info · registry-verified · 2016-07-22 · 10y ago
BURST
3 releases in 21m: 1.5.0, 1.5.1, 1.5.2
info · registry-verified · 2016-10-15 · 9y ago
BURST
2 releases in 48m: 2.1.1, 2.1.2
info · registry-verified · 2017-03-21 · 9y ago
BURST
2 releases in 17m: 3.2.2, 3.3.0
info · registry-verified · 2017-07-24 · 9y ago
BURST
2 releases in 53m: 4.0.0, 4.0.1
info · registry-verified · 2017-12-10 · 8y ago
BURST
2 releases in 18m: 6.2.0, 7.0.0
info · registry-verified · 2018-06-22 · 8y ago
BURST
2 releases in 23m: 8.0.0, 8.0.1
info · registry-verified · 2019-01-22 · 7y ago
BURST
2 releases in 57m: 8.4.0, 8.4.1
info · registry-verified · 2019-09-15 · 6y ago
BURST
2 releases in 7m: 8.5.1, 8.5.2
info · registry-verified · 2019-11-15 · 6y ago
release diff 10.9.1 → 10.9.2
+0 added · -0 removed · ~8 modified
dist/transpilers/swc.js +19 lines
--- +++ @@ -3,2 +3,3 @@ exports.createSwcOptions = exports.targetMapping = exports.create = void 0;+const ts_internals_1 = require("../ts-internals"); function create(createOptions) {@@ -37,5 +38,3 @@         const { fileName } = transpileOptions;-        const swcOptions = fileName.endsWith('.tsx') || fileName.endsWith('.jsx')-            ? tsxOptions-            : nonTsxOptions;+        const swcOptions = fileName.endsWith('.tsx') || fileName.endsWith('.jsx') ? tsxOptions : nonTsxOptions;         const { code, map } = swcInstance.transformSync(input, {@@ -63,3 +62,3 @@ exports.targetMapping.set(/* ts.ScriptTarget.ES2022 */ 9, 'es2022');-exports.targetMapping.set(/* ts.ScriptTarget.ESNext */ 99, 'es2022');+exports.targetMapping.set(/* ts.ScriptTarget.ESNext */ 99, 'esnext'); /**@@ -79,2 +78,3 @@     'es2022',+    'esnext', ];@@ -102,3 +102,3 @@     var _a;-    const { esModuleInterop, sourceMap, importHelpers, experimentalDecorators, emitDecoratorMetadata, target, module, jsx, jsxFactory, jsxFragmentFactory, strict, alwaysStrict, noImplicitUseStrict, } = compilerOptions;+    const { esModuleInterop, sourceMap, importHelpers, experimentalDecorators, emitDecoratorMetadata, target, module, jsx, jsxFactory, jsxFragmentFactory, strict, alwaysStrict, noImplicitUseStrict, jsxImportSource, } = compilerOptions;     let swcTarget = (_a = exports.targetMapping.get(target)) !== null && _a !== void 0 ? _a : 'es3';@@ -147,6 +147,5 @@         : true;-    const jsxRuntime = jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev-        ? 'automatic'-        : undefined;+    const jsxRuntime = jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev ? 'automatic' : undefined;     const jsxDevelopment = jsx === JsxEmit.ReactJSXDev ? true : undefined;+    const useDefineForClassFields = (0, ts_internals_1.getUseDefineForClassFields)(compilerOptions);     const nonTsxOptions = createVariant(false);@@ -160,7 +159,11 @@                 ? {-                    noInterop: !esModuleInterop,                     type: moduleType,-                    strictMode,-                    // For NodeNext and Node12, emit as CJS but do not transform dynamic imports-                    ignoreDynamic: nodeModuleEmitKind === 'nodecjs',+                    ...(moduleType === 'amd' || moduleType === 'commonjs' || moduleType === 'umd'+                        ? {+                            noInterop: !esModuleInterop,+                            strictMode,+                            // For NodeNext and Node12, emit as CJS but do not transform dynamic imports+                            ignoreDynamic: nodeModuleEmitKind === 'nodecjs',+                        }+                        : {}),                 }@@ -188,3 +191,5 @@                         runtime: jsxRuntime,+                        importSource: jsxImportSource,                     },+                    useDefineForClassFields,                 },@@ -192,3 +197,4 @@                 experimental: {-                    keepImportAssertions: true,+                    keepImportAttributes: true,+                    emitAssertForImportAttributes: true,                 },
dist/ts-internals.d.ts +6 lines
--- +++ @@ -1 +1,6 @@-export {};+import type * as _ts from 'typescript';+export declare function getUseDefineForClassFields(compilerOptions: _ts.CompilerOptions): boolean;+export declare function getEmitScriptTarget(compilerOptions: {+    module?: _ts.CompilerOptions['module'];+    target?: _ts.CompilerOptions['target'];+}): _ts.ScriptTarget;
dist/ts-internals.js +24 lines
--- +++ @@ -2,3 +2,3 @@ Object.defineProperty(exports, "__esModule", { value: true });-exports.getPatternFromSpec = exports.createTsInternals = void 0;+exports.getEmitScriptTarget = exports.getUseDefineForClassFields = exports.getPatternFromSpec = exports.createTsInternals = void 0; const path_1 = require("path");@@ -39,2 +39,3 @@         // If the path isn't a rooted or relative path, resolve like a module+        const tsGte5_3_0 = (0, util_1.versionGteLt)(ts.version, '5.3.0');         const resolved = ts.nodeModuleNameResolver(extendedConfig, combinePaths(basePath, 'tsconfig.json'), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, @@ -42,3 +43,4 @@         /*projectRefs*/ undefined, -        /*lookupConfig*/ true);+        /*conditionsOrIsConfigLookup*/ tsGte5_3_0 ? undefined : true, +        /*isConfigLookup*/ tsGte5_3_0 ? true : undefined);         if (resolved.resolvedModule) {@@ -298,2 +300,22 @@ }+const ts_ScriptTarget_ES5 = 1;+const ts_ScriptTarget_ES2022 = 9;+const ts_ScriptTarget_ESNext = 99;+const ts_ModuleKind_Node16 = 100;+const ts_ModuleKind_NodeNext = 199;+// https://github.com/microsoft/TypeScript/blob/fc418a2e611c88cf9afa0115ff73490b2397d311/src/compiler/utilities.ts#L8761+function getUseDefineForClassFields(compilerOptions) {+    return compilerOptions.useDefineForClassFields === undefined+        ? getEmitScriptTarget(compilerOptions) >= ts_ScriptTarget_ES2022+        : compilerOptions.useDefineForClassFields;+}+exports.getUseDefineForClassFields = getUseDefineForClassFields;+// https://github.com/microsoft/TypeScript/blob/fc418a2e611c88cf9afa0115ff73490b2397d311/src/compiler/utilities.ts#L8556+function getEmitScriptTarget(compilerOptions) {+    var _a;+    return ((_a = compilerOptions.target) !== null && _a !== void 0 ? _a : ((compilerOptions.module === ts_ModuleKind_Node16 && ts_ScriptTarget_ES2022) ||+        (compilerOptions.module === ts_ModuleKind_NodeNext && ts_ScriptTarget_ESNext) ||+        ts_ScriptTarget_ES5));+}+exports.getEmitScriptTarget = getEmitScriptTarget; //# sourceMappingURL=ts-internals.js.map
package.json +3 lines
--- +++ @@ -2,3 +2,3 @@   "name": "ts-node",-  "version": "10.9.1",+  "version": "10.9.2",   "description": "TypeScript execution environment and REPL for node.js, with source map support",@@ -114,4 +114,4 @@     "@microsoft/api-extractor": "^7.19.4",-    "@swc/core": ">=1.2.205",-    "@swc/wasm": ">=1.2.205",+    "@swc/core": "^1.3.100",+    "@swc/wasm": "^1.3.100",     "@types/diff": "^4.0.2",
tsconfig.schemastore-schema.json +121 lines
--- +++ @@ -2,2 +2,3 @@   "$schema": "http://json-schema.org/draft-04/schema#",+  "allowTrailingCommas": true,   "allOf": [@@ -94,4 +95,16 @@         "extends": {-          "description": "Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later.",-          "type": "string"+          "description": "Path to base configuration file to inherit from (requires TypeScript version 2.1 or later), or array of base files, with the rightmost files having the greater priority (requires TypeScript version 5.0 or later).",+          "oneOf": [+            {+              "default": "",+              "type": "string"+            },+            {+              "default": [],+              "items": {+                "type": "string"+              },+              "type": "array"+            }+          ]         }@@ -200,2 +213,12 @@           "properties": {+            "allowArbitraryExtensions": {+              "description": "Enable importing files with any extension, provided a declaration file is present.",+              "type": "boolean",+              "markdownDescription": "Enable importing files with any extension, provided a declaration file is present.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowImportingTsExtensions"+            },+            "allowImportingTsExtensions": {+              "description": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.",+              "type": "boolean",+              "markdownDescription": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowImportingTsExtensions"+            },             "charset": {@@ -210,2 +233,11 @@               "markdownDescription": "Enable constraints that allow a TypeScript project to be used with project references.\n\nSee more: https://www.typescriptlang.org/tsconfig#composite"+            },+            "customConditions": {+              "description": "Conditions to set in addition to the resolver-specific defaults when resolving imports.",+              "type": "array",+              "uniqueItems": true,+              "items": {+                "type": "string"+              },+              "markdownDescription": "Conditions to set in addition to the resolver-specific defaults when resolving imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#customConditions"             },@@ -263,5 +295,9 @@             "tsBuildInfoFile": {+              "$comment": "The value of 'null' is UNDOCUMENTED.",               "description": "Specify the folder for .tsbuildinfo incremental compilation files.",               "default": ".tsbuildinfo",-              "type": "string",+              "type": [+                "string",+                "null"+              ],               "markdownDescription": "Specify the folder for .tsbuildinfo incremental compilation files.\n\nSee more: https://www.typescriptlang.org/tsconfig#tsBuildInfoFile"@@ -346,3 +382,3 @@                 {-                  "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[AaUu][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Ee][Ss]([356]|20(1[567]|2[02])|[Nn][Ee][Xx][Tt])|[Nn][Oo][dD][Ee]16|[Nn][Oo][Dd][Ed][Nn][Ee][Xx][Tt]|[Nn][Oo][Nn][Ee])$"+                  "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[AaUu][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Ee][Ss]([356]|20(1[567]|2[02])|[Nn][Ee][Xx][Tt])|[Nn][Oo][dD][Ee]16|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Nn][Oo][Nn][Ee])$"                 }@@ -359,4 +395,14 @@                     "Node",+                    "Node10",                     "Node16",-                    "NodeNext"+                    "NodeNext",+                    "Bundler"+                  ],+                  "markdownEnumDescriptions": [+                    "It’s recommended to use `\"Node16\"` instead",+                    "Deprecated, use `\"Node10\"` in TypeScript 5.0+ instead",+                    "It’s recommended to use `\"Node16\"` instead",+                    "This is the recommended setting for libraries and Node.js applications",+                    "This is the recommended setting for libraries and Node.js applications",+                    "This is the recommended setting in TypeScript 5.0+ for applications that use a bundler"                   ]@@ -364,6 +410,5 @@                 {-                  "pattern": "^(([Nn]ode)|([Nn]ode16)|([Nn]ode[Nn]ext)|([Cc]lassic))$"+                  "pattern": "^(([Nn]ode)|([Nn]ode1[06])|([Nn]ode[Nn]ext)|([Cc]lassic)|([Bb]undler))$"                 }               ],-              "default": "classic",               "markdownDescription": "Specify how TypeScript looks up a file from a given module specifier.\n\nSee more: https://www.typescriptlang.org/tsconfig#moduleResolution"@@ -558,2 +603,3 @@                     "ES2022",+                    "ES2023",                     "ESNext"@@ -562,3 +608,3 @@                 {-                  "pattern": "^([Ee][Ss]([356]|(20(1[56789]|2[012]))|[Nn][Ee][Xx][Tt]))$"+                  "pattern": "^([Ee][Ss]([356]|(20(1[56789]|2[0123]))|[Nn][Ee][Xx][Tt]))$"                 }@@ -802,2 +848,3 @@                       "ES2019.Array",+                      "ES2019.Intl",                       "ES2019.Object",@@ -828,2 +875,4 @@                       "ES2020.Intl",+                      "ES2020.Date",+                      "ES2020.Number",                       "ES2021.Promise",@@ -832,3 +881,3 @@                       "ESNext.WeakRef",-                      "es2021.intl",+                      "ES2021.Intl",                       "ES2022",@@ -838,3 +887,13 @@                       "ES2022.Object",-                      "ES2022.String"+                      "ES2022.String",+                      "ES2022.SharedMemory",+                      "ES2022.RegExp",+                      "ES2023",+                      "ES2023.Array",+                      "Decorators",+                      "Decorators.Legacy",+                      "ES2017.Date",+                      "ES2023.Collection",+                      "ESNext.Decorators",+                      "ESNext.Disposable"                     ]@@ -845,18 +904,18 @@                   {-                    "pattern": "^[Ee][Ss]2015(\\.([Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Rr][Ee]|[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Pp][Rr][Oo][Xx][Yy]|[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"-                  },-                  {-                    "pattern": "^[Ee][Ss]2016(\\.[Aa][Rr][Rr][Aa][Yy].[Ii][Nn][Cc][Ll][Uu][Dd][Ee])?$"-                  },-                  {-                    "pattern": "^[Ee][Ss]2017(\\.([Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]))?$"-                  },-                  {-                    "pattern": "^[Ee][Ss]2018(\\.([Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"-                  },-                  {-                    "pattern": "^[Ee][Ss]2019(\\.([Aa][Rr][Rr][Aa][Yy]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"-                  },-                  {-                    "pattern": "^[Ee][Ss]2020(\\.([Bb][Ii][Gg][Ii][Nn][Tt]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]))?$"+                    "pattern": "^[Ee][Ss]2015(\\.([Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Rr][Ee]|[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Pp][Rr][Oo][Xx][Yy]|[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2016(\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee])?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2017(\\.([Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Aa][Tt][Ee]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2018(\\.([Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2019(\\.([Aa][Rr][Rr][Aa][Yy]|[Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2020(\\.([Bb][Ii][Gg][Ii][Nn][Tt]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ii][Nn][Tt][Ll]|[Dd][Aa][Tt][Ee]|[Nn][Uu][Mm][Bb][Ee][Rr]))?$"                   },@@ -866,6 +925,9 @@                   {-                    "pattern": "^[Ee][Ss]2022(\\.([Aa][Rr][Rr][Aa][Yy]|[Ee][Rr][Rr][Oo][Rr]|[Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]))?$"-                  },-                  {-                    "pattern": "^[Ee][Ss][Nn][Ee][Xx][Tt](\\.([Aa][Rr][Rr][Aa][Yy]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Bb][Ii][Gg][Ii][Nn][Tt]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]|[Ww][Ee][Aa][Kk][Rr][Ee][Ff]))?$"+                    "pattern": "^[Ee][Ss]2022(\\.([Aa][Rr][Rr][Aa][Yy]|[Ee][Rr][Rr][Oo][Rr]|[Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss]2023(\\.([Aa][Rr][Rr][Aa][Yy]|[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]))?$"+                  },+                  {+                    "pattern": "^[Ee][Ss][Nn][Ee][Xx][Tt](\\.([Aa][Rr][Rr][Aa][Yy]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Bb][Ii][Gg][Ii][Nn][Tt]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]|[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]))?$"                   },@@ -878,3 +940,6 @@                   {-                    "pattern": "^[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr](\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss])?$"+                    "pattern": "^[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr](\\.([Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]))?$"+                  },+                  {+                    "pattern": "^[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss](\\.([Ll][Ee][Gg][Aa][Cc][Yy]))?$"                   }@@ -883,2 +948,10 @@               "markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee more: https://www.typescriptlang.org/tsconfig#lib"+            },+            "moduleDetection": {+              "description": "Specify how TypeScript determine a file as module.",+              "enum": [+                "auto",+                "legacy",+                "force"+              ]             },@@ -988,2 +1061,14 @@             },+            "resolvePackageJsonExports": {+              "description": "Use the package.json 'exports' field when resolving package imports.",+              "type": "boolean",+              "default": false,+              "markdownDescription": "Use the package.json 'exports' field when resolving package imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#resolvePackageJsonExports"+            },+            "resolvePackageJsonImports": {+              "description": "Use the package.json 'imports' field when resolving imports.",+              "type": "boolean",+              "default": false,+              "markdownDescription": "Use the package.json 'imports' field when resolving imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#resolvePackageJsonImports"+            },             "assumeChangesOnlyAffectDirectDependencies": {@@ -1011,2 +1096,7 @@               "markdownDescription": "Opt a project out of multi-project reference checking when editing.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSolutionSearching"+            },+            "verbatimModuleSyntax": {+              "description": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.",+              "type": "boolean",+              "markdownDescription": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.\n\nSee more: https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax"             }
typescript npm
7.0.2 1mo ago incident on record
critical-tier DELETIONBURST ×4
latest 7.0.2 versions 3802 maintainers 7 critical-tier (snapshotted)
5.5.4
5.6.2
5.6.3
5.7.2
5.7.3
5.8.2
5.8.3
5.9.2
5.9.3
6.0.2
6.0.3
7.0.2
DELETION
1.9.0 published then removed
high · registry-verified · 2016-04-28 · 10y ago
BURST
2 releases in 15m: 1.8.6, 1.8.7
info · registry-verified · 2016-03-02 · 10y ago
BURST
5 releases in 8m: 3.1.7, 3.7.6, 3.9.8, 4.0.6, 4.1.4
info · registry-verified · 2021-02-09 · 5y ago
BURST
5 releases in 3m: 3.1.8, 3.7.7, 3.9.9, 4.0.7, 4.1.5
info · registry-verified · 2021-02-10 · 5y ago
BURST
4 releases in 53m: 3.9.10, 4.0.8, 4.3.3, 4.1.6
info · registry-verified · 2021-06-16 · 5y ago
release diff 6.0.3 → 7.0.2
+412 added · -136 removed · ~4 modified
new files touching dangerous APIs: dist/api/async/client.js, dist/api/syncChannel.js, dist/ast/scanner.js, vendor/vscode-jsonrpc/lib/browser/ril.js, vendor/vscode-jsonrpc/lib/node/main.d.ts, vendor/vscode-jsonrpc/lib/node/main.js
+202 more files not shown
dist/api/async/client.js +211 lines · 5 flagged
--- +++ @@ -0,0 +1,211 @@+import { createMessageConnection, RequestType, SocketMessageReader, SocketMessageWriter, StreamMessageReader, StreamMessageWriter, } from "#vscode-jsonrpc/node";+import { fsCallbackNames, } from "../fs.js";+import { isSpawnOptions, resolveExePath, } from "../options.js";+import { combineTimingInfo, disabledServerTimingInfo, disabledTimingInfo, TimingCollector, } from "../timing.js";+/**+ * Client handles communication with the TypeScript API server+ * over STDIO (spawned process) or a Unix domain socket using JSON-RPC.+ */+export class Client {+    socket;+    process;+    connection;+    options;+    connected = false;+    timing;+    constructor(options) {+        this.options = options;+        if (isSpawnOptions(options) && options.collectTiming) {+            this.timing = new TimingCollector();+        }+    }+    async connect() {+        if (this.connected)+            return;+        if (isSpawnOptions(this.options)) {+            await this.connectViaSpawn(this.options);+        }+        else {+            await this.connectViaSocket(this.options);+        }+    }+    async connectViaSpawn(options) {+        const { spawn } = await import("node:child_process");+        return new Promise((resolve, reject) => {+            const args = [+                "--api",+                "--async",+                "--cwd",+                options.cwd ?? process.cwd(),+            ];+            if (options.collectTiming) {+                args.push("--timing");+            }+            // Enable virtual FS callbacks for each provided FS function+            const enabledCallbacks = [];+            if (options.fs) {+                for (const name of fsCallbackNames) {+                    if (options.fs[name]) {+                        enabledCallbacks.push(name);+                    }+                }+            }+            if (enabledCallbacks.length > 0) {+                args.push(`--callbacks=${enabledCallbacks.join(",")}`);+            }+            this.process = spawn(resolveExePath(options), args, {+                stdio: ["pipe", "pipe", "inherit"],+            });+            this.process.once("error", error => {+                reject(new Error(`Failed to start tsgo process: ${error.message}`));+            });+            this.process.once("spawn", () => {+                this.connected = true;+                resolve();+            });+            const reader = new StreamMessageReader(this.process.stdout);+            const writer = new StreamMessageWriter(this.process.stdin);+            this.connection = createMessageConnection(reader, writer);+            this.registerFSCallbacks(this.connection, options.fs);+            this.connection.listen();+        });+    }+    async connectViaSocket(options) {+        const { createConnection } = await import("node:net");+        return new Promise((resolve, reject) => {+            this.socket = createConnection(options.pipe, () => {+                const reader = new SocketMessageReader(this.socket);+                const writer = new SocketMessageWriter(this.socket);+                this.connection = createMessageConnection(reader, writer);+                this.connection.listen();+                this.connected = true;+                resolve();+            });+            this.socket.once("error", error => {+                reject(new Error(`Socket error: ${error.message}`));+            });+        });+    }+    registerFSCallbacks(connection, fs) {+        if (!fs)+            return;+        for (const name of fsCallbackNames) {+            const callback = fs[name];+            if (callback) {+                const requestType = new RequestType(name);+                connection.onRequest(requestType, (arg) => {+                    const result = callback(arg);+                    if (name === "readFile") {+                        // readFile has 3 returns: string (content), null (not found), undefined (fall back).+                        // JSON-RPC can't distinguish null from undefined, so wrap in object.+                        if (result === undefined)+                            return null;+                        return { content: result };+                    }+                    return result ?? null;+                });+            }+        }+    }+    async apiRequest(method, params) {+        if (!this.connected) {+            await this.connect();+        }+        if (!this.connection) {+            throw new Error("Connection not established");+        }+        const requestType = new RequestType(method);+        if (!this.timing) {+            return this.connection.sendRequest(requestType, params);+        }+        // Round-trip latency is measured here; byte counts approximate the wire+        // payload via the serialized JSON. Server-side processing time is not+        // carried on the response; it is retrieved separately (via a+        // getServerTiming request) and folded in by getTimingInfo().+        const bytesSent = params === undefined ? 0 : Buffer.byteLength(JSON.stringify(params), "utf-8");+        const start = performance.now();+        const result = await this.connection.sendRequest(requestType, params);+        const roundTripMs = performance.now() - start;+        this.timing.record({+            method,+            roundTripMs,+            bytesSent,+            bytesReceived: result === undefined || result === null+                ? 0+                : Buffer.byteLength(JSON.stringify(result), "utf-8"),+        });+        return result;+    }+    async apiRequestBinary(method, params) {+        const response = await this.apiRequest(method, params);+        if (!response)+            return undefined;+        const buffer = Buffer.from(response.data, "base64");+        return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);+    }+    /**+     * Returns the timing collector that per-node materialization is reported+     * into, or undefined when timing collection is disabled. The returned+     * collector is the same one folded into {@link getTimingInfo}, so+     * materialization totals surface alongside request timings.+     */+    getTimingCollector() {+        return this.timing;+    }+    /**+     * Returns a combined timing snapshot: client-measured round-trip and byte+     * counts folded together with the server's own per-request processing time+     * (fetched via a getServerTiming request) and estimated transport overhead.+     */+    async getTimingInfo() {+        if (!this.timing) {+            return disabledTimingInfo();+        }+        const local = this.timing.getInfo();+        // No requests have been sent yet: nothing to fetch from the server.+        if (!this.connected || !this.connection) {+            return local;+        }+        return combineTimingInfo(local, await this.fetchServerTiming());+    }+    async resetTimingInfo() {+        if (!this.timing)+            return;+        this.timing.reset();+        if (this.connected && this.connection) {+            // Keep the server's collection in sync so combined totals stay meaningful.+            const requestType = new RequestType("resetServerTiming");+            await this.connection.sendRequest(requestType, undefined);+        }+    }+    async fetchServerTiming() {+        if (!this.connection) {+            return disabledServerTimingInfo();+        }+        // Fetch the server's own timing collection via a dedicated request. This+        // bypasses the client-side collector so the query does not pollute it.+        const requestType = new RequestType("getServerTiming");+        return this.connection.sendRequest(requestType, undefined);+    }+    async close() {+        if (this.connection) {+            this.connection.dispose();+            this.connection = undefined;+        }+        if (this.socket) {+            this.socket.destroy();+            this.socket = undefined;+        }+        if (this.process) {+            // Close stdin to unblock the server's read loop, allowing it to exit cleanly.+            // The server is blocked on stdin.Read(), so just sending SIGTERM would deadlock:+            // - Node won't exit while child is alive+            // - Child can't process SIGTERM while blocked on read+            // - Read won't error until stdin is closed+            this.process.stdin?.end();+            this.process = undefined;+        }+        this.connected = false;+    }+}+//# sourceMappingURL=client.js.map
dist/api/syncChannel.js +508 lines · 3 flagged
--- +++ @@ -0,0 +1,508 @@+/**+ * Pure JS replacement for @typescript/libsyncrpc.+ *+ * Spawns a child process and communicates with it synchronously over+ * stdin/stdout pipes using the same MessagePack-based tuple protocol:+ *   [MessageType (u8), method (bin), payload (bin)]+ *+ * Synchronous I/O is achieved by calling fs.readSync / fs.writeSync+ * directly on the pipe file descriptors obtained from the spawned+ * ChildProcess.+ */+import { spawn, } from "node:child_process";+import { closeSync, openSync, readSync, writeSync, } from "node:fs";+import { binHeaderSize, MSGPACK_BIN16, MSGPACK_BIN32, MSGPACK_BIN8, MSGPACK_FIXARRAY3, MSGPACK_UINT8, writeBinHeader, } from "./node/msgpack.js";+// ── MessageType constants ────────────────────────────────────────────+// Sent by channel (parent → child)+const MSG_REQUEST = 1;+const MSG_CALL_RESPONSE = 2;+const MSG_CALL_ERROR = 3;+// Sent by child (child → parent)+const MSG_RESPONSE = 4;+const MSG_ERROR = 5;+const MSG_CALL = 6;+// Pre-allocated buffer used by Atomics.wait for tiny sleeps when a+// non-blocking fd returns EAGAIN.+const sleepBuf = new Int32Array(new SharedArrayBuffer(4));+// Shared empty buffer – avoids allocating Buffer.alloc(0) on every+// zero-length bin field.+const EMPTY_BUF = Buffer.alloc(0);+// ── Global cleanup tracking ─────────────────────────────────────────+// Track all live child processes so they can be killed on process exit.+// This mimics the auto-cleanup behavior of the native libsyncrpc module,+// whose Rust/C++ destructors would kill children automatically.+const liveChildren = new Set();+process.on("exit", () => {+    for (const child of liveChildren) {+        try {+            child.kill();+        }+        catch {+            // swallow – process may already be dead+        }+    }+    liveChildren.clear();+});+/**+ * SyncRpcChannel – drop-in replacement for the native libsyncrpc class.+ *+ * API surface intentionally matches the original:+ *   - constructor(exe, args)+ *   - requestSync(method, payload): string+ *   - requestBinarySync(method, payload): Uint8Array+ *   - registerCallback(name, cb)+ *   - close()+ *+ * The protocol is unversioned; both sides (this JS channel and the Go+ * child process) must be built from the same tree.+ *+ * This class is **not** thread-safe. All calls must originate from a+ * single thread — do not share an instance across worker threads.+ */+export class SyncRpcChannel {+    child;+    readFd;+    writeFd;+    pipeFd;+    callbacks = new Map();+    methodBufCache = new Map();+    // When true, the payload byte lengths of each request/response are recorded+    // and exposed via the `last*` fields below. These count only the JSON/binary+    // payload bytes, not the MessagePack tuple framing (message type, method+    // name, and length headers).+    collectTiming;+    // Per-request payload byte measurements for the most recently completed+    // request. Only meaningful when `collectTiming` is true. Callers read these+    // immediately after a request returns (the channel is strictly serial).+    lastBytesSent = 0;+    lastBytesReceived = 0;+    _msgType = 0;+    _msgName = EMPTY_BUF;+    _msgPayload = EMPTY_BUF;+    headerBuf = Buffer.allocUnsafe(4);+    // Read-ahead buffer – reduces readSync syscalls by buffering data from the pipe.+    readBuf = Buffer.allocUnsafe(65536);+    readBufPos = 0;+    readBufLen = 0;+    // Write buffer – assembles entire tuples for a single writeSync.+    writeBuf = Buffer.allocUnsafe(65536);+    constructor(exe, args, collectTiming = false) {+        this.collectTiming = collectTiming;+        const isWindows = process.platform === "win32";+        if (isWindows) {+            // On Windows, libuv pipe handles don't expose POSIX fds, so+            // readSync/writeSync can't be used on stdio pipes. Instead,+            // we create a Windows named pipe path, pass it to the child+            // via --pipe, and open it with fs.openSync which returns a+            // real C-runtime fd backed by a proper HANDLE.+            const pipePath = `\\\\.\\pipe\\tsgo-sync-${process.pid}-${Date.now()}`;+            this.child = spawn(exe, [...args, "--pipe", pipePath], {+                stdio: ["ignore", "ignore", "inherit"],+            });+            // Retry openSync until the child creates the named pipe.+            let fd;+            for (let i = 0; i < 500; i++) {+                try {+                    fd = openSync(pipePath, "r+");+                    break;+                }+                catch {+                    if (this.child.exitCode !== null) {+                        throw new Error(`Child process exited with code ${this.child.exitCode} before pipe was ready`);+                    }+                    Atomics.wait(sleepBuf, 0, 0, 10);+                }+            }+            if (fd === undefined) {+                this.child.kill();+                throw new Error("SyncRpcChannel: timed out connecting to named pipe");+            }+            this.readFd = fd;+            this.writeFd = fd;+            this.pipeFd = fd;+        }+        else {+            // POSIX: use stdio pipe file descriptors directly.+            this.child = spawn(exe, args, {+                stdio: ["pipe", "pipe", "inherit"],+            });+            const stdout = this.child.stdout;+            const stdin = this.child.stdin;+            this.readFd = stdout._handle.fd;+            this.writeFd = stdin._handle.fd;+            if (typeof this.readFd !== "number" || this.readFd < 0 || typeof this.writeFd !== "number" || this.writeFd < 0) {+                stdout.destroy();+                stdin.destroy();+                this.child.kill();+                throw new Error("SyncRpcChannel: could not obtain pipe file descriptors.");+            }+            // Set the pipe handles to blocking mode. Under node --test's+            // process isolation, pipes are created in non-blocking mode+            // (for the IPC channel). This causes readSync/writeSync to get+            // EAGAIN, requiring costly 1ms sleeps per retry. Setting+            // blocking mode ensures readSync blocks properly until data+            // arrives, matching the behavior of the native libsyncrpc.+            stdout._handle.setBlocking?.(true);+            stdin._handle.setBlocking?.(true);+            // Prevent Node's event-loop from reading stdout or keeping the+            // process alive – we will use fs.readSync exclusively.+            stdout.pause();+            stdout.unref();+            stdin.unref();+        }+        // Track for auto-cleanup on process exit.+        liveChildren.add(this.child);+        this.child.unref();+    }+    // ── Public API ──────────────────────────────────────────────────+    /**+     * Send a request and synchronously wait for the response (string).+     * Handles Call (callback) messages from the child inline.+     */+    requestSync(method, payload) {+        this.ensureOpen();+        const result = this.requestBytesSync(method, payload);+        return result.toString("utf-8");+    }+    /**+     * Send a request and synchronously wait for the response (binary).+     * Handles Call (callback) messages from the child inline.+     */+    requestBinarySync(method, payload) {+        this.ensureOpen();+        return this.requestBytesSync(method, payload);+    }+    /** Register a string→string callback that the child may invoke. */+    registerCallback(name, callback) {+        this.callbacks.set(name, callback);+    }+    /** Kill the child process and release resources. */+    close() {+        try {+            liveChildren.delete(this.child);+            if (this.pipeFd !== undefined) {+                closeSync(this.pipeFd);+                this.pipeFd = undefined;+            }+            // Destroy the stdio streams so that their pipe handles are closed+            // and no longer prevent the event loop from draining.+            this.child.stdout?.destroy();+            this.child.stdin?.destroy();+            this.child.kill();+            this.readFd = -1;+            this.writeFd = -1;+        }+        catch {+            // swallow – process may already be dead+        }+    }+    // ── Core request loop ───────────────────────────────────────────+    ensureOpen() {+        if (this.readFd < 0) {+            throw new Error("SyncRpcChannel is closed");+        }+    }+    getMethodBuf(method) {+        let buf = this.methodBufCache.get(method);+        if (buf === undefined) {+            buf = Buffer.from(method, "utf-8");+            this.methodBufCache.set(method, buf);+        }+        return buf;+    }+    requestBytesSync(method, payload) {+        const methodBuf = this.getMethodBuf(method);+        if (this.collectTiming) {+            this.lastBytesSent = typeof payload === "string"+                ? Buffer.byteLength(payload, "utf-8")+                : payload.length;+            this.lastBytesReceived = 0;+        }+        this.writeTuple(MSG_REQUEST, methodBuf, payload);+        for (;;) {+            this.readTuple();+            switch (this._msgType) {+                case MSG_RESPONSE: {+                    // Compare raw bytes instead of decoding to string.+                    if (!methodBuf.equals(this._msgName)) {+                        throw new Error(`name mismatch for response: expected \`${method}\`, got \`${this._msgName.toString("utf-8")}\``);+                    }+                    if (this.collectTiming) {+                        this.lastBytesReceived = this._msgPayload.length;+                    }+                    return this._msgPayload;+                }+                case MSG_ERROR: {+                    if (methodBuf.equals(this._msgName)) {+                        throw new Error(this._msgPayload.toString("utf-8"));+                    }+                    throw new Error(`name mismatch for response: expected \`${method}\`, got \`${this._msgName.toString("utf-8")}\``);+                }+                case MSG_CALL: {+                    this.handleCall(this._msgName.toString("utf-8"), this._msgPayload);+                    break;+                }+                default:+                    throw new Error(`Invalid message type from child: ${this._msgType}`);+            }
… 261 more lines (truncated)
dist/ast/scanner.js +2230 lines · 2 flagged
--- +++ @@ -0,0 +1,2230 @@+import { CharacterCodes } from "#enums/characterCodes";+import { CommentDirectiveType } from "#enums/commentDirectiveType";+import { LanguageVariant } from "#enums/languageVariant";+import { RegularExpressionFlags } from "#enums/regularExpressionFlags";+import { ScriptTarget } from "#enums/scriptTarget";+import { SyntaxKind } from "#enums/syntaxKind";+import { TokenFlags } from "#enums/tokenFlags";+// Internal-only, not exported+const EscapeSequenceScanningFlags = {+    String: 1 << 0,+    ReportErrors: 1 << 1,+    RegularExpression: 1 << 2,+    AnnexB: 1 << 3,+    AnyUnicodeMode: 1 << 4,+    AtomEscape: 1 << 5,+    ReportInvalidEscapeErrors: (1 << 2) | (1 << 1),+    AllowExtendedUnicodeEscape: (1 << 0) | (1 << 4),+};+export function tokenIsIdentifierOrKeyword(token) {+    return token >= SyntaxKind.Identifier;+}+export function tokenIsIdentifierOrKeywordOrGreaterThan(token) {+    return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token);+}+export const textToKeywordObj = {+    abstract: SyntaxKind.AbstractKeyword,+    accessor: SyntaxKind.AccessorKeyword,+    any: SyntaxKind.AnyKeyword,+    as: SyntaxKind.AsKeyword,+    asserts: SyntaxKind.AssertsKeyword,+    assert: SyntaxKind.AssertKeyword,+    bigint: SyntaxKind.BigIntKeyword,+    boolean: SyntaxKind.BooleanKeyword,+    break: SyntaxKind.BreakKeyword,+    case: SyntaxKind.CaseKeyword,+    catch: SyntaxKind.CatchKeyword,+    class: SyntaxKind.ClassKeyword,+    continue: SyntaxKind.ContinueKeyword,+    const: SyntaxKind.ConstKeyword,+    ["" + "constructor"]: SyntaxKind.ConstructorKeyword,+    debugger: SyntaxKind.DebuggerKeyword,+    declare: SyntaxKind.DeclareKeyword,+    default: SyntaxKind.DefaultKeyword,+    defer: SyntaxKind.DeferKeyword,+    delete: SyntaxKind.DeleteKeyword,+    do: SyntaxKind.DoKeyword,+    else: SyntaxKind.ElseKeyword,+    enum: SyntaxKind.EnumKeyword,+    export: SyntaxKind.ExportKeyword,+    extends: SyntaxKind.ExtendsKeyword,+    false: SyntaxKind.FalseKeyword,+    finally: SyntaxKind.FinallyKeyword,+    for: SyntaxKind.ForKeyword,+    from: SyntaxKind.FromKeyword,+    function: SyntaxKind.FunctionKeyword,+    get: SyntaxKind.GetKeyword,+    if: SyntaxKind.IfKeyword,+    implements: SyntaxKind.ImplementsKeyword,+    import: SyntaxKind.ImportKeyword,+    in: SyntaxKind.InKeyword,+    infer: SyntaxKind.InferKeyword,+    instanceof: SyntaxKind.InstanceOfKeyword,+    interface: SyntaxKind.InterfaceKeyword,+    intrinsic: SyntaxKind.IntrinsicKeyword,+    is: SyntaxKind.IsKeyword,+    keyof: SyntaxKind.KeyOfKeyword,+    let: SyntaxKind.LetKeyword,+    module: SyntaxKind.ModuleKeyword,+    namespace: SyntaxKind.NamespaceKeyword,+    never: SyntaxKind.NeverKeyword,+    new: SyntaxKind.NewKeyword,+    null: SyntaxKind.NullKeyword,+    number: SyntaxKind.NumberKeyword,+    object: SyntaxKind.ObjectKeyword,+    package: SyntaxKind.PackageKeyword,+    private: SyntaxKind.PrivateKeyword,+    protected: SyntaxKind.ProtectedKeyword,+    public: SyntaxKind.PublicKeyword,+    override: SyntaxKind.OverrideKeyword,+    out: SyntaxKind.OutKeyword,+    readonly: SyntaxKind.ReadonlyKeyword,+    require: SyntaxKind.RequireKeyword,+    global: SyntaxKind.GlobalKeyword,+    return: SyntaxKind.ReturnKeyword,+    satisfies: SyntaxKind.SatisfiesKeyword,+    set: SyntaxKind.SetKeyword,+    static: SyntaxKind.StaticKeyword,+    string: SyntaxKind.StringKeyword,+    super: SyntaxKind.SuperKeyword,+    switch: SyntaxKind.SwitchKeyword,+    symbol: SyntaxKind.SymbolKeyword,+    this: SyntaxKind.ThisKeyword,+    throw: SyntaxKind.ThrowKeyword,+    true: SyntaxKind.TrueKeyword,+    try: SyntaxKind.TryKeyword,+    type: SyntaxKind.TypeKeyword,+    typeof: SyntaxKind.TypeOfKeyword,+    undefined: SyntaxKind.UndefinedKeyword,+    unique: SyntaxKind.UniqueKeyword,+    unknown: SyntaxKind.UnknownKeyword,+    using: SyntaxKind.UsingKeyword,+    var: SyntaxKind.VarKeyword,+    void: SyntaxKind.VoidKeyword,+    while: SyntaxKind.WhileKeyword,+    with: SyntaxKind.WithKeyword,+    yield: SyntaxKind.YieldKeyword,+    async: SyntaxKind.AsyncKeyword,+    await: SyntaxKind.AwaitKeyword,+    of: SyntaxKind.OfKeyword,+};+const textToKeyword = new Map(Object.entries(textToKeywordObj));+const textToToken = new Map(Object.entries({+    ...textToKeywordObj,+    "{": SyntaxKind.OpenBraceToken,+    "}": SyntaxKind.CloseBraceToken,+    "(": SyntaxKind.OpenParenToken,+    ")": SyntaxKind.CloseParenToken,+    "[": SyntaxKind.OpenBracketToken,+    "]": SyntaxKind.CloseBracketToken,+    ".": SyntaxKind.DotToken,+    "...": SyntaxKind.DotDotDotToken,+    ";": SyntaxKind.SemicolonToken,+    ",": SyntaxKind.CommaToken,+    "<": SyntaxKind.LessThanToken,+    ">": SyntaxKind.GreaterThanToken,+    "<=": SyntaxKind.LessThanEqualsToken,+    ">=": SyntaxKind.GreaterThanEqualsToken,+    "==": SyntaxKind.EqualsEqualsToken,+    "!=": SyntaxKind.ExclamationEqualsToken,+    "===": SyntaxKind.EqualsEqualsEqualsToken,+    "!==": SyntaxKind.ExclamationEqualsEqualsToken,+    "=>": SyntaxKind.EqualsGreaterThanToken,+    "+": SyntaxKind.PlusToken,+    "-": SyntaxKind.MinusToken,+    "**": SyntaxKind.AsteriskAsteriskToken,+    "*": SyntaxKind.AsteriskToken,+    "/": SyntaxKind.SlashToken,+    "%": SyntaxKind.PercentToken,+    "++": SyntaxKind.PlusPlusToken,+    "--": SyntaxKind.MinusMinusToken,+    "<<": SyntaxKind.LessThanLessThanToken,+    "</": SyntaxKind.LessThanSlashToken,+    ">>": SyntaxKind.GreaterThanGreaterThanToken,+    ">>>": SyntaxKind.GreaterThanGreaterThanGreaterThanToken,+    "&": SyntaxKind.AmpersandToken,+    "|": SyntaxKind.BarToken,+    "^": SyntaxKind.CaretToken,+    "!": SyntaxKind.ExclamationToken,+    "~": SyntaxKind.TildeToken,+    "&&": SyntaxKind.AmpersandAmpersandToken,+    "||": SyntaxKind.BarBarToken,+    "?": SyntaxKind.QuestionToken,+    "??": SyntaxKind.QuestionQuestionToken,+    "?.": SyntaxKind.QuestionDotToken,+    ":": SyntaxKind.ColonToken,+    "=": SyntaxKind.EqualsToken,+    "+=": SyntaxKind.PlusEqualsToken,+    "-=": SyntaxKind.MinusEqualsToken,+    "*=": SyntaxKind.AsteriskEqualsToken,+    "**=": SyntaxKind.AsteriskAsteriskEqualsToken,+    "/=": SyntaxKind.SlashEqualsToken,+    "%=": SyntaxKind.PercentEqualsToken,+    "<<=": SyntaxKind.LessThanLessThanEqualsToken,+    ">>=": SyntaxKind.GreaterThanGreaterThanEqualsToken,+    ">>>=": SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,+    "&=": SyntaxKind.AmpersandEqualsToken,+    "|=": SyntaxKind.BarEqualsToken,+    "^=": SyntaxKind.CaretEqualsToken,+    "||=": SyntaxKind.BarBarEqualsToken,+    "&&=": SyntaxKind.AmpersandAmpersandEqualsToken,+    "??=": SyntaxKind.QuestionQuestionEqualsToken,+    "@": SyntaxKind.AtToken,+    "#": SyntaxKind.HashToken,+    "`": SyntaxKind.BacktickToken,+}));+const charCodeToRegExpFlag = new Map([+    [CharacterCodes.d, RegularExpressionFlags.HasIndices],+    [CharacterCodes.g, RegularExpressionFlags.Global],+    [CharacterCodes.i, RegularExpressionFlags.IgnoreCase],+    [CharacterCodes.m, RegularExpressionFlags.Multiline],+    [CharacterCodes.s, RegularExpressionFlags.DotAll],+    [CharacterCodes.u, RegularExpressionFlags.Unicode],+    [CharacterCodes.v, RegularExpressionFlags.UnicodeSets],+    [CharacterCodes.y, RegularExpressionFlags.Sticky],+]);+/**+ * Generated by scripts/regenerate-unicode-identifier-parts.mjs on node v22.1.0 with unicode 15.1+ * based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords+ * unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and+ * unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start+ */+// dprint-ignore+const unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2160, 2183, 2185, 2190, 2208, 2249, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3165, 3165, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3293, 3294, 3296, 3297, 3313, 3314, 3332, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5905, 5919, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6988, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69248, 69289, 69296, 69297, 69376, 69404, 69415, 69415, 69424, 69445, 69488, 69505, 69552, 69572, 69600, 69622, 69635, 69687, 69745, 69746, 69749, 69749, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69959, 69959, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70207, 70208, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70753, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71488, 71494, 71680, 71723, 71840, 71903, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71983, 71999, 71999, 72001, 72001, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73474, 73474, 73476, 73488, 73490, 73523, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78913, 78918, 82944, 83526, 92160, 92728, 92736, 92766, 92784, 92862, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 122624, 122654, 122661, 122666, 122928, 122989, 123136, 123180, 123191, 123197, 123214, 123214, 123536, 123565, 123584, 123627, 124112, 124139, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743];+// dprint-ignore+const unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2160, 2183, 2185, 2190, 2200, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2901, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3132, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3165, 3165, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3293, 3294, 3296, 3299, 3302, 3311, 3313, 3315, 3328, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3457, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3790, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5909, 5919, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6159, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6847, 6862, 6912, 6988, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43047, 43052, 43052, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69248, 69289, 69291, 69292, 69296, 69297, 69373, 69404, 69415, 69415, 69424, 69456, 69488, 69509, 69552, 69572, 69600, 69622, 69632, 69702, 69734, 69749, 69759, 69818, 69826, 69826, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69959, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70094, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70209, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70753, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71488, 71494, 71680, 71738, 71840, 71913, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71989, 71991, 71992, 71995, 72003, 72016, 72025, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73472, 73488, 73490, 73530, 73534, 73538, 73552, 73561, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78912, 78933, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92784, 92862, 92864, 92873, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94180, 94192, 94193, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 118528, 118573, 118576, 118598, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122624, 122654, 122661, 122666, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 122928, 122989, 123023, 123023, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123536, 123566, 123584, 123641, 124112, 124153, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 130032, 130041, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743, 917760, 917999];+const commentDirectiveRegExSingleLine = /^\/\/\/?\s*@(ts-expect-error|ts-ignore)/;+const commentDirectiveRegExMultiLine = /^(?:\/|\*)*\s*@(ts-expect-error|ts-ignore)/;+const jsDocTagTerminators = new Set([" ", "\t", "\n", "\r", "}", "*"]);+function hasJSDocTag(text, offset, ...tags) {+    for (const tag of tags) {+        if (text.startsWith(tag, offset)) {+            if (offset + tag.length === text.length) {+                return true;+            }+            if (jsDocTagTerminators.has(text[offset + tag.length])) {+                return true;+            }+        }+    }+    return false;+}+function scanJSDocCommentForTags(text, tokenFlags) {+    let offset = 0;+    while (true) {+        const i = text.indexOf("@", offset);+        if (i < 0) {+            return tokenFlags;+        }+        offset = i + 1;+        if (!(tokenFlags & TokenFlags.PrecedingJSDocWithDeprecated) && hasJSDocTag(text, offset, "deprecated")) {+            tokenFlags |= TokenFlags.PrecedingJSDocWithDeprecated;+        }+        if (!(tokenFlags & TokenFlags.PrecedingJSDocWithSeeOrLink) && hasJSDocTag(text, offset, "see", "link", "linkcode", "linkplain")) {+            tokenFlags |= TokenFlags.PrecedingJSDocWithSeeOrLink;+        }+        if ((tokenFlags & (TokenFlags.PrecedingJSDocWithDeprecated | TokenFlags.PrecedingJSDocWithSeeOrLink)) ===+            (TokenFlags.PrecedingJSDocWithDeprecated | TokenFlags.PrecedingJSDocWithSeeOrLink)) {+            return tokenFlags;+        }+    }+}+function lookupInUnicodeMap(code, map) {+    if (code < map[0]) {+        return false;+    }+    let lo = 0;+    let hi = map.length;+    let mid;+    while (lo + 1 < hi) {+        mid = lo + (hi - lo) / 2;+        mid -= mid % 2;+        if (map[mid] <= code && code <= map[mid + 1]) {+            return true;+        }+        if (code < map[mid]) {+            hi = mid;+        }
… 1983 more lines (truncated)
lib/tsc.js +27 lines · 1 flagged
--- +++ @@ -1,8 +1,28 @@-// This file is a shim which defers loading the real module until the compile cache is enabled.+#!/usr/bin/env node++import getExePath from "#getExePath";+import { execFileSync } from "node:child_process";++const exe = getExePath();++if (process.platform !== "win32" && typeof process.execve === "function") {+    // > v22.15.0+    try {+        process.execve(exe, [exe, ...process.argv.slice(2)]);+    }+    catch {+        // may not be available, ignore the error and fallback+    }+}+ try {-  const { enableCompileCache } = require("node:module");-  if (enableCompileCache) {-    enableCompileCache();-  }-} catch {}-module.exports = require("./_tsc.js");+    execFileSync(exe, process.argv.slice(2), { stdio: "inherit" });+}+catch (e) {+    if (e.status) {+        process.exitCode = e.status;+    }+    else {+        throw e;+    }+}
dist/api/async/api.d.ts +529 lines
--- +++ @@ -0,0 +1,529 @@+/// <reference path="../node/node.d.ts" preserve="true" />+import { CompletionItemKind } from "#enums/completionItemKind";+import { DiagnosticCategory } from "#enums/diagnosticCategory";+import { ElementFlags } from "#enums/elementFlags";+import { ModuleKind } from "#enums/moduleKind";+import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";+import { ObjectFlags } from "#enums/objectFlags";+import { SignatureFlags } from "#enums/signatureFlags";+import { SignatureKind } from "#enums/signatureKind";+import { SymbolFlags } from "#enums/symbolFlags";+import { TypeFlags } from "#enums/typeFlags";+import { TypePredicateKind } from "#enums/typePredicateKind";+import { type __String, type Expression, type Identifier, ModifierFlags, type Node, type Path, type SourceFile, type SyntaxKind, type TypeNode } from "../../ast/index.ts";+import type { APIOptions, LSPConnectionOptions } from "../options.ts";+import type { CompilerOptions, ConfigResponse, DocumentIdentifier, DocumentPosition, LSPUpdateSnapshotParams, ProjectResponse, SignatureResponse, SourceFileMetadata, SymbolResponse, TypeResponse, UpdateSnapshotParams, UpdateSnapshotResponse } from "../proto.ts";+import { SourceFileCache } from "../sourceFileCache.ts";+import type { RequestTiming, TimingAccumulators, TimingInfo } from "../timing.ts";+import { Client, type ClientSocketOptions, type ClientSpawnOptions } from "./client.ts";+import type { AssertsIdentifierTypePredicate, AssertsThisTypePredicate, BigIntLiteralType, BooleanLiteralType, CompletionEntry, CompletionInfo, CompletionOptions, ConditionalType, Diagnostic, FreshableType, IdentifierTypePredicate, IndexedAccessType, IndexInfo, IndexType, InterfaceType, IntersectionType, IntrinsicType, JSDocTagInfo, LiteralType, NumberLiteralType, ObjectType, StringLiteralType, StringMappingType, SubstitutionType, TemplateLiteralType, ThisTypePredicate, TupleType, Type, TypeParameter, TypePredicate, TypePredicateBase, TypeReference, UnionOrIntersectionType, UnionType } from "./types.ts";+export { documentURIToFileName, fileNameToDocumentURI } from "../path.ts";+export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };+export type { APIOptions, AssertsIdentifierTypePredicate, AssertsThisTypePredicate, BigIntLiteralType, BooleanLiteralType, ClientSocketOptions, ClientSpawnOptions, CompilerOptions, CompletionEntry, CompletionInfo, CompletionOptions, ConditionalType, Diagnostic, DocumentIdentifier, DocumentPosition, FreshableType, IdentifierTypePredicate, IndexedAccessType, IndexInfo, IndexType, InterfaceType, IntersectionType, IntrinsicType, JSDocTagInfo, LiteralType, LSPConnectionOptions, NumberLiteralType, ObjectType, RequestTiming, SourceFileMetadata, StringLiteralType, StringMappingType, SubstitutionType, TemplateLiteralType, ThisTypePredicate, TimingAccumulators, TimingInfo, TupleType, Type, TypeParameter, TypePredicate, TypePredicateBase, TypeReference, UnionOrIntersectionType, UnionType };+export declare class API<FromLSP extends boolean = false> {+    private client;+    private sourceFileCache;+    private toPath;+    private initialized;+    private activeSnapshots;+    private latestSnapshot;+    readonly internal: InternalAPI;+    constructor(options?: APIOptions | LSPConnectionOptions);+    /**+     * Create an API instance from an existing LSP connection's API session.+     * Use this when connecting to an API pipe provided by an LSP server via custom/initializeAPISession.+     */+    static fromLSPConnection(options: LSPConnectionOptions): Promise<API<true>>;+    private ensureInitialized;+    parseConfigFile(file: DocumentIdentifier): Promise<ConfigResponse>;+    updateSnapshot(params?: FromLSP extends true ? LSPUpdateSnapshotParams : UpdateSnapshotParams): Promise<Snapshot>;+    close(): Promise<void>;+    clearSourceFileCache(): void;+    /**+     * Returns a snapshot of collected timing information for requests made+     * through this API instance: client-measured round-trip latency and bytes+     * transferred, folded together with the server's own per-request processing+     * time and an estimated transport overhead (round-trip minus server time).+     *+     * Fetching the snapshot issues a lightweight request to the server to+     * retrieve its timing collection. Collection must be enabled via the+     * `collectTiming` option; when it is not, the returned snapshot has+     * `enabled: false` and zeroed totals.+     */+    getTimingInfo(): Promise<TimingInfo>;+    /** Clears all accumulated timing totals and recent-request history, on both the client and the server. */+    resetTimingInfo(): Promise<void>;+}+export declare class InternalAPI {+    private client;+    private ensureInitialized;+    /** @internal */+    constructor(client: Client, ensureInitialized: () => Promise<void>);+    startCPUProfile(dir: string): Promise<void>;+    stopCPUProfile(): Promise<string>;+    saveHeapProfile(dir: string): Promise<string>;+}+export declare class Snapshot {+    readonly id: number;+    private projectMap;+    private toPath;+    private client;+    private disposed;+    private onDispose;+    private snapshotRegistry;+    constructor(data: UpdateSnapshotResponse, client: Client, sourceFileCache: SourceFileCache, toPath: (fileName: string) => Path, onDispose: () => void);+    getProjects(): readonly Project[];+    getProject(configFileName: string): Project | undefined;+    getDefaultProjectForFile(file: DocumentIdentifier): Promise<Project | undefined>;+    [globalThis.Symbol.dispose](): void;+    dispose(): Promise<void>;+    isDisposed(): boolean;+    private ensureNotDisposed;+}+declare class SnapshotObjectRegistry {+    private readonly symbols;+    private readonly client;+    private readonly snapshotId;+    private readonly resolveProject;+    constructor(client: Client, snapshotId: number, resolveProject: (projectId: Path) => Project | undefined);+    /** Resolve a project id (a config file path) to its Project within this snapshot. */+    getProject(projectId: Path): Project | undefined;+    getOrCreateSymbol(data: SymbolResponse): Symbol;+    getSymbol(id: number): Symbol | undefined;+    clear(): void;+    fetchSymbol(source: Symbol | Signature | Type, method: string, handle: number | undefined, projectId?: Path): Promise<Symbol>;+    fetchSymbols(source: Symbol | Signature | Type, method: string, handles?: readonly number[], projectId?: Path): Promise<readonly Symbol[]>;+}+declare class ProjectObjectRegistry {+    private client;+    private snapshotId;+    private project;+    private snapshotRegistry;+    private types;+    private signatures;+    constructor(client: Client, snapshotId: number, project: Project, snapshotRegistry: SnapshotObjectRegistry);+    getOrCreateSymbol(data: SymbolResponse): Symbol;+    getSymbol(id: number): Symbol | undefined;+    getOrCreateType(data: TypeResponse): TypeObject;+    getType(id: number): TypeObject | undefined;+    getOrCreateSignature(data: SignatureResponse): Signature;+    getSignature(id: number): Signature | undefined;+    clear(): void;+    fetchType<T extends Type>(source: Symbol | Signature | Type, method: string, handle: number | false | undefined): Promise<T>;+    fetchSymbol(source: Symbol | Signature | Type, method: string, handle: number | undefined): Promise<Symbol>;+    fetchSignature(source: Symbol | Signature | Type, method: string, handle: number | undefined): Promise<Signature>;+    fetchTypes(source: Symbol | Signature | Type, method: string, handles?: readonly number[]): Promise<readonly Type[]>;+    fetchSymbols(source: Symbol | Signature | Type, method: string, handles?: readonly number[]): Promise<readonly Symbol[]>;+    fetchBaseTypes(source: Type): Promise<readonly Type[]>;+}+export declare class Project {+    readonly id: Path;+    readonly configFileName: string;+    readonly compilerOptions: CompilerOptions;+    readonly rootFiles: readonly string[];+    readonly program: Program;+    readonly checker: Checker;+    readonly emitter: Emitter;+    private client;+    constructor(data: ProjectResponse, snapshotId: number, client: Client, sourceFileCache: SourceFileCache, toPath: (fileName: string) => Path, snapshotRegistry: SnapshotObjectRegistry);+    dispose(): void;+}+export declare class Program {+    private snapshotId;+    private project;+    private client;+    private sourceFileCache;+    private toPath;+    private decoder;+    private sourceFileMetadataCache;+    constructor(snapshotId: number, project: Project, client: Client, sourceFileCache: SourceFileCache, toPath: (fileName: string) => Path);+    getCompilerOptions(): CompilerOptions;+    getSourceFile(file: DocumentIdentifier): Promise<SourceFile | undefined>;+    getSourceFileNames(): Promise<readonly string[]>;+    /**+     * Returns program-stored metadata for the given source file, or `undefined` if the file+     * is not part of the program. Metadata is fetched lazily per file and cached on this+     * `Program` instance.+     */+    getSourceFileMetadata(fileName: string): Promise<SourceFileMetadata | undefined>;+    /**+     * Returns program-stored metadata for the source file at the given path, or `undefined`+     * if the file is not part of the program. Like {@link getSourceFileMetadata}, but skips+     * the file name to path conversion. Metadata is fetched lazily per file and cached on+     * this `Program` instance.+     */+    getSourceFileMetadataByPath(path: Path): Promise<SourceFileMetadata | undefined>;+    private fetchSourceFileMetadata;+    /**+     * Returns whether the given source file was loaded as part of an external library+     * (e.g. a dependency resolved from `node_modules`). The underlying program metadata is+     * fetched lazily per file and cached on this `Program` instance.+     */+    isSourceFileFromExternalLibrary(file: SourceFile): Promise<boolean>;+    /**+     * Returns whether the given source file is a default library file (e.g. `lib.d.ts`).+     * The underlying program metadata is fetched lazily per file and cached on this+     * `Program` instance.+     */+    isSourceFileDefaultLibrary(file: SourceFile): Promise<boolean>;+    /**+     * Get syntactic (parse) diagnostics for a specific file or all files.+     * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.+     */+    getSyntacticDiagnostics(file?: DocumentIdentifier): Promise<readonly Diagnostic[]>;+    /**+     * Get binder diagnostics for a specific file or all files.+     * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.+     */+    getBindDiagnostics(file?: DocumentIdentifier): Promise<readonly Diagnostic[]>;+    /**+     * Get semantic (type-check) diagnostics for a specific file or all files.+     * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.+     */+    getSemanticDiagnostics(file?: DocumentIdentifier): Promise<readonly Diagnostic[]>;+    /**+     * Get suggestion diagnostics for a specific file or all files.+     * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.+     */+    getSuggestionDiagnostics(file?: DocumentIdentifier): Promise<readonly Diagnostic[]>;+    /**+     * Get declaration emit diagnostics for a specific file or all files.+     * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.+     */+    getDeclarationDiagnostics(file?: DocumentIdentifier): Promise<readonly Diagnostic[]>;+    /**+     * Get program-wide diagnostics for the project, including compiler options diagnostics.+     */+    getProgramDiagnostics(): Promise<readonly Diagnostic[]>;+    /**+     * Get global (non-file-specific) semantic diagnostics for the project.+     */+    getGlobalDiagnostics(): Promise<readonly Diagnostic[]>;+    /**+     * Get config file parsing diagnostics for the project.+     */+    getConfigFileParsingDiagnostics(): Promise<readonly Diagnostic[]>;+}+export declare class Checker {+    private snapshotId;+    private project;+    private client;+    private objectRegistry;+    private wellKnownSymbols;+    constructor(snapshotId: number, project: Project, client: Client, objectRegistry: ProjectObjectRegistry);+    dispose(): void;+    getSymbolAtLocation(node: Node): Promise<Symbol | undefined>;+    getSymbolAtLocation(nodes: readonly Node[]): Promise<(Symbol | undefined)[]>;+    getSymbolAtPosition(file: DocumentIdentifier, position: number): Promise<Symbol | undefined>;+    getSymbolAtPosition(file: DocumentIdentifier, positions: readonly number[]): Promise<(Symbol | undefined)[]>;+    getTypeOfSymbol(symbol: Symbol): Promise<Type | undefined>;+    getTypeOfSymbol(symbols: readonly Symbol[]): Promise<(Type | undefined)[]>;+    /**+     * Get the declared type of a symbol. Always returns a type; for symbols whose+     * declared type cannot be determined the checker yields the error type (use+     * {@link Type.isErrorType} to detect it).+     */+    getDeclaredTypeOfSymbol(symbol: Symbol): Promise<Type>;+    getReferencesToSymbolInFile(file: DocumentIdentifier, symbol: Symbol): Promise<NodeHandle[]>;+    getReferencedSymbolsForNode(node: Node, position: number): Promise<ReferencedSymbolEntry[]>;+    getSignatureUsage(signatureDecl: Node): Promise<SignatureUsage[]>;+    getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): Promise<CompletionInfo | undefined>;+    getTypeAtLocation(node: Node): Promise<Type | undefined>;+    getTypeAtLocation(nodes: readonly Node[]): Promise<(Type | undefined)[]>;+    getSignaturesOfType(type: Type, kind: SignatureKind): Promise<readonly Signature[]>;+    getResolvedSignature(node: Node): Promise<Signature | undefined>;+    getTypeAtPosition(file: DocumentIdentifier, position: number): Promise<Type | undefined>;+    getTypeAtPosition(file: DocumentIdentifier, positions: readonly number[]): Promise<(Type | undefined)[]>;+    resolveName(name: string, meaning: SymbolFlags, location?: Node | DocumentPosition, excludeGlobals?: boolean): Promise<Symbol | undefined>;+    getResolvedSymbol(node: Identifier): Promise<Symbol | undefined>;+    getContextualType(node: Expression): Promise<Type | undefined>;+    getBaseTypeOfLiteralType(type: Type): Promise<Type | undefined>;+    getNonNullableType(type: Type): Promise<Type | undefined>;+    getTypeFromTypeNode(node: TypeNode): Promise<Type | undefined>;+    getWidenedType(type: Type): Promise<Type | undefined>;+    getParameterType(signature: Signature, index: number): Promise<Type | undefined>;+    isArrayLikeType(type: Type): Promise<boolean>;+    isTypeAssignableTo(source: Type, target: Type): Promise<boolean>;+    getShorthandAssignmentValueSymbol(node: Node): Promise<Symbol | undefined>;
… 282 more lines (truncated)
dist/api/async/api.js +1657 lines
--- +++ @@ -0,0 +1,1657 @@+/// <reference path="../node/node.ts" preserve="true" />+import { CompletionItemKind } from "#enums/completionItemKind";+import { DiagnosticCategory } from "#enums/diagnosticCategory";+import { ElementFlags } from "#enums/elementFlags";+import { ModuleKind } from "#enums/moduleKind";+import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";+import { ObjectFlags } from "#enums/objectFlags";+import { SignatureFlags } from "#enums/signatureFlags";+import { SignatureKind } from "#enums/signatureKind";+import { SymbolFlags } from "#enums/symbolFlags";+import { TypeFlags } from "#enums/typeFlags";+import { TypePredicateKind } from "#enums/typePredicateKind";+import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";+import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";+import { decodeNode, getNodeId, parseNodeHandle, readParseOptionsKey, readSourceFileHash, RemoteSourceFile, } from "../node/node.js";+import { Wtf8Decoder } from "../node/wtf8.js";+import { createGetCanonicalFileName, toPath, } from "../path.js";+import { resolveFileName, toUpdateSnapshotRequest, } from "../proto.js";+import { SourceFileCache } from "../sourceFileCache.js";+import { Client, } from "./client.js";+export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";+export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };+export class API {+    client;+    sourceFileCache;+    toPath;+    initialized = false;+    activeSnapshots = new Set();+    latestSnapshot;+    internal;+    constructor(options = {}) {+        this.client = new Client(options);+        this.sourceFileCache = new SourceFileCache();+        this.internal = new InternalAPI(this.client, () => this.ensureInitialized());+    }+    /**+     * Create an API instance from an existing LSP connection's API session.+     * Use this when connecting to an API pipe provided by an LSP server via custom/initializeAPISession.+     */+    static async fromLSPConnection(options) {+        const api = new API(options);+        await api.ensureInitialized();+        return api;+    }+    async ensureInitialized() {+        if (!this.initialized) {+            const response = await this.client.apiRequest("initialize", null);+            const getCanonicalFileName = createGetCanonicalFileName(response.useCaseSensitiveFileNames);+            const currentDirectory = response.currentDirectory;+            this.toPath = (fileName) => toPath(fileName, currentDirectory, getCanonicalFileName);+            this.initialized = true;+        }+    }+    async parseConfigFile(file) {+        await this.ensureInitialized();+        return this.client.apiRequest("parseConfigFile", { file });+    }+    async updateSnapshot(params) {+        await this.ensureInitialized();+        const requestParams = toUpdateSnapshotRequest(params);+        const data = await this.client.apiRequest("updateSnapshot", requestParams);+        // Retain cached source files from previous snapshot for unchanged files+        if (this.latestSnapshot) {+            this.sourceFileCache.retainForSnapshot(data.snapshot, this.latestSnapshot.id, data.changes);+            if (this.latestSnapshot.isDisposed()) {+                this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);+            }+        }+        const snapshot = new Snapshot(data, this.client, this.sourceFileCache, this.toPath, () => {+            this.activeSnapshots.delete(snapshot);+            if (snapshot !== this.latestSnapshot) {+                this.sourceFileCache.releaseSnapshot(snapshot.id);+            }+        });+        this.latestSnapshot = snapshot;+        this.activeSnapshots.add(snapshot);+        return snapshot;+    }+    async close() {+        // Dispose all active snapshots+        for (const snapshot of [...this.activeSnapshots]) {+            await snapshot.dispose();+        }+        // Release the latest snapshot's cache refs if still held+        if (this.latestSnapshot) {+            this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);+            this.latestSnapshot = undefined;+        }+        await this.client.close();+        this.sourceFileCache.clear();+    }+    clearSourceFileCache() {+        this.sourceFileCache.clear();+    }+    /**+     * Returns a snapshot of collected timing information for requests made+     * through this API instance: client-measured round-trip latency and bytes+     * transferred, folded together with the server's own per-request processing+     * time and an estimated transport overhead (round-trip minus server time).+     *+     * Fetching the snapshot issues a lightweight request to the server to+     * retrieve its timing collection. Collection must be enabled via the+     * `collectTiming` option; when it is not, the returned snapshot has+     * `enabled: false` and zeroed totals.+     */+    getTimingInfo() {+        return this.client.getTimingInfo();+    }+    /** Clears all accumulated timing totals and recent-request history, on both the client and the server. */+    resetTimingInfo() {+        return this.client.resetTimingInfo();+    }+}+export class InternalAPI {+    client;+    ensureInitialized;+    /** @internal */+    constructor(client, ensureInitialized) {+        this.client = client;+        this.ensureInitialized = ensureInitialized;+    }+    async startCPUProfile(dir) {+        await this.ensureInitialized();+        await this.client.apiRequest("startCPUProfile", { dir });+    }+    async stopCPUProfile() {+        await this.ensureInitialized();+        const result = await this.client.apiRequest("stopCPUProfile", null);+        return result.file;+    }+    async saveHeapProfile(dir) {+        await this.ensureInitialized();+        const result = await this.client.apiRequest("saveHeapProfile", { dir });+        return result.file;+    }+}+export class Snapshot {+    id;+    projectMap;+    toPath;+    client;+    disposed = false;+    onDispose;+    snapshotRegistry;+    constructor(data, client, sourceFileCache, toPath, onDispose) {+        this.id = data.snapshot;+        this.client = client;+        this.toPath = toPath;+        this.onDispose = onDispose;+        this.projectMap = new Map();+        this.snapshotRegistry = new SnapshotObjectRegistry(client, this.id, projectId => this.projectMap.get(projectId));+        for (const projData of data.projects) {+            const project = new Project(projData, this.id, client, sourceFileCache, toPath, this.snapshotRegistry);+            this.projectMap.set(toPath(projData.configFileName), project);+        }+    }+    getProjects() {+        this.ensureNotDisposed();+        return [...this.projectMap.values()];+    }+    getProject(configFileName) {+        this.ensureNotDisposed();+        return this.projectMap.get(this.toPath(configFileName));+    }+    async getDefaultProjectForFile(file) {+        this.ensureNotDisposed();+        const data = await this.client.apiRequest("getDefaultProjectForFile", {+            snapshot: this.id,+            file,+        });+        if (!data)+            return undefined;+        return this.projectMap.get(this.toPath(data.configFileName));+    }+    [globalThis.Symbol.dispose]() {+        this.dispose();+    }+    async dispose() {+        if (this.disposed)+            return;+        this.disposed = true;+        for (const project of this.projectMap.values()) {+            project.dispose();+        }+        this.projectMap.clear();+        this.snapshotRegistry.clear();+        this.onDispose();+        await this.client.apiRequest("release", { snapshot: this.id });+    }+    isDisposed() {+        return this.disposed;+    }+    ensureNotDisposed() {+        if (this.disposed) {+            throw new Error("Snapshot is disposed");+        }+    }+}+class SnapshotObjectRegistry {+    symbols = new Map();+    client;+    snapshotId;+    resolveProject;+    constructor(client, snapshotId, resolveProject) {+        this.client = client;+        this.snapshotId = snapshotId;+        this.resolveProject = resolveProject;+    }+    /** Resolve a project id (a config file path) to its Project within this snapshot. */+    getProject(projectId) {+        return this.resolveProject(projectId);+    }+    getOrCreateSymbol(data) {+        let symbol = this.symbols.get(data.id);+        if (!symbol) {+            symbol = new Symbol(data, this);+            this.symbols.set(data.id, symbol);+        }+        return symbol;+    }+    getSymbol(id) {+        return this.symbols.get(id);+    }+    clear() {+        this.symbols.clear();+    }+    async fetchSymbol(source, method, handle, projectId) {+        if (!handle)+            return undefined;+        const cached = this.getSymbol(handle);+        if (cached)+            return cached;+        const data = await this.client.apiRequest(method, {+            snapshot: this.snapshotId,+            project: projectId,+            objectId: source.id,+        });+        if (!data)+            throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);+        return this.getOrCreateSymbol(data);+    }+    async fetchSymbols(source, method, handles, projectId) {+        if (handles) {+            const result = new Array(handles.length);+            let allCached = true;+            for (let i = 0; i < handles.length; i++) {+                const cached = this.getSymbol(handles[i]);
… 1410 more lines (truncated)
dist/api/async/client.d.ts +39 lines
--- +++ @@ -0,0 +1,39 @@+import { type ClientOptions, type ClientSocketOptions, type ClientSpawnOptions } from "../options.ts";+import { TimingCollector, type TimingInfo } from "../timing.ts";+export type { ClientOptions, ClientSocketOptions, ClientSpawnOptions };+/**+ * Client handles communication with the TypeScript API server+ * over STDIO (spawned process) or a Unix domain socket using JSON-RPC.+ */+export declare class Client {+    private socket;+    private process;+    private connection;+    private options;+    private connected;+    private timing;+    constructor(options: ClientOptions);+    connect(): Promise<void>;+    private connectViaSpawn;+    private connectViaSocket;+    private registerFSCallbacks;+    apiRequest<T>(method: string, params?: unknown): Promise<T>;+    apiRequestBinary(method: string, params?: unknown): Promise<Uint8Array | undefined>;+    /**+     * Returns the timing collector that per-node materialization is reported+     * into, or undefined when timing collection is disabled. The returned+     * collector is the same one folded into {@link getTimingInfo}, so+     * materialization totals surface alongside request timings.+     */+    getTimingCollector(): TimingCollector | undefined;+    /**+     * Returns a combined timing snapshot: client-measured round-trip and byte+     * counts folded together with the server's own per-request processing time+     * (fetched via a getServerTiming request) and estimated transport overhead.+     */+    getTimingInfo(): Promise<TimingInfo>;+    resetTimingInfo(): Promise<void>;+    private fetchServerTiming;+    close(): Promise<void>;+}+//# sourceMappingURL=client.d.ts.map
dist/api/async/types.d.ts +310 lines
--- +++ @@ -0,0 +1,310 @@+import type { CompletionItemKind } from "#enums/completionItemKind";+import type { DiagnosticCategory } from "#enums/diagnosticCategory";+import type { ElementFlags } from "#enums/elementFlags";+import type { ObjectFlags } from "#enums/objectFlags";+import type { TypeFlags } from "#enums/typeFlags";+import type { TypePredicateKind } from "#enums/typePredicateKind";+import type { NodeHandle, Symbol } from "./api.ts";+/**+ * A TypeScript type.+ *+ * Use TypeFlags to determine the specific kind of type and access+ * kind-specific properties. For example:+ *+ * ```ts+ * if (type.flags & TypeFlags.StringLiteral) {+ *     console.log((type as StringLiteralType).value); // string+ * }+ * ```+ */+export interface Type {+    /** Type flags — use to determine the specific kind of type. */+    readonly flags: TypeFlags;+    /** Unique identifier for this type */+    readonly id: number;+    /** Get the symbol associated with this type, if any */+    getSymbol(): Promise<Symbol | undefined>;+    /** Get the type arguments of the type alias this type was instantiated from, if any */+    getAliasTypeArguments(): Promise<readonly Type[]>;+    /** Get the symbol of the type alias this type was instantiated from, if any */+    getAliasSymbol(): Promise<Symbol | undefined>;+    /**+     * Get the base types of this type, or `undefined` if it is not a class or+     * interface type.+     */+    getBaseTypes(): Promise<readonly Type[] | undefined>;+    /** Whether this type is a class or interface type */+    isClassOrInterface(): this is InterfaceType;+    /** Whether this type is a union type */+    isUnionType(): this is UnionType;+    /** Whether this type is an intersection type */+    isIntersectionType(): this is IntersectionType;+    /** Whether this type is an object type */+    isObjectType(): this is ObjectType;+    /** Whether this type is an intrinsic primitive type */+    isIntrinsicType(): this is IntrinsicType;+    /**+     * Whether this is the error type — the placeholder produced when a type+     * cannot be determined (e.g. an unresolved reference).+     */+    isErrorType(): boolean;+    /** Whether this type is a literal type */+    isLiteralType(): this is LiteralType;+    /** Whether this type is a string literal type */+    isStringLiteralType(): this is StringLiteralType;+    /** Whether this type is a number literal type */+    isNumberLiteralType(): this is NumberLiteralType;+    /** Whether this type is a bigint literal type */+    isBigIntLiteralType(): this is BigIntLiteralType;+    /** Whether this type is a boolean literal type */+    isBooleanLiteralType(): this is BooleanLiteralType;+    /** Whether this type is a type reference */+    isTypeReference(): this is TypeReference;+    /** Whether this type is a tuple type */+    isTupleType(): this is TupleType;+    /** Whether this type is an index type (`keyof T`) */+    isIndexType(): this is IndexType;+    /** Whether this type is an indexed access type (`T[K]`) */+    isIndexedAccessType(): this is IndexedAccessType;+    /** Whether this type is a conditional type */+    isConditionalType(): this is ConditionalType;+    /** Whether this type is a substitution type */+    isSubstitutionType(): this is SubstitutionType;+    /** Whether this type is a template literal type */+    isTemplateLiteralType(): this is TemplateLiteralType;+    /** Whether this type is a string mapping type */+    isStringMappingType(): this is StringMappingType;+    /** Whether this type is a type parameter */+    isTypeParameter(): this is TypeParameter;+}+/**+ * Freshable types (TypeFlags.Freshable) - literal types (TypeFlags.Literal) and computed enum types (TypeFlags.Enum).+ */+export interface FreshableType extends Type {+    /** Get the fresh version of this type, if any */+    getFreshType(): Promise<FreshableType | undefined>;+    /** Get the regular (non-fresh) version of this type, if any */+    getRegularType(): Promise<FreshableType | undefined>;+}+/** Literal types: StringLiteral, NumberLiteral, BigIntLiteral, BooleanLiteral */+export interface LiteralType extends FreshableType {+    /** The literal value. Use TypeFlags to narrow to a specific literal subtype with a concrete value type. */+    readonly value: string | number | boolean | bigint;+}+/** String literal types (TypeFlags.StringLiteral) */+export interface StringLiteralType extends LiteralType {+    /** The string value of the literal */+    readonly value: string;+}+/** Numeric literal types (TypeFlags.NumberLiteral) */+export interface NumberLiteralType extends LiteralType {+    /** The numeric value of the literal */+    readonly value: number;+}+/** BigInt literal types (TypeFlags.BigIntLiteral) */+export interface BigIntLiteralType extends LiteralType {+    /** The bigint value of the literal */+    readonly value: bigint;+}+/** Boolean literal types (TypeFlags.BooleanLiteral) */+export interface BooleanLiteralType extends LiteralType {+    /** The boolean value of the literal */+    readonly value: boolean;+}+/** Object types (TypeFlags.Object) */+export interface ObjectType extends Type {+    /** Object flags — use to determine the specific kind of object type. */+    readonly objectFlags: ObjectFlags;+}+/** Type references (ObjectFlags.Reference) — e.g. Array<string>, Map<K, V> */+export interface TypeReference extends ObjectType {+    /** Get the generic target type (e.g. Array for Array<string>) */+    getTarget(): Promise<Type>;+}+/** Interface types — classes and interfaces (ObjectFlags.ClassOrInterface) */+export interface InterfaceType extends TypeReference {+    /** Get all type parameters (outer + local, excluding thisType) */+    getTypeParameters(): Promise<readonly TypeParameter[]>;+    /** Get outer type parameters from enclosing declarations */+    getOuterTypeParameters(): Promise<readonly TypeParameter[]>;+    /** Get local type parameters declared on this interface/class */+    getLocalTypeParameters(): Promise<readonly TypeParameter[]>;+}+/** Tuple types (ObjectFlags.Tuple) */+export interface TupleType extends InterfaceType {+    /** Per-element flags (Required, Optional, Rest, Variadic) */+    readonly elementFlags: readonly ElementFlags[];+    /** Number of initial required or optional elements */+    readonly fixedLength: number;+    /** Whether the tuple is readonly */+    readonly readonly: boolean;+}+/** Union or intersection types (TypeFlags.Union | TypeFlags.Intersection) */+export interface UnionOrIntersectionType extends Type {+    /** Get the constituent types */+    getTypes(): Promise<readonly Type[]>;+}+/** Union types (TypeFlags.Union) */+export interface UnionType extends UnionOrIntersectionType {+}+/** Intersection types (TypeFlags.Intersection) */+export interface IntersectionType extends UnionOrIntersectionType {+}+/** Type parameters (TypeFlags.TypeParameter) */+export interface TypeParameter extends Type {+    /** True if this is the synthetic `this` type of an interface, class, or tuple */+    readonly isThisType?: boolean | undefined;+}+/** Index types — keyof T (TypeFlags.Index) */+export interface IndexType extends Type {+    /** Get the target type T in `keyof T` */+    getTarget(): Promise<Type>;+}+/** Indexed access types — T[K] (TypeFlags.IndexedAccess) */+export interface IndexedAccessType extends Type {+    /** Get the object type T in `T[K]` */+    getObjectType(): Promise<Type>;+    /** Get the index type K in `T[K]` */+    getIndexType(): Promise<Type>;+}+/** Conditional types — T extends U ? X : Y (TypeFlags.Conditional) */+export interface ConditionalType extends Type {+    /** Get the check type T in `T extends U ? X : Y` */+    getCheckType(): Promise<Type>;+    /** Get the extends type U in `T extends U ? X : Y` */+    getExtendsType(): Promise<Type>;+    /** Get the true type X in `T extends U ? X : Y` */+    getTrueType(): Promise<Type>;+    /** Get the false type Y in `T extends U ? X : Y` */+    getFalseType(): Promise<Type>;+}+/** Substitution types (TypeFlags.Substitution) */+export interface SubstitutionType extends Type {+    getBaseType(): Promise<Type>;+    getConstraint(): Promise<Type>;+}+/** Template literal types (TypeFlags.TemplateLiteral) */+export interface TemplateLiteralType extends Type {+    /** Text segments (always one more than the number of type spans) */+    readonly texts: readonly string[];+    /** Get the types interspersed between text segments */+    getTypes(): Promise<readonly Type[]>;+}+/** String mapping types — Uppercase<T>, Lowercase<T>, etc. (TypeFlags.StringMapping) */+export interface StringMappingType extends Type {+    /** Get the mapped type */+    getTarget(): Promise<Type>;+}+/** Intrinsic types — any, unknown, string, number, bigint, symbol, void, undefined, null, never, object (TypeFlags.Intrinsic) */+export interface IntrinsicType extends Type {+    /** The intrinsic type name (e.g. "any", "string", "never") */+    readonly intrinsicName: string;+}+/** Base for all type predicates */+export interface TypePredicateBase {+    readonly kind: TypePredicateKind;+    readonly type: Type | undefined;+}+/** `this is T` */+export interface ThisTypePredicate extends TypePredicateBase {+    readonly kind: TypePredicateKind.This;+    readonly parameterName: undefined;+    readonly parameterIndex: undefined;+    readonly type: Type;+}+/** `x is T` */+export interface IdentifierTypePredicate extends TypePredicateBase {+    readonly kind: TypePredicateKind.Identifier;+    readonly parameterName: string;+    readonly parameterIndex: number;+    readonly type: Type;+}+/** `asserts this is T` */+export interface AssertsThisTypePredicate extends TypePredicateBase {+    readonly kind: TypePredicateKind.AssertsThis;+    readonly parameterName: undefined;+    readonly parameterIndex: undefined;+    readonly type: Type | undefined;+}+/** `asserts x is T` */+export interface AssertsIdentifierTypePredicate extends TypePredicateBase {+    readonly kind: TypePredicateKind.AssertsIdentifier;+    readonly parameterName: string;+    readonly parameterIndex: number;+    readonly type: Type | undefined;+}+/** A type predicate — e.g. `x is T` or `asserts x is T` */+export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate;+/** An index signature — e.g. `[key: string]: T` */+export interface IndexInfo {+    /** The index key type (e.g. string or number) */+    readonly keyType: Type;+    /** The index value type */+    readonly valueType: Type;+    /** Whether the index signature is readonly */+    readonly isReadonly: boolean;+    /** The index signature declaration, if any */+    readonly declaration?: NodeHandle | undefined;
… 63 more lines (truncated)
dist/api/async/types.js +2 lines
--- +++ @@ -0,0 +1,2 @@+export {};+//# sourceMappingURL=types.js.map
dist/api/compilerOptions.d.ts +109 lines
--- +++ @@ -0,0 +1,109 @@+import type { JsxEmit } from "#enums/jsxEmit";+import type { ModuleDetectionKind } from "#enums/moduleDetectionKind";+import type { ModuleKind } from "#enums/moduleKind";+import type { ModuleResolutionKind } from "#enums/moduleResolutionKind";+import type { NewLineKind } from "#enums/newLineKind";+import type { ScriptTarget } from "#enums/scriptTarget";+export interface CompilerOptions {+    allowJs?: boolean;+    allowArbitraryExtensions?: boolean;+    allowImportingTsExtensions?: boolean;+    allowNonTsExtensions?: boolean;+    allowUmdGlobalAccess?: boolean;+    allowUnreachableCode?: boolean;+    allowUnusedLabels?: boolean;+    assumeChangesOnlyAffectDirectDependencies?: boolean;+    checkJs?: boolean;+    customConditions?: string[];+    composite?: boolean;+    emitDeclarationOnly?: boolean;+    emitBOM?: boolean;+    emitDecoratorMetadata?: boolean;+    declaration?: boolean;+    declarationDir?: string;+    declarationMap?: boolean;+    deduplicatePackages?: boolean;+    disableSizeLimit?: boolean;+    disableSourceOfProjectReferenceRedirect?: boolean;+    disableSolutionSearching?: boolean;+    disableReferencedProjectLoad?: boolean;+    erasableSyntaxOnly?: boolean;+    exactOptionalPropertyTypes?: boolean;+    experimentalDecorators?: boolean;+    forceConsistentCasingInFileNames?: boolean;+    isolatedModules?: boolean;+    isolatedDeclarations?: boolean;+    ignoreConfig?: boolean;+    ignoreDeprecations?: string;+    importHelpers?: boolean;+    inlineSourceMap?: boolean;+    inlineSources?: boolean;+    init?: boolean;+    incremental?: boolean;+    jsx?: JsxEmit;+    jsxFactory?: string;+    jsxFragmentFactory?: string;+    jsxImportSource?: string;+    lib?: string[];+    libReplacement?: boolean;+    locale?: string;+    mapRoot?: string;+    module?: ModuleKind;+    moduleResolution?: ModuleResolutionKind;+    moduleSuffixes?: string[];+    moduleDetection?: ModuleDetectionKind;+    newLine?: NewLineKind;+    noEmit?: boolean;+    noCheck?: boolean;+    noErrorTruncation?: boolean;+    noFallthroughCasesInSwitch?: boolean;+    noImplicitAny?: boolean;+    noImplicitThis?: boolean;+    noImplicitReturns?: boolean;+    noEmitHelpers?: boolean;+    noLib?: boolean;+    noPropertyAccessFromIndexSignature?: boolean;+    noUncheckedIndexedAccess?: boolean;+    noEmitOnError?: boolean;+    noUnusedLocals?: boolean;+    noUnusedParameters?: boolean;+    noResolve?: boolean;+    noImplicitOverride?: boolean;+    noUncheckedSideEffectImports?: boolean;+    outDir?: string;+    paths?: Record<string, string[]>;+    preserveConstEnums?: boolean;+    preserveSymlinks?: boolean;+    project?: string;+    resolveJsonModule?: boolean;+    resolvePackageJsonExports?: boolean;+    resolvePackageJsonImports?: boolean;+    removeComments?: boolean;+    rewriteRelativeImportExtensions?: boolean;+    reactNamespace?: string;+    rootDir?: string;+    rootDirs?: string[];+    skipLibCheck?: boolean;+    stableTypeOrdering?: boolean;+    strict?: boolean;+    strictBindCallApply?: boolean;+    strictBuiltinIteratorReturn?: boolean;+    strictFunctionTypes?: boolean;+    strictNullChecks?: boolean;+    strictPropertyInitialization?: boolean;+    stripInternal?: boolean;+    skipDefaultLibCheck?: boolean;+    sourceMap?: boolean;+    sourceRoot?: string;+    suppressOutputPathCheck?: boolean;+    target?: ScriptTarget;+    traceResolution?: boolean;+    tsBuildInfoFile?: string;+    typeRoots?: string[];+    types?: string[];+    useDefineForClassFields?: boolean;+    useUnknownInCatchVariables?: boolean;+    verbatimModuleSyntax?: boolean;+    maxNodeModuleJsDepth?: number;+}+//# sourceMappingURL=compilerOptions.d.ts.map
dist/api/compilerOptions.js +2 lines
--- +++ @@ -0,0 +1,2 @@+export {};+//# sourceMappingURL=compilerOptions.js.map
dist/api/fs.d.ts +23 lines
--- +++ @@ -0,0 +1,23 @@+export interface FileSystemEntries {+    files: string[];+    directories: string[];+}+export interface FileSystem {+    directoryExists?: (directoryName: string) => boolean | undefined;+    fileExists?: (fileName: string) => boolean | undefined;+    getAccessibleEntries?: (directoryName: string) => FileSystemEntries | undefined;+    /**+     * Read a file's content.+     * - Return the file content as a `string` (including `""` for empty files).+     * - Return `null` to indicate the file does not exist (without falling back to the real FS).+     * - Return `undefined` to fall back to the real filesystem.+     */+    readFile?: (fileName: string) => string | null | undefined;+    realpath?: (path: string) => string | undefined;+    writeFile?: (path: string, content: string) => void;+    removeFile?: (path: string) => void;+}+/** The callback names supported by the Go server for virtual FS delegation. */+export declare const fsCallbackNames: readonly ["readFile", "fileExists", "directoryExists", "getAccessibleEntries", "realpath"];+export declare function createVirtualFileSystem(files: Record<string, string>): FileSystem;+//# sourceMappingURL=fs.d.ts.map
dist/api/fs.js +109 lines
--- +++ @@ -0,0 +1,109 @@+import { getPathComponents } from "./path.js";+/** The callback names supported by the Go server for virtual FS delegation. */+export const fsCallbackNames = ["readFile", "fileExists", "directoryExists", "getAccessibleEntries", "realpath"];+export function createVirtualFileSystem(files) {+    const root = {+        type: "directory",+        children: {},+    };+    const content = {};+    for (const filePath of Object.keys(files)) {+        content[filePath] = files[filePath];+        addToTree(filePath);+    }+    return {+        directoryExists,+        fileExists,+        getAccessibleEntries,+        readFile,+        realpath: path => path,+        writeFile,+        removeFile,+    };+    function getNodeFromPath(path) {+        if (!path || path === "/") {+            return root;+        }+        const segments = getPathComponents(path).slice(1);+        let current = root;+        for (const segment of segments) {+            if (current.type !== "directory") {+                return undefined;+            }+            const child = current.children[segment];+            if (!child) {+                return undefined;+            }+            current = child;+        }+        return current;+    }+    function ensureDirectory(segments) {+        let current = root;+        for (const segment of segments) {+            if (!current.children[segment]) {+                current.children[segment] = { type: "directory", children: {} };+            }+            else if (current.children[segment].type !== "directory") {+                throw new Error(`Cannot create directory: a file already exists at "/${segments.join("/")}"`);+            }+            current = current.children[segment];+        }+        return current;+    }+    function addToTree(path) {+        const segments = getPathComponents(path).slice(1);+        if (segments.length === 0) {+            throw new Error(`Invalid file path: "${path}"`);+        }+        const filename = segments.pop();+        const dirNode = ensureDirectory(segments);+        dirNode.children[filename] = { type: "file" };+    }+    function writeFile(path, data) {+        content[path] = data;+        addToTree(path);+    }+    function removeFile(path) {+        delete content[path];+        const segments = getPathComponents(path).slice(1);+        if (segments.length === 0)+            return;+        const filename = segments.pop();+        const dirNode = getNodeFromPath("/" + segments.join("/"));+        if (dirNode && dirNode.type === "directory") {+            delete dirNode.children[filename];+        }+    }+    function directoryExists(directoryName) {+        const node = getNodeFromPath(directoryName);+        return !!node && node.type === "directory";+    }+    function fileExists(fileName) {+        return fileName in content;+    }+    function getAccessibleEntries(directoryName) {+        const node = getNodeFromPath(directoryName);+        if (!node || node.type !== "directory") {+            return undefined;+        }+        const fileEntries = [];+        const directories = [];+        for (const [name, child] of Object.entries(node.children)) {+            if (child.type === "file") {+                fileEntries.push(name);+            }+            else {+                directories.push(name);+            }+        }+        return { files: fileEntries, directories };+    }+    function readFile(fileName) {+        if (fileName in content) {+            return content[fileName];+        }+        return undefined;+    }+}+//# sourceMappingURL=fs.js.map
dist/api/node/encoder.d.ts +15 lines
--- +++ @@ -0,0 +1,15 @@+import type { Node, SourceFile } from "../../ast/index.ts";+/**+ * Encode a SourceFile AST node into the binary format.+ */+export declare function encodeSourceFile(sourceFile: SourceFile): Uint8Array;+/**+ * Encode an arbitrary AST node into the binary format.+ * When encoding a non-SourceFile node, the header hash and parse options fields will be zero.+ */+export declare function encodeNode(node: Node): Uint8Array;+/**+ * Encode a Uint8Array to a base64 string.+ */+export declare function uint8ArrayToBase64(data: Uint8Array): string;+//# sourceMappingURL=encoder.d.ts.map
dist/api/node/encoder.generated.d.ts +5 lines
--- +++ @@ -0,0 +1,5 @@+import type { Node } from "../../ast/index.ts";+import { SyntaxKind } from "../../ast/index.ts";+export declare function getNodeDataType(kind: SyntaxKind): number;+export declare function getNodeCommonData(node: Node): number;+//# sourceMappingURL=encoder.generated.d.ts.map
dist/api/node/encoder.generated.js +74 lines
--- +++ @@ -0,0 +1,74 @@+// Code generated by _scripts/generate-encoder.ts. DO NOT EDIT.+import { SyntaxKind } from "../../ast/index.js";+import { NODE_DATA_TYPE_CHILDREN, NODE_DATA_TYPE_EXTENDED, NODE_DATA_TYPE_STRING, } from "./protocol.js";+export function getNodeDataType(kind) {+    switch (kind) {+        case SyntaxKind.Identifier:+        case SyntaxKind.PrivateIdentifier:+        case SyntaxKind.JsxText:+        case SyntaxKind.JSDocText:+        case SyntaxKind.JSDocLink:+        case SyntaxKind.JSDocLinkPlain:+        case SyntaxKind.JSDocLinkCode:+            return NODE_DATA_TYPE_STRING;+        case SyntaxKind.StringLiteral:+        case SyntaxKind.NumericLiteral:+        case SyntaxKind.BigIntLiteral:+        case SyntaxKind.RegularExpressionLiteral:+        case SyntaxKind.NoSubstitutionTemplateLiteral:+        case SyntaxKind.TemplateHead:+        case SyntaxKind.TemplateMiddle:+        case SyntaxKind.TemplateTail:+        case SyntaxKind.SourceFile:+            return NODE_DATA_TYPE_EXTENDED;+        default:+            return NODE_DATA_TYPE_CHILDREN;+    }+}+export function getNodeCommonData(node) {+    switch (node.kind) {+        case SyntaxKind.Block:+            return (node.multiLine ? 1 : 0) << 24;+        case SyntaxKind.HeritageClause:+            return (node.token === SyntaxKind.ImplementsKeyword ? 1 : 0) << 24;+        case SyntaxKind.ExportAssignment:+            return (node.isExportEquals ? 1 : 0) << 24;+        case SyntaxKind.ExportSpecifier:+            return (node.isTypeOnly ? 1 : 0) << 24;+        case SyntaxKind.PrefixUnaryExpression:+            return (node.operator === SyntaxKind.MinusToken ? 1 : node.operator === SyntaxKind.TildeToken ? 2 : node.operator === SyntaxKind.ExclamationToken ? 3 : node.operator === SyntaxKind.PlusPlusToken ? 4 : node.operator === SyntaxKind.MinusMinusToken ? 5 : 0) << 24;+        case SyntaxKind.PostfixUnaryExpression:+            return (node.operator === SyntaxKind.MinusMinusToken ? 1 : 0) << 24;+        case SyntaxKind.MetaProperty:+            return (node.keywordToken === SyntaxKind.NewKeyword ? 1 : 0) << 24;+        case SyntaxKind.ArrayLiteralExpression:+            return (node.multiLine ? 1 : 0) << 24;+        case SyntaxKind.ObjectLiteralExpression:+            return (node.multiLine ? 1 : 0) << 24;+        case SyntaxKind.TypeOperator:+            return (node.operator === SyntaxKind.ReadonlyKeyword ? 1 : node.operator === SyntaxKind.UniqueKeyword ? 2 : 0) << 24;+        case SyntaxKind.ImportAttributes:+            return (node.multiLine ? 1 : 0) << 24 | (node.token === SyntaxKind.AssertKeyword ? 1 : 0) << 25;+        case SyntaxKind.JsxText:+            return (node.containsOnlyTriviaWhiteSpaces ? 1 : 0) << 24;+        case SyntaxKind.ModuleDeclaration:+            return (node.keyword === SyntaxKind.NamespaceKeyword ? 1 : 0) << 24;+        case SyntaxKind.ImportEqualsDeclaration:+            return (node.isTypeOnly ? 1 : 0) << 24;+        case SyntaxKind.ExportDeclaration:+            return (node.isTypeOnly ? 1 : 0) << 24;+        case SyntaxKind.ImportType:+            return (node.isTypeOf ? 1 : 0) << 24;+        case SyntaxKind.ImportClause:+            return (node.phaseModifier === SyntaxKind.TypeKeyword ? 1 : node.phaseModifier === SyntaxKind.DeferKeyword ? 2 : 0) << 24;+        case SyntaxKind.ImportSpecifier:+            return (node.isTypeOnly ? 1 : 0) << 24;+        case SyntaxKind.JSDocTypeLiteral:+            return (node.isArrayType ? 1 : 0) << 24;+        case SyntaxKind.JSDocParameterTag:+        case SyntaxKind.JSDocPropertyTag:+            return (node.isBracketed ? 1 : 0) << 24 | (node.isNameFirst ? 1 : 0) << 25;+    }+    return 0;+}+//# sourceMappingURL=encoder.generated.js.map
dist/api/node/encoder.js +287 lines
--- +++ @@ -0,0 +1,287 @@+import { SyntaxKind } from "../../ast/index.js";+import { getNodeCommonData, getNodeDataType, } from "./encoder.generated.js";+import { MsgpackWriter } from "./msgpack.js";+import { childProperties, HEADER_OFFSET_EXTENDED_DATA, HEADER_OFFSET_METADATA, HEADER_OFFSET_NODES, HEADER_OFFSET_STRING_TABLE, HEADER_OFFSET_STRING_TABLE_OFFSETS, HEADER_OFFSET_STRUCTURED_DATA, HEADER_SIZE, KIND_NODE_LIST, NODE_DATA_TYPE_CHILDREN, NODE_DATA_TYPE_EXTENDED, NODE_DATA_TYPE_STRING, NODE_LEN, PROTOCOL_VERSION, } from "./protocol.js";+const NODE_FIELDS = NODE_LEN / 4;+const NODE_FIELD_NEXT = 3;+const NO_STRUCTURED_DATA = 0xFFFFFFFF;+// String table that accumulates strings into a flat byte pool.+class StringTable {+    parts;+    byteLen;+    offsets;+    constructor() {+        this.parts = [];+        this.byteLen = 0;+        this.offsets = [];+    }+    add(text) {+        const index = this.offsets.length;+        const encoder = cachedEncoder();+        const encodedLength = encoder.encode(text).length;+        const offset = this.byteLen;+        this.parts.push(text);+        this.byteLen += encodedLength;+        this.offsets.push(offset, offset + encodedLength);+        return index;+    }+    encode() {+        const encoder = cachedEncoder();+        const dataBytes = encoder.encode(this.parts.join(""));+        const offsetBytes = new Uint8Array(this.offsets.length * 4);+        const view = new DataView(offsetBytes.buffer);+        for (let i = 0; i < this.offsets.length; i++) {+            view.setUint32(i * 4, this.offsets[i], true);+        }+        const result = new Uint8Array(offsetBytes.length + dataBytes.length);+        result.set(offsetBytes, 0);+        result.set(dataBytes, offsetBytes.length);+        return result;+    }+    stringByteLength() {+        return this.byteLen;+    }+    offsetsCount() {+        return this.offsets.length;+    }+}+let _encoder;+function cachedEncoder() {+    return _encoder ??= new TextEncoder();+}+function getChildrenPropertyMask(node) {+    const kind = node.kind;+    const props = childProperties[kind];+    if (!props) {+        return 0;+    }+    const n = node;+    let mask = 0;+    for (let i = 0; i < props.length; i++) {+        const prop = props[i];+        if (prop !== undefined && isChildPresent(n[prop])) {+            mask |= 1 << i;+        }+    }+    return mask;+}+// A child is "present" if it's non-null/non-undefined.+// This matches the Go encoder's behavior where non-nil NodeLists (even empty)+// are treated as present, and only nil NodeLists are absent.+function isChildPresent(v) {+    if (v === undefined || v === null)+        return false;+    return true;+}+function recordNodeStrings(node, strs) {+    return strs.add(node.text ?? "");+}+function encodeFileReferences(refs, writer) {+    if (!refs || refs.length === 0)+        return NO_STRUCTURED_DATA;+    const offset = writer.finish().length;+    writer.writeArrayHeader(refs.length);+    for (const ref of refs) {+        writer.writeArrayHeader(5);+        writer.writeUint(ref.pos);+        writer.writeUint(ref.end);+        writer.writeString(ref.fileName);+        writer.writeUint(ref.resolutionMode ?? 0);+        writer.writeBool(ref.preserve ?? false);+    }+    return offset;+}+function recordExtendedData(node, strs, extendedData, structuredWriter) {+    const offset = extendedData.length * 4;+    if (node.kind === SyntaxKind.SourceFile) {+        const sf = node;+        const textIndex = strs.add(sf.text);+        const fileNameIndex = strs.add(sf.fileName);+        const pathIndex = strs.add(sf.path);+        const referencedFilesOffset = encodeFileReferences(sf.referencedFiles, structuredWriter);+        const typeRefDirectivesOffset = encodeFileReferences(sf.typeReferenceDirectives, structuredWriter);+        const libRefDirectivesOffset = encodeFileReferences(sf.libReferenceDirectives, structuredWriter);+        extendedData.push(textIndex, fileNameIndex, pathIndex, sf.languageVariant, sf.scriptKind, referencedFilesOffset, typeRefDirectivesOffset, libRefDirectivesOffset, NO_STRUCTURED_DATA, NO_STRUCTURED_DATA, NO_STRUCTURED_DATA, 0);+    }+    else if (node.kind === SyntaxKind.TemplateHead ||+        node.kind === SyntaxKind.TemplateMiddle ||+        node.kind === SyntaxKind.TemplateTail) {+        const tmpl = node;+        const text = tmpl.text ?? "";+        const rawText = tmpl.rawText ?? "";+        const templateFlags = tmpl.templateFlags ?? 0;+        const textIndex = strs.add(text);+        const rawTextIndex = strs.add(rawText);+        extendedData.push(textIndex, rawTextIndex, templateFlags);+    }+    else {+        // StringLiteral, NumericLiteral, BigIntLiteral, RegularExpressionLiteral,+        // NoSubstitutionTemplateLiteral — format: [textIndex, tokenFlags]+        const n = node;+        const text = n.text ?? "";+        const tokenFlags = n.tokenFlags ?? 0;+        const textIndex = strs.add(text);+        extendedData.push(textIndex, tokenFlags);+    }+    return offset;+}+function getNodeData(node, strs, extendedData, structuredWriter) {+    const t = getNodeDataType(node.kind);+    const common = getNodeCommonData(node);+    switch (t) {+        case NODE_DATA_TYPE_CHILDREN:+            return t | common | getChildrenPropertyMask(node);+        case NODE_DATA_TYPE_STRING:+            return t | common | recordNodeStrings(node, strs);+        case NODE_DATA_TYPE_EXTENDED:+            return t | common | recordExtendedData(node, strs, extendedData, structuredWriter);+        default:+            throw new Error("unreachable");+    }+}+function getChildPropertiesForNode(node) {+    return childProperties[node.kind];+}+// Returns whether a value is a NodeArray (array-like with pos and end).+function isNodeArray(value) {+    return Array.isArray(value) && typeof value.pos === "number" && typeof value.end === "number";+}+/**+ * Encode a SourceFile AST node into the binary format.+ */+export function encodeSourceFile(sourceFile) {+    return encodeNode(sourceFile);+}+/**+ * Encode an arbitrary AST node into the binary format.+ * When encoding a non-SourceFile node, the header hash and parse options fields will be zero.+ */+export function encodeNode(node) {+    const strs = new StringTable();+    const extendedDataValues = [];+    const structuredWriter = new MsgpackWriter();+    // We'll build an array of uint32 values for the nodes section, 7 per node+    const nodeValues = [];+    // Nil node (index 0)+    nodeValues.push(0, 0, 0, 0, 0, 0, 0);+    let nodeCount = 0;+    let parentIndex = 0;+    let prevIndex = 0;+    function visitNode(node) {+        nodeCount++;+        const currentIndex = nodeCount;+        if (prevIndex !== 0) {+            // Set next pointer on previous sibling+            nodeValues[prevIndex * NODE_FIELDS + NODE_FIELD_NEXT] = currentIndex;+        }+        const data = getNodeData(node, strs, extendedDataValues, structuredWriter);+        nodeValues.push(node.kind, node.pos >= 0 ? node.pos : 0, node.end >= 0 ? node.end : 0, 0, // next (filled in later)+        parentIndex, data, node.flags);+        const saveParentIndex = parentIndex;+        const savePrevIndex = prevIndex;+        parentIndex = currentIndex;+        prevIndex = 0;+        visitChildren(node);+        prevIndex = currentIndex;+        parentIndex = saveParentIndex;+    }+    function visitNodeList(list) {+        if (!list) {+            return;+        }+        nodeCount++;+        const currentIndex = nodeCount;+        if (prevIndex !== 0) {+            nodeValues[prevIndex * NODE_FIELDS + NODE_FIELD_NEXT] = currentIndex;+        }+        nodeValues.push(KIND_NODE_LIST, list.pos >= 0 ? list.pos : 0, list.end >= 0 ? list.end : 0, 0, // next+        parentIndex, list.length, // data for NodeList is its length+        0);+        const saveParentIndex = parentIndex;+        parentIndex = currentIndex;+        prevIndex = 0;+        for (const child of list) {+            visitNode(child);+        }+        prevIndex = currentIndex;+        parentIndex = saveParentIndex;+    }+    function visitChildren(node) {+        const props = getChildPropertiesForNode(node);+        const n = node;+        if (props) {+            for (const propName of props) {+                if (propName === undefined)+                    continue;+                const child = n[propName];+                if (child === undefined || child === null)+                    continue;+                if (isNodeArray(child)) {+                    visitNodeList(child);+                }+                else {+                    visitNode(child);+                }+            }+        }+    }+    // Encode root node+    nodeCount++;+    parentIndex++;+    const rootData = getNodeData(node, strs, extendedDataValues, structuredWriter);+    nodeValues.push(node.kind, node.pos >= 0 ? node.pos : 0, node.end >= 0 ? node.end : 0, 0, 0, rootData, node.flags);+    const saveParent = parentIndex;+    prevIndex = 0;+    parentIndex = 1; // root is at index 1+    visitChildren(node);+    parentIndex = saveParent;+    // Encode extended data section+    const extendedDataBytes = new Uint8Array(extendedDataValues.length * 4);+    const extView = new DataView(extendedDataBytes.buffer);+    for (let i = 0; i < extendedDataValues.length; i++) {+        extView.setUint32(i * 4, extendedDataValues[i], true);+    }+    // Encode structured data section+    const structuredDataBytes = structuredWriter.finish();+    // Encode string table+    const strsBytes = strs.encode();
… 40 more lines (truncated)
dist/api/node/msgpack.d.ts +32 lines
--- +++ @@ -0,0 +1,32 @@+export declare const MSGPACK_FIXARRAY3 = 147;+export declare const MSGPACK_BIN8 = 196;+export declare const MSGPACK_BIN16 = 197;+export declare const MSGPACK_BIN32 = 198;+export declare const MSGPACK_UINT8 = 204;+/** Compute the MessagePack bin header size for a given data length. */+export declare function binHeaderSize(len: number): number;+/** Write a MessagePack bin header into `buf` at `off`, return new offset. */+export declare function writeBinHeader(buf: Uint8Array, off: number, len: number): number;+export declare class MsgpackWriter {+    private buf;+    private view;+    private pos;+    constructor(initialSize?: number);+    private ensure;+    writeArrayHeader(length: number): void;+    writeUint(value: number): void;+    writeString(str: string): void;+    writeBool(value: boolean): void;+    finish(): Uint8Array;+}+export declare class MsgpackReader {+    private buf;+    private view;+    private pos;+    constructor(data: Uint8Array, offset?: number);+    readArrayHeader(): number;+    readUint(): number;+    readString(): string;+    readBool(): boolean;+}+//# sourceMappingURL=msgpack.d.ts.map
dist/api/node/msgpack.js +213 lines
--- +++ @@ -0,0 +1,213 @@+// Minimal msgpack encoder/decoder.+// Supports: arrays, unsigned integers, strings, booleans, binary data.+import { Wtf8Decoder } from "./wtf8.js";+// ── MessagePack format constants ────────────────────────────────────+export const MSGPACK_FIXARRAY3 = 0x93; // 3-element fixarray+export const MSGPACK_BIN8 = 0xc4;+export const MSGPACK_BIN16 = 0xc5;+export const MSGPACK_BIN32 = 0xc6;+export const MSGPACK_UINT8 = 0xcc;+// ── Bin header helpers ──────────────────────────────────────────────+/** Compute the MessagePack bin header size for a given data length. */+export function binHeaderSize(len) {+    if (len < 0x100)+        return 2; // BIN8: marker + 1-byte size+    if (len < 0x10000)+        return 3; // BIN16: marker + 2-byte size+    return 5; // BIN32: marker + 4-byte size+}+/** Write a MessagePack bin header into `buf` at `off`, return new offset. */+export function writeBinHeader(buf, off, len) {+    if (len < 0x100) {+        buf[off++] = MSGPACK_BIN8;+        buf[off++] = len;+    }+    else if (len < 0x10000) {+        buf[off++] = MSGPACK_BIN16;+        buf[off++] = (len >>> 8) & 0xff;+        buf[off++] = len & 0xff;+    }+    else {+        buf[off++] = MSGPACK_BIN32;+        buf[off++] = (len >>> 24) & 0xff;+        buf[off++] = (len >>> 16) & 0xff;+        buf[off++] = (len >>> 8) & 0xff;+        buf[off++] = len & 0xff;+    }+    return off;+}+const encoder = new TextEncoder();+const decoder = new Wtf8Decoder();+export class MsgpackWriter {+    buf;+    view;+    pos;+    constructor(initialSize = 256) {+        this.buf = new Uint8Array(initialSize);+        this.view = new DataView(this.buf.buffer);+        this.pos = 0;+    }+    ensure(n) {+        if (this.pos + n > this.buf.length) {+            let newSize = this.buf.length * 2;+            while (newSize < this.pos + n)+                newSize *= 2;+            const next = new Uint8Array(newSize);+            next.set(this.buf);+            this.buf = next;+            this.view = new DataView(this.buf.buffer);+        }+    }+    writeArrayHeader(length) {+        if (length <= 0x0f) {+            this.ensure(1);+            this.buf[this.pos++] = 0x90 | length;+        }+        else if (length <= 0xffff) {+            this.ensure(3);+            this.buf[this.pos++] = 0xdc;+            this.view.setUint16(this.pos, length, false);+            this.pos += 2;+        }+        else {+            this.ensure(5);+            this.buf[this.pos++] = 0xdd;+            this.view.setUint32(this.pos, length, false);+            this.pos += 4;+        }+    }+    writeUint(value) {+        if (value <= 0x7f) {+            this.ensure(1);+            this.buf[this.pos++] = value;+        }+        else if (value <= 0xff) {+            this.ensure(2);+            this.buf[this.pos++] = 0xcc;+            this.buf[this.pos++] = value;+        }+        else if (value <= 0xffff) {+            this.ensure(3);+            this.buf[this.pos++] = 0xcd;+            this.view.setUint16(this.pos, value, false);+            this.pos += 2;+        }+        else {+            this.ensure(5);+            this.buf[this.pos++] = 0xce;+            this.view.setUint32(this.pos, value, false);+            this.pos += 4;+        }+    }+    writeString(str) {+        const encoded = encoder.encode(str);+        const len = encoded.length;+        if (len <= 0x1f) {+            this.ensure(1 + len);+            this.buf[this.pos++] = 0xa0 | len;+        }+        else if (len <= 0xff) {+            this.ensure(2 + len);+            this.buf[this.pos++] = 0xd9;+            this.buf[this.pos++] = len;+        }+        else if (len <= 0xffff) {+            this.ensure(3 + len);+            this.buf[this.pos++] = 0xda;+            this.view.setUint16(this.pos, len, false);+            this.pos += 2;+        }+        else {+            this.ensure(5 + len);+            this.buf[this.pos++] = 0xdb;+            this.view.setUint32(this.pos, len, false);+            this.pos += 4;+        }+        this.buf.set(encoded, this.pos);+        this.pos += len;+    }+    writeBool(value) {+        this.ensure(1);+        this.buf[this.pos++] = value ? 0xc3 : 0xc2;+    }+    finish() {+        return this.buf.subarray(0, this.pos);+    }+}+export class MsgpackReader {+    buf;+    view;+    pos;+    constructor(data, offset = 0) {+        this.buf = data;+        this.view = new DataView(data.buffer, data.byteOffset, data.byteLength);+        this.pos = offset;+    }+    readArrayHeader() {+        const byte = this.buf[this.pos++];+        if ((byte & 0xf0) === 0x90)+            return byte & 0x0f;+        if (byte === 0xdc) {+            const len = this.view.getUint16(this.pos, false);+            this.pos += 2;+            return len;+        }+        if (byte === 0xdd) {+            const len = this.view.getUint32(this.pos, false);+            this.pos += 4;+            return len;+        }+        throw new Error(`Expected array header, got 0x${byte.toString(16)}`);+    }+    readUint() {+        const byte = this.buf[this.pos++];+        if (byte <= 0x7f)+            return byte;+        if (byte === 0xcc)+            return this.buf[this.pos++];+        if (byte === 0xcd) {+            const val = this.view.getUint16(this.pos, false);+            this.pos += 2;+            return val;+        }+        if (byte === 0xce) {+            const val = this.view.getUint32(this.pos, false);+            this.pos += 4;+            return val;+        }+        throw new Error(`Expected uint, got 0x${byte.toString(16)}`);+    }+    readString() {+        const byte = this.buf[this.pos++];+        let len;+        if ((byte & 0xe0) === 0xa0) {+            len = byte & 0x1f;+        }+        else if (byte === 0xd9) {+            len = this.buf[this.pos++];+        }+        else if (byte === 0xda) {+            len = this.view.getUint16(this.pos, false);+            this.pos += 2;+        }+        else if (byte === 0xdb) {+            len = this.view.getUint32(this.pos, false);+            this.pos += 4;+        }+        else {+            throw new Error(`Expected string, got 0x${byte.toString(16)}`);+        }+        const str = decoder.decode(this.buf.subarray(this.pos, this.pos + len));+        this.pos += len;+        return str;+    }+    readBool() {+        const byte = this.buf[this.pos++];+        if (byte === 0xc3)+            return true;+        if (byte === 0xc2)+            return false;+        throw new Error(`Expected bool, got 0x${byte.toString(16)}`);+    }+}+//# sourceMappingURL=msgpack.js.map
dist/api/node/node.d.ts +76 lines
--- +++ @@ -0,0 +1,76 @@+import { type FileReference, type LineAndCharacter, type Node, type Path, SyntaxKind } from "../../ast/index.ts";+import type { TimingCollector } from "../timing.ts";+import { RemoteNode, RemoteNodeList } from "./node.generated.ts";+import { type SourceFileInfo, type TextDecoder } from "./node.infrastructure.ts";+export { RemoteNode, RemoteNodeList } from "./node.generated.ts";+export { readParseOptionsKey, readSourceFileHash, RemoteNodeBase } from "./node.infrastructure.ts";+export declare class RemoteSourceFile extends RemoteNode implements SourceFileInfo {+    readonly nodes: (RemoteNode | RemoteNodeList)[];+    readonly _offsetNodes: number;+    readonly _offsetStringTableOffsets: number;+    readonly _offsetStringTable: number;+    readonly _offsetExtendedData: number;+    readonly _offsetStructuredData: number;+    readonly _decoder: TextDecoder;+    readonly _timing: TimingCollector | undefined;+    private _lineStarts;+    private _cachedText;+    private _cachedReferencedFiles;+    private _cachedTypeReferenceDirectives;+    private _cachedLibReferenceDirectives;+    private _cachedImports;+    private _cachedModuleAugmentations;+    private _cachedAmbientModuleNames;+    constructor(data: Uint8Array, decoder: TextDecoder, timing?: TimingCollector);+    readFileReferences(structuredDataOffset: number): readonly FileReference[];+    readNodeIndexArray(structuredDataOffset: number): readonly Node[];+    readStringArray(structuredDataOffset: number): readonly string[];+    /** @internal */+    getOrCreateNodeAtIndex(index: number): Node;+    private get extendedDataOffset();+    get fileName(): string;+    get path(): string;+    get languageVariant(): number;+    get scriptKind(): number;+    get referencedFiles(): readonly FileReference[];+    get typeReferenceDirectives(): readonly FileReference[];+    get libReferenceDirectives(): readonly FileReference[];+    get imports(): readonly Node[];+    get moduleAugmentations(): readonly Node[];+    get ambientModuleNames(): readonly string[];+    get externalModuleIndicator(): Node | true | undefined;+    get isDeclarationFile(): boolean;+    get text(): string;+    getLineStarts(): readonly number[];+    getLineAndCharacterOfPosition(position: number): LineAndCharacter;+    getPositionOfLineAndCharacter(line: number, character: number): number;+}+/**+ * Find a descendant node at a specific position with matching kind and end position.+ */+export declare function findDescendant(root: Node, pos: number, end: number, kind: SyntaxKind): Node | undefined;+/**+ * Parsed components of a node handle.+ */+export interface ParsedNodeHandle {+    index: number;+    kind: SyntaxKind;+    path: Path;+}+/**+ * Parse a node handle string into its components.+ * Handle format: "index.kind.path" where path may contain dots.+ */+export declare function parseNodeHandle(handle: string): ParsedNodeHandle;+/**+ * Decode binary-encoded AST data into a Node.+ * Works for any binary-encoded node, including synthetic nodes+ * (e.g. from typeToTypeNode) that don't have a source file.+ */+export declare function decodeNode(data: Uint8Array): Node;+/**+ * Get the unique ID string for a remote node.+ * Throws if the node is not a RemoteNode (i.e. not decoded from binary data).+ */+export declare function getNodeId(node: Node): string;+//# sourceMappingURL=node.d.ts.map
dist/api/node/node.generated.d.ts +182 lines
--- +++ @@ -0,0 +1,182 @@+import { ModifierFlags, type Node, type NodeArray, type SourceFile, SyntaxKind } from "../../ast/index.ts";+import { RemoteNodeBase, type SourceFileInfo } from "./node.infrastructure.ts";+export declare class RemoteNodeList extends Array<RemoteNode> implements NodeArray<RemoteNode> {+    static get [Symbol.species](): ArrayConstructor;+    parent: RemoteNode;+    hasTrailingComma?: boolean;+    transformFlags: number;+    protected view: DataView;+    protected index: number;+    private _byteIndex;+    private _cursorIndex;+    private _cursorNodeIndex;+    get pos(): number;+    get end(): number;+    get next(): number;+    private get data();+    private sourceFile;+    constructor(view: DataView, index: number, parent: RemoteNode, sourceFile: SourceFileInfo, offsetNodes: number);+    get 0(): RemoteNode;+    get 1(): RemoteNode;+    get 2(): RemoteNode;+    get 3(): RemoteNode;+    get 4(): RemoteNode;+    get 5(): RemoteNode;+    get 6(): RemoteNode;+    get 7(): RemoteNode;+    get 8(): RemoteNode;+    get 9(): RemoteNode;+    get 10(): RemoteNode;+    get 11(): RemoteNode;+    get 12(): RemoteNode;+    get 13(): RemoteNode;+    get 14(): RemoteNode;+    get 15(): RemoteNode;+    [Symbol.iterator](): ArrayIterator<RemoteNode>;+    forEachNode<T>(visitNode: (node: RemoteNode) => T | undefined): T | undefined;+    at(index: number): RemoteNode;+    private getOrCreateChildAtNodeIndex;+    __print(): string;+}+export declare class RemoteNode extends RemoteNodeBase implements Node {+    protected static NODE_LEN: number;+    protected get sourceFile(): SourceFileInfo;+    protected _sourceFile: SourceFileInfo;+    get id(): string;+    constructor(view: DataView, index: number, parent: RemoteNode, sourceFile: SourceFileInfo, offsetNodes: number);+    forEachChild<T>(visitNode: (node: Node) => T, visitList?: (list: NodeArray<Node>) => T): T | undefined;+    get jsDoc(): readonly Node[] | undefined;+    getSourceFile(): SourceFile;+    getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number;+    getFullStart(): number;+    getEnd(): number;+    getWidth(sourceFile?: SourceFile): number;+    getFullWidth(): number;+    getLeadingTriviaWidth(sourceFile?: SourceFile): number;+    getFullText(sourceFile?: SourceFile): string;+    getText(sourceFile?: SourceFile): string;+    protected getString(index: number): string;+    private getOrCreateChildAtNodeIndex;+    private hasChildren;+    private getNamedChild;+    private getChildAtOrder;+    __print(): string;+    __printChildren(): string;+    __printSubtree(): string;+    get containsOnlyTriviaWhiteSpaces(): boolean;+    get isArrayType(): boolean;+    get isBracketed(): boolean;+    get isExportEquals(): boolean;+    get isNameFirst(): boolean;+    get isTypeOf(): boolean;+    get isTypeOnly(): boolean;+    get multiLine(): boolean;+    get keyword(): SyntaxKind | undefined;+    get keywordToken(): SyntaxKind | undefined;+    get operator(): SyntaxKind | undefined;+    get phaseModifier(): SyntaxKind | undefined;+    get token(): SyntaxKind | undefined;+    get templateFlags(): number | undefined;+    get tokenFlags(): number;+    get argument(): RemoteNode | undefined;+    get argumentExpression(): RemoteNode | undefined;+    get arguments(): RemoteNodeList | undefined;+    get assertsModifier(): RemoteNode | undefined;+    get asteriskToken(): RemoteNode | undefined;+    get attributes(): RemoteNode | RemoteNodeList | undefined;+    get awaitModifier(): RemoteNode | undefined;+    get block(): RemoteNode | undefined;+    get body(): RemoteNode | undefined;+    get caseBlock(): RemoteNode | undefined;+    get catchClause(): RemoteNode | undefined;+    get checkType(): RemoteNode | undefined;+    get children(): RemoteNode | RemoteNodeList | undefined;+    get className(): RemoteNode | undefined;+    get clauses(): RemoteNodeList | undefined;+    get closingElement(): RemoteNode | undefined;+    get closingFragment(): RemoteNode | undefined;+    get colonToken(): RemoteNode | undefined;+    get comment(): RemoteNodeList | undefined;+    get condition(): RemoteNode | undefined;+    get constraint(): RemoteNode | undefined;+    get declarationList(): RemoteNode | undefined;+    get declarations(): RemoteNodeList | undefined;+    get defaultType(): RemoteNode | undefined;+    get dotDotDotToken(): RemoteNode | undefined;+    get elements(): RemoteNodeList | undefined;+    get elementType(): RemoteNode | undefined;+    get elseStatement(): RemoteNode | undefined;+    get endOfFileToken(): RemoteNode | undefined;+    get equalsGreaterThanToken(): RemoteNode | undefined;+    get equalsToken(): RemoteNode | undefined;+    get exclamationToken(): RemoteNode | undefined;+    get exportClause(): RemoteNode | undefined;+    get expression(): RemoteNode | undefined;+    get exprName(): RemoteNode | undefined;+    get extendsType(): RemoteNode | undefined;+    get falseType(): RemoteNode | undefined;+    get finallyBlock(): RemoteNode | undefined;+    get head(): RemoteNode | undefined;+    get heritageClauses(): RemoteNodeList | undefined;+    get importClause(): RemoteNode | undefined;+    get incrementor(): RemoteNode | undefined;+    get indexType(): RemoteNode | undefined;+    get initializer(): RemoteNode | undefined;+    get jsdocPropertyTags(): RemoteNode | undefined;+    get label(): RemoteNode | undefined;+    get left(): RemoteNode | undefined;+    get literal(): RemoteNode | undefined;+    get members(): RemoteNodeList | undefined;+    get modifiers(): RemoteNodeList | undefined;+    get moduleReference(): RemoteNode | undefined;+    get moduleSpecifier(): RemoteNode | undefined;+    get name(): RemoteNode | undefined;+    get namedBindings(): RemoteNode | undefined;+    get nameExpression(): RemoteNode | undefined;+    get namespace(): RemoteNode | undefined;+    get nameType(): RemoteNode | undefined;+    get objectAssignmentInitializer(): RemoteNode | undefined;+    get objectType(): RemoteNode | undefined;+    get openingElement(): RemoteNode | undefined;+    get openingFragment(): RemoteNode | undefined;+    get operand(): RemoteNode | undefined;+    get operatorToken(): RemoteNode | undefined;+    get parameterName(): RemoteNode | undefined;+    get parameters(): RemoteNodeList | undefined;+    get postfixToken(): RemoteNode | undefined;+    get properties(): RemoteNodeList | undefined;+    get propertyName(): RemoteNode | undefined;+    get qualifier(): RemoteNode | undefined;+    get questionDotToken(): RemoteNode | undefined;+    get questionToken(): RemoteNode | undefined;+    get readonlyToken(): RemoteNode | undefined;+    get right(): RemoteNode | undefined;+    get statement(): RemoteNode | undefined;+    get statements(): RemoteNodeList | undefined;+    get tag(): RemoteNode | undefined;+    get tagName(): RemoteNode | undefined;+    get tags(): RemoteNodeList | undefined;+    get template(): RemoteNode | undefined;+    get templateSpans(): RemoteNodeList | undefined;+    get thenStatement(): RemoteNode | undefined;+    get thisArg(): RemoteNode | undefined;+    get trueType(): RemoteNode | undefined;+    get tryBlock(): RemoteNode | undefined;+    get tupleNameSource(): RemoteNode | undefined;+    get type(): RemoteNode | undefined;+    get typeArguments(): RemoteNodeList | undefined;+    get typeExpression(): RemoteNode | undefined;+    get typeName(): RemoteNode | undefined;+    get typeParameter(): RemoteNode | undefined;+    get typeParameters(): RemoteNodeList | undefined;+    get types(): RemoteNodeList | undefined;+    get value(): RemoteNode | undefined;+    get variableDeclaration(): RemoteNode | undefined;+    get whenFalse(): RemoteNode | undefined;+    get whenTrue(): RemoteNode | undefined;+    get text(): string | undefined;+    get rawText(): string | undefined;+    get flags(): number;+    get modifierFlags(): ModifierFlags;+}+//# sourceMappingURL=node.generated.d.ts.map
dist/api/node/node.generated.js +835 lines
--- +++ @@ -0,0 +1,835 @@+// Code generated by _scripts/generate-encoder.ts. DO NOT EDIT.+import { getTokenPosOfNode, ModifierFlags, SyntaxKind, } from "../../ast/index.js";+import { modifierToFlag, NODE_CHILD_MASK, NODE_DATA_TYPE_MASK, NODE_EXTENDED_DATA_MASK, NODE_STRING_INDEX_MASK, popcount8, RemoteNodeBase, } from "./node.infrastructure.js";+import { childProperties, KIND_NODE_LIST, NODE_DATA_TYPE_CHILDREN, NODE_DATA_TYPE_EXTENDED, NODE_DATA_TYPE_STRING, NODE_LEN, NODE_OFFSET_DATA, NODE_OFFSET_END, NODE_OFFSET_FLAGS, NODE_OFFSET_KIND, NODE_OFFSET_NEXT, NODE_OFFSET_PARENT, NODE_OFFSET_POS, } from "./protocol.js";+export class RemoteNodeList extends Array {+    // Inherited Array methods like filter/map/slice use ArraySpeciesCreate, which would+    // otherwise call `new RemoteNodeList(length)` and fail. Produce a plain Array instead.+    static get [Symbol.species]() {+        return Array;+    }+    parent;+    hasTrailingComma;+    transformFlags = 0;+    view;+    index;+    _byteIndex;+    // Cursor memoizing the last resolved (logical index -> node index) so that+    // sequential forward access (index loops and list[i], plus forEach/map/+    // reduce/filter) resumes instead of re-walking from the head, turning an+    // O(n) pass over the whole list from O(n^2) into O(n).+    _cursorIndex = 0;+    _cursorNodeIndex = 0;+    get pos() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_POS, true);+    }+    get end() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_END, true);+    }+    get next() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_NEXT, true);+    }+    get data() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_DATA, true);+    }+    sourceFile;+    constructor(view, index, parent, sourceFile, offsetNodes) {+        super();+        this.view = view;+        this.index = index;+        this.parent = parent;+        this.sourceFile = sourceFile;+        this._byteIndex = offsetNodes + index * NODE_LEN;+        this.length = this.data;+        this._cursorNodeIndex = index + 1;+        const length = this.length;+        for (let i = 16; i < length; i++) {+            Object.defineProperty(this, i, {+                get() {+                    return this.at(i);+                },+            });+        }+    }+    get 0() {+        return this.at(0);+    }+    get 1() {+        return this.at(1);+    }+    get 2() {+        return this.at(2);+    }+    get 3() {+        return this.at(3);+    }+    get 4() {+        return this.at(4);+    }+    get 5() {+        return this.at(5);+    }+    get 6() {+        return this.at(6);+    }+    get 7() {+        return this.at(7);+    }+    get 8() {+        return this.at(8);+    }+    get 9() {+        return this.at(9);+    }+    get 10() {+        return this.at(10);+    }+    get 11() {+        return this.at(11);+    }+    get 12() {+        return this.at(12);+    }+    get 13() {+        return this.at(13);+    }+    get 14() {+        return this.at(14);+    }+    get 15() {+        return this.at(15);+    }+    *[Symbol.iterator]() {+        if (!this.length)+            return;+        let next = this.index + 1;+        while (next) {+            const child = this.getOrCreateChildAtNodeIndex(next);+            next = child.next;+            yield child;+        }+    }+    forEachNode(visitNode) {+        if (!this.length)+            return;+        let next = this.index + 1;+        while (next) {+            const child = this.getOrCreateChildAtNodeIndex(next);+            next = child.next;+            const result = visitNode(child);+            if (result)+                return result;+        }+    }+    at(index) {+        if (!Number.isInteger(index)) {+            return undefined;+        }+        if (index >= this.data || (index < 0 && -index > this.data)) {+            return undefined;+        }+        if (index < 0) {+            index = this.length + index;+        }+        // Walk the raw buffer following each node's `next` pointer instead of+        // materializing every intermediate RemoteNode just to read it. Resume from+        // the memoized cursor when possible so sequential forward access is O(1)+        // amortized (a full in-order pass is O(n) rather than O(n^2)).+        const offsetNodes = this.sourceFile._offsetNodes;+        let i;+        let next;+        if (index >= this._cursorIndex) {+            i = this._cursorIndex;+            next = this._cursorNodeIndex;+        }+        else {+            i = 0;+            next = this.index + 1;+        }+        for (; i < index; i++) {+            next = this.view.getUint32(offsetNodes + next * NODE_LEN + NODE_OFFSET_NEXT, true);+        }+        this._cursorIndex = index;+        this._cursorNodeIndex = next;+        return this.getOrCreateChildAtNodeIndex(next);+    }+    getOrCreateChildAtNodeIndex(index) {+        let child = this.sourceFile.nodes[index];+        if (!child) {+            const kind = this.view.getUint32(this.sourceFile._offsetNodes + index * NODE_LEN + NODE_OFFSET_KIND, true);+            if (kind === KIND_NODE_LIST) {+                throw new Error("NodeList cannot directly contain another NodeList");+            }+            const sf = this.sourceFile;+            child = new RemoteNode(this.view, index, this.parent, sf, sf._offsetNodes);+            sf.nodes[index] = child;+            sf._timing?.recordMaterialization();+        }+        return child;+    }+    __print() {+        const result = [];+        result.push(`kind: NodeList`);+        result.push(`index: ${this.index}`);+        result.push(`byteIndex: ${this._byteIndex}`);+        result.push(`length: ${this.length}`);+        return result.join("\n");+    }+}+export class RemoteNode extends RemoteNodeBase {+    static NODE_LEN = NODE_LEN;+    get sourceFile() {+        return this._sourceFile;+    }+    _sourceFile;+    get id() {+        return `${this.index}.${this.kind}.${this.sourceFile.path}`;+    }+    constructor(view, index, parent, sourceFile, offsetNodes) {+        super(view, index, parent, offsetNodes + index * NODE_LEN);+        this._sourceFile = sourceFile;+    }+    forEachChild(visitNode, visitList) {+        if (this.hasChildren()) {+            let next = this.index + 1;+            do {+                const child = this.getOrCreateChildAtNodeIndex(next);+                if (child instanceof RemoteNodeList) {+                    if (visitList) {+                        const result = visitList(child);+                        if (result) {+                            return result;+                        }+                    }+                    else {+                        const result = child.forEachNode(visitNode);+                        if (result) {+                            return result;+                        }+                    }+                }+                else if (child.kind !== SyntaxKind.JSDoc) {+                    const result = visitNode(child);+                    if (result) {+                        return result;+                    }+                }+                next = child.next;+            } while (next);+        }+    }+    get jsDoc() {+        if (!this.hasChildren()) {+            return undefined;+        }+        let result;+        let next = this.index + 1;+        do {+            const child = this.getOrCreateChildAtNodeIndex(next);+            if (!(child instanceof RemoteNodeList) && child.kind === SyntaxKind.JSDoc) {+                (result ??= []).push(child);+            }+            next = child.next;+        } while (next);+        return result;+    }+    getSourceFile() {+        return this.sourceFile;+    }+    getStart(sourceFile, includeJsDocComment) {+        return getTokenPosOfNode(this, sourceFile ?? this.getSourceFile(), includeJsDocComment);+    }+    getFullStart() {+        return this.pos;+    }+    getEnd() {+        return this.end;+    }
… 588 more lines (truncated)
dist/api/node/node.infrastructure.d.ts +62 lines
--- +++ @@ -0,0 +1,62 @@+import { type FileReference, ModifierFlags, type Node, SyntaxKind } from "../../ast/index.ts";+import type { TimingCollector } from "../timing.ts";+import { NODE_DATA_TYPE_CHILDREN, NODE_DATA_TYPE_EXTENDED, NODE_DATA_TYPE_STRING } from "./protocol.ts";+export declare const popcount8: number[];+export type NodeDataType = typeof NODE_DATA_TYPE_CHILDREN | typeof NODE_DATA_TYPE_STRING | typeof NODE_DATA_TYPE_EXTENDED;+export declare const NODE_DATA_TYPE_MASK = 3221225472;+export declare const NODE_CHILD_MASK = 255;+export declare const NODE_STRING_INDEX_MASK = 16777215;+export declare const NODE_EXTENDED_DATA_MASK = 16777215;+export interface TextDecoder {+    decode(input?: ArrayBufferView | ArrayBufferLike): string;+}+export interface SourceFileInfo {+    readonly _offsetNodes: number;+    readonly _offsetStringTableOffsets: number;+    readonly _offsetStringTable: number;+    readonly _offsetExtendedData: number;+    readonly _offsetStructuredData: number;+    readonly _decoder: TextDecoder;+    nodes: any[];+    readonly path?: string;+    /**+     * The timing collector that per-node materialization is reported into, and+     * that this source file registered itself with when fetched. Present only+     * when timing collection is enabled; when undefined, materialization is not+     * timed and no clock is read.+     */+    readonly _timing?: TimingCollector | undefined;+    readFileReferences(offset: number): readonly FileReference[];+    readNodeIndexArray(offset: number): readonly Node[];+    readStringArray(offset: number): readonly string[];+    getOrCreateNodeAtIndex(index: number): Node;+}+/**+ * Read the 128-bit content hash from a source file binary response as a hex string.+ */+export declare function readSourceFileHash(data: DataView): string;+/**+ * Read the per-file parse options key from a source file binary response.+ * This encodes the ExternalModuleIndicatorOptions bitmask as a string,+ * allowing the client to distinguish files parsed with different options.+ */+export declare function readParseOptionsKey(data: DataView): string;+export declare function modifierToFlag(kind: SyntaxKind): ModifierFlags;+export declare class RemoteNodeBase {+    parent: any;+    view: DataView;+    protected index: number;+    protected _byteIndex: number;+    constructor(view: DataView, index: number, parent: any, byteIndex: number);+    get kind(): SyntaxKind;+    get pos(): number;+    get end(): number;+    get next(): number;+    protected get parentIndex(): number;+    protected get data(): number;+    protected get dataType(): NodeDataType;+    protected get childMask(): number;+    protected getFileText(start: number, end: number): string;+    protected get sourceFile(): SourceFileInfo;+}+//# sourceMappingURL=node.infrastructure.d.ts.map
dist/api/node/node.infrastructure.js +122 lines
--- +++ @@ -0,0 +1,122 @@+import { ModifierFlags, SyntaxKind, } from "../../ast/index.js";+import { HEADER_OFFSET_HASH_HI0, HEADER_OFFSET_HASH_HI1, HEADER_OFFSET_HASH_LO0, HEADER_OFFSET_HASH_LO1, HEADER_OFFSET_PARSE_OPTIONS, NODE_DATA_TYPE_CHILDREN, NODE_DATA_TYPE_EXTENDED, NODE_DATA_TYPE_STRING, NODE_OFFSET_DATA, NODE_OFFSET_END, NODE_OFFSET_KIND, NODE_OFFSET_NEXT, NODE_OFFSET_PARENT, NODE_OFFSET_POS, } from "./protocol.js";+// ═══════════════════════════════════════════════════════════════════════════+// Constants+// ═══════════════════════════════════════════════════════════════════════════+export const popcount8 = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8];+export const NODE_DATA_TYPE_MASK = 0xc0_00_00_00;+export const NODE_CHILD_MASK = 0x00_00_00_ff;+export const NODE_STRING_INDEX_MASK = 0x00_ff_ff_ff;+export const NODE_EXTENDED_DATA_MASK = 0x00_ff_ff_ff;+// ═══════════════════════════════════════════════════════════════════════════+// Free functions+// ═══════════════════════════════════════════════════════════════════════════+/**+ * Read the 128-bit content hash from a source file binary response as a hex string.+ */+export function readSourceFileHash(data) {+    const lo0 = data.getUint32(HEADER_OFFSET_HASH_LO0, true);+    const lo1 = data.getUint32(HEADER_OFFSET_HASH_LO1, true);+    const hi0 = data.getUint32(HEADER_OFFSET_HASH_HI0, true);+    const hi1 = data.getUint32(HEADER_OFFSET_HASH_HI1, true);+    return hex8(hi1) + hex8(hi0) + hex8(lo1) + hex8(lo0);+}+/**+ * Read the per-file parse options key from a source file binary response.+ * This encodes the ExternalModuleIndicatorOptions bitmask as a string,+ * allowing the client to distinguish files parsed with different options.+ */+export function readParseOptionsKey(data) {+    return data.getUint32(HEADER_OFFSET_PARSE_OPTIONS, true).toString();+}+function hex8(n) {+    return (n >>> 0).toString(16).padStart(8, "0");+}+export function modifierToFlag(kind) {+    switch (kind) {+        case SyntaxKind.StaticKeyword:+            return ModifierFlags.Static;+        case SyntaxKind.PublicKeyword:+            return ModifierFlags.Public;+        case SyntaxKind.ProtectedKeyword:+            return ModifierFlags.Protected;+        case SyntaxKind.PrivateKeyword:+            return ModifierFlags.Private;+        case SyntaxKind.AbstractKeyword:+            return ModifierFlags.Abstract;+        case SyntaxKind.AccessorKeyword:+            return ModifierFlags.Accessor;+        case SyntaxKind.ExportKeyword:+            return ModifierFlags.Export;+        case SyntaxKind.DeclareKeyword:+            return ModifierFlags.Ambient;+        case SyntaxKind.ConstKeyword:+            return ModifierFlags.Const;+        case SyntaxKind.DefaultKeyword:+            return ModifierFlags.Default;+        case SyntaxKind.AsyncKeyword:+            return ModifierFlags.Async;+        case SyntaxKind.ReadonlyKeyword:+            return ModifierFlags.Readonly;+        case SyntaxKind.OverrideKeyword:+            return ModifierFlags.Override;+        case SyntaxKind.InKeyword:+            return ModifierFlags.In;+        case SyntaxKind.OutKeyword:+            return ModifierFlags.Out;+        case SyntaxKind.Decorator:+            return ModifierFlags.Decorator;+        default:+            return ModifierFlags.None;+    }+}+// ═══════════════════════════════════════════════════════════════════════════+// RemoteNodeBase+// ═══════════════════════════════════════════════════════════════════════════+export class RemoteNodeBase {+    parent; // RemoteNode at runtime+    view;+    index;+    _byteIndex;+    constructor(view, index, parent, byteIndex) {+        this.view = view;+        this.index = index;+        this.parent = parent;+        this._byteIndex = byteIndex;+    }+    get kind() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_KIND, true);+    }+    get pos() {+        return this.view.getInt32(this._byteIndex + NODE_OFFSET_POS, true);+    }+    get end() {+        return this.view.getInt32(this._byteIndex + NODE_OFFSET_END, true);+    }+    get next() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_NEXT, true);+    }+    get parentIndex() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_PARENT, true);+    }+    get data() {+        return this.view.getUint32(this._byteIndex + NODE_OFFSET_DATA, true);+    }+    get dataType() {+        return (this.data & NODE_DATA_TYPE_MASK);+    }+    get childMask() {+        if (this.dataType !== NODE_DATA_TYPE_CHILDREN) {+            return -1;+        }+        return this.data & NODE_CHILD_MASK;+    }+    getFileText(start, end) {+        return this.sourceFile._decoder.decode(new Uint8Array(this.view.buffer, this.view.byteOffset + this.sourceFile._offsetStringTable + start, end - start));+    }+    get sourceFile() {+        // Overridden in RemoteNode; exists here for getFileText access+        throw new Error("sourceFile not available on base");+    }+}+//# sourceMappingURL=node.infrastructure.js.map
dist/api/node/node.js +298 lines
--- +++ @@ -0,0 +1,298 @@+import { computeLineStarts, NodeFlags, SyntaxKind, TokenFlags, } from "../../ast/index.js";+import { MsgpackReader } from "./msgpack.js";+import { RemoteNode, RemoteNodeList, } from "./node.generated.js";+import { NODE_EXTENDED_DATA_MASK, } from "./node.infrastructure.js";+import { HEADER_OFFSET_EXTENDED_DATA, HEADER_OFFSET_NODES, HEADER_OFFSET_STRING_TABLE, HEADER_OFFSET_STRING_TABLE_OFFSETS, HEADER_OFFSET_STRUCTURED_DATA, KIND_NODE_LIST, NODE_LEN, NODE_OFFSET_KIND, NODE_OFFSET_PARENT, } from "./protocol.js";+import { Wtf8Decoder } from "./wtf8.js";+// Re-export everything consumers need from the other two files.+export { RemoteNode, RemoteNodeList } from "./node.generated.js";+export { readParseOptionsKey, readSourceFileHash, RemoteNodeBase } from "./node.infrastructure.js";+// ═══════════════════════════════════════════════════════════════════════════+// RemoteSourceFile+// ═══════════════════════════════════════════════════════════════════════════+const NO_STRUCTURED_DATA = 0xFFFFFFFF;+export class RemoteSourceFile extends RemoteNode {+    nodes;+    _offsetNodes;+    _offsetStringTableOffsets;+    _offsetStringTable;+    _offsetExtendedData;+    _offsetStructuredData;+    _decoder;+    _timing;+    _lineStarts;+    _cachedText;+    _cachedReferencedFiles;+    _cachedTypeReferenceDirectives;+    _cachedLibReferenceDirectives;+    _cachedImports;+    _cachedModuleAugmentations;+    _cachedAmbientModuleNames;+    constructor(data, decoder, timing) {+        const view = new DataView(data.buffer, data.byteOffset, data.byteLength);+        const offsetNodes = view.getUint32(HEADER_OFFSET_NODES, true);+        super(view, 1, undefined, undefined, offsetNodes);+        this._sourceFile = this;+        this._offsetNodes = offsetNodes;+        this._offsetStringTableOffsets = view.getUint32(HEADER_OFFSET_STRING_TABLE_OFFSETS, true);+        this._offsetStringTable = view.getUint32(HEADER_OFFSET_STRING_TABLE, true);+        this._offsetExtendedData = view.getUint32(HEADER_OFFSET_EXTENDED_DATA, true);+        this._offsetStructuredData = view.getUint32(HEADER_OFFSET_STRUCTURED_DATA, true);+        this._decoder = decoder;+        this._timing = timing;+        this.nodes = Array((view.byteLength - offsetNodes) / NODE_LEN);+        this.nodes[1] = this;+        // Every node slot is materializable on demand except the nil sentinel at+        // index 0 and the source-file node at index 1, which is pre-materialized.+        timing?.recordSourceFileFetched(Math.max(0, this.nodes.length - 2));+    }+    readFileReferences(structuredDataOffset) {+        if (structuredDataOffset === NO_STRUCTURED_DATA) {+            return [];+        }+        const buf = new Uint8Array(this.view.buffer, this.view.byteOffset, this.view.byteLength);+        const reader = new MsgpackReader(buf, this._offsetStructuredData + structuredDataOffset);+        const count = reader.readArrayHeader();+        const result = [];+        for (let i = 0; i < count; i++) {+            reader.readArrayHeader(); // 5-element tuple+            const pos = reader.readUint();+            const end = reader.readUint();+            const fileName = reader.readString();+            const resolutionMode = reader.readUint();+            const preserve = reader.readBool();+            result.push({ pos, end, fileName, resolutionMode, preserve });+        }+        return result;+    }+    readNodeIndexArray(structuredDataOffset) {+        if (structuredDataOffset === NO_STRUCTURED_DATA) {+            return [];+        }+        const buf = new Uint8Array(this.view.buffer, this.view.byteOffset, this.view.byteLength);+        const reader = new MsgpackReader(buf, this._offsetStructuredData + structuredDataOffset);+        const count = reader.readArrayHeader();+        const result = [];+        for (let i = 0; i < count; i++) {+            const nodeIndex = reader.readUint();+            result.push(this.getOrCreateNodeAtIndex(nodeIndex));+        }+        return result;+    }+    readStringArray(structuredDataOffset) {+        if (structuredDataOffset === NO_STRUCTURED_DATA) {+            return [];+        }+        const buf = new Uint8Array(this.view.buffer, this.view.byteOffset, this.view.byteLength);+        const reader = new MsgpackReader(buf, this._offsetStructuredData + structuredDataOffset);+        const count = reader.readArrayHeader();+        const result = [];+        for (let i = 0; i < count; i++) {+            result.push(reader.readString());+        }+        return result;+    }+    /** @internal */+    getOrCreateNodeAtIndex(index) {+        let node = this.nodes[index];+        if (!node) {+            // Resolve the real parent so that nodes looked up directly by index (e.g. via+            // NodeHandle.resolve) report the correct `parent`, rather than always pointing at+            // the source file. The stored parent index can refer to a synthetic NodeList+            // container; skip those to mirror normal traversal, where list elements take the+            // list's parent. The walk terminates at the source file, which occupies index 1+            // and is already cached.+            let parentIndex = this.view.getUint32(this._offsetNodes + index * NODE_LEN + NODE_OFFSET_PARENT, true);+            while (parentIndex !== index &&+                this.view.getUint32(this._offsetNodes + parentIndex * NODE_LEN + NODE_OFFSET_KIND, true) === KIND_NODE_LIST) {+                parentIndex = this.view.getUint32(this._offsetNodes + parentIndex * NODE_LEN + NODE_OFFSET_PARENT, true);+            }+            const parent = parentIndex === index ? this : this.getOrCreateNodeAtIndex(parentIndex);+            node = new RemoteNode(this.view, index, parent, this, this._offsetNodes);+            this.nodes[index] = node;+            this._timing?.recordMaterialization();+        }+        return node;+    }+    // ═══ SourceFile-specific extended data getters ═══+    get extendedDataOffset() {+        return this._offsetExtendedData + (this.data & NODE_EXTENDED_DATA_MASK);+    }+    get fileName() {+        const stringIndex = this.view.getUint32(this.extendedDataOffset + 4, true);+        return this.getString(stringIndex);+    }+    get path() {+        const stringIndex = this.view.getUint32(this.extendedDataOffset + 8, true);+        return this.getString(stringIndex);+    }+    get languageVariant() {+        return this.view.getUint32(this.extendedDataOffset + 12, true);+    }+    get scriptKind() {+        return this.view.getUint32(this.extendedDataOffset + 16, true);+    }+    get referencedFiles() {+        if (this._cachedReferencedFiles !== undefined)+            return this._cachedReferencedFiles;+        const offset = this.view.getUint32(this.extendedDataOffset + 20, true);+        const files = this.readFileReferences(offset);+        this._cachedReferencedFiles = files;+        return files;+    }+    get typeReferenceDirectives() {+        if (this._cachedTypeReferenceDirectives !== undefined)+            return this._cachedTypeReferenceDirectives;+        const offset = this.view.getUint32(this.extendedDataOffset + 24, true);+        const directives = this.readFileReferences(offset);+        this._cachedTypeReferenceDirectives = directives;+        return directives;+    }+    get libReferenceDirectives() {+        if (this._cachedLibReferenceDirectives !== undefined)+            return this._cachedLibReferenceDirectives;+        const offset = this.view.getUint32(this.extendedDataOffset + 28, true);+        const directives = this.readFileReferences(offset);+        this._cachedLibReferenceDirectives = directives;+        return directives;+    }+    get imports() {+        if (this._cachedImports !== undefined)+            return this._cachedImports;+        const offset = this.view.getUint32(this.extendedDataOffset + 32, true);+        const imports = this.readNodeIndexArray(offset);+        this._cachedImports = imports;+        return imports;+    }+    get moduleAugmentations() {+        if (this._cachedModuleAugmentations !== undefined)+            return this._cachedModuleAugmentations;+        const offset = this.view.getUint32(this.extendedDataOffset + 36, true);+        const moduleAugmentations = this.readNodeIndexArray(offset);+        this._cachedModuleAugmentations = moduleAugmentations;+        return moduleAugmentations;+    }+    get ambientModuleNames() {+        if (this._cachedAmbientModuleNames !== undefined)+            return this._cachedAmbientModuleNames;+        const offset = this.view.getUint32(this.extendedDataOffset + 40, true);+        const names = this.readStringArray(offset);+        this._cachedAmbientModuleNames = names;+        return names;+    }+    get externalModuleIndicator() {+        const nodeIndex = this.view.getUint32(this.extendedDataOffset + 44, true);+        if (nodeIndex === 0)+            return undefined;+        if (nodeIndex === this.index)+            return true;+        return this.getOrCreateNodeAtIndex(nodeIndex);+    }+    get isDeclarationFile() {+        return (this.flags & NodeFlags.Ambient) !== 0;+    }+    get text() {+        if (this._cachedText !== undefined)+            return this._cachedText;+        const text = super.text;+        this._cachedText = text;+        return text;+    }+    // ═══ Line/character position mapping ═══+    getLineStarts() {+        return this._lineStarts ??= computeLineStarts(this.text ?? "");+    }+    getLineAndCharacterOfPosition(position) {+        const lineStarts = this.getLineStarts();+        const line = computeLineOfPosition(lineStarts, position);+        return { line, character: position - lineStarts[line] };+    }+    getPositionOfLineAndCharacter(line, character) {+        const lineStarts = this.getLineStarts();+        if (line < 0 || line >= lineStarts.length) {+            throw new Error(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length}`);+        }+        return lineStarts[line] + character;+    }+}+/**+ * Find the 0-based line number containing the given position via binary search.+ * Assumes the first line starts at position 0 and `position` is non-negative.+ */+function computeLineOfPosition(lineStarts, position) {+    let low = 0;+    let high = lineStarts.length - 1;+    while (low <= high) {+        const middle = low + ((high - low) >> 1);+        const value = lineStarts[middle];+        if (value < position) {+            low = middle + 1;+        }+        else if (value > position) {+            high = middle - 1;+        }+        else {+            return middle;+        }+    }+    return low - 1;+}+/**+ * Find a descendant node at a specific position with matching kind and end position.+ */+export function findDescendant(root, pos, end, kind) {+    if (root.pos === pos && root.end === end && root.kind === kind) {+        return root;+    }+    // Search children
… 51 more lines (truncated)
@typescript-eslint/eslint-plugin npm
8.67.0 11d ago incident on record
DELETIONBURST ×7
latest 8.67.0 versions 4750 maintainers 2
8.59.4
8.60.0
8.60.1
8.61.0
8.61.1
8.62.0
8.62.1
8.63.0
8.64.0
8.65.0
8.66.0
8.67.0
DELETION
1.10.0 published then removed
high · registry-verified · 2019-06-09 · 7y ago
BURST
2 releases in 31m: 1.10.0, 1.10.1
info · registry-verified · 2019-06-09 · 7y ago
BURST
3 releases in 59m: 5.30.1, 5.30.2, 5.30.3
info · registry-verified · 2022-07-01 · 4y ago
BURST
2 releases in 44m: 5.35.0, 5.35.1
info · registry-verified · 2022-08-24 · 3y ago
BURST
2 releases in 45m: 5.59.10, 5.59.11
info · registry-verified · 2023-06-12 · 3y ago
BURST
2 releases in 41m: 5.62.0, 6.0.0
info · registry-verified · 2023-07-10 · 3y ago
BURST
2 releases in 30m: 7.0.0, 7.0.1
info · registry-verified · 2024-02-12 · 2y ago
BURST
2 releases in 20m: 7.14.0, 7.14.1
info · registry-verified · 2024-06-24 · 2y ago
release diff 8.66.0 → 8.67.0
+0 added · -0 removed · ~22 modified
dist/configs/eslint-recommended-raw.d.ts +2 lines
--- +++ @@ -5,5 +5,5 @@  */-declare const config: (style: "glob" | "minimatch") => {+declare const config: (style: 'glob' | 'minimatch') => {     files: string[];-    rules: Record<string, "error" | "off" | "warn">;+    rules: Record<string, 'error' | 'off' | 'warn'>; };
dist/configs/eslintrc/eslint-recommended.d.ts +1 lines
--- +++ @@ -8,3 +8,3 @@         files: string[];-        rules: Record<string, "error" | "off" | "warn">;+        rules: Record<string, 'error' | 'off' | 'warn'>;     }[];
dist/configs/flat/all.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/base.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -6,3 +7,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.Config;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.Config;
dist/configs/flat/disable-type-checked.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser) => FlatConfig.Config;-export default _default;+declare function _default(_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser): FlatConfig.Config;
dist/configs/flat/eslint-recommended.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -7,3 +8,2 @@  */-declare const _default: (_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser) => FlatConfig.Config;-export default _default;+declare function _default(_plugin: FlatConfig.Plugin, _parser: FlatConfig.Parser): FlatConfig.Config;
dist/configs/flat/recommended-type-checked-only.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/recommended-type-checked.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/recommended.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/strict-type-checked-only.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/strict-type-checked.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/strict.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/stylistic-type-checked-only.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/stylistic-type-checked.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/configs/flat/stylistic.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';+export default _default; /**@@ -5,3 +6,2 @@  */-declare const _default: (plugin: FlatConfig.Plugin, parser: FlatConfig.Parser) => FlatConfig.ConfigArray;-export default _default;+declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;
dist/index.d.ts +1 lines
--- +++ @@ -236,3 +236,3 @@                 files: string[];-                rules: Record<string, "error" | "off" | "warn">;+                rules: Record<string, 'error' | 'off' | 'warn'>;             }[];
dist/raw-plugin.d.ts +1 lines
--- +++ @@ -258,3 +258,3 @@                     files: string[];-                    rules: Record<string, "error" | "off" | "warn">;+                    rules: Record<string, 'error' | 'off' | 'warn'>;                 }[];
dist/rules/consistent-type-imports.d.ts +2 lines
--- +++ @@ -1,2 +1,3 @@ import type { TSESLint } from '@typescript-eslint/utils';+import type { RuleListener } from '@typescript-eslint/utils/eslint-utils'; type Prefer = 'no-type-imports' | 'type-imports';@@ -11,3 +12,3 @@ export type MessageIds = 'avoidImportType' | 'noImportTypeAnnotations' | 'someImportsAreOnlyTypes' | 'typeOverValue';-declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {+declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, RuleListener> & {     name: string;
dist/rules/prefer-function-type.d.ts +2 lines
--- +++ @@ -2,4 +2,4 @@ export declare const phrases: {-    readonly TSInterfaceDeclaration: "Interface";-    readonly TSTypeLiteral: "Type literal";+    readonly TSInterfaceDeclaration: 'Interface';+    readonly TSTypeLiteral: 'Type literal'; };
dist/util/index.d.ts +1 lines
--- +++ @@ -36,3 +36,3 @@ export declare const applyDefault: typeof ESLintUtils.applyDefault, deepMerge: typeof ESLintUtils.deepMerge, getParserServices: typeof ESLintUtils.getParserServices, isObjectNotArray: typeof ESLintUtils.isObjectNotArray, nullThrows: typeof ESLintUtils.nullThrows, NullThrowsReasons: {-    readonly MissingParent: "Expected node to have a parent.";+    readonly MissingParent: 'Expected node to have a parent.';     readonly MissingToken: (token: string, thing: string) => string;
dist/util/index.js +1 lines
--- +++ @@ -53,2 +53,2 @@ __exportStar(require("@typescript-eslint/type-utils"), exports);-exports.applyDefault = utils_1.ESLintUtils.applyDefault, exports.deepMerge = utils_1.ESLintUtils.deepMerge, exports.getParserServices = utils_1.ESLintUtils.getParserServices, exports.isObjectNotArray = utils_1.ESLintUtils.isObjectNotArray, exports.nullThrows = utils_1.ESLintUtils.nullThrows, exports.NullThrowsReasons = utils_1.ESLintUtils.NullThrowsReasons;+({ applyDefault: exports.applyDefault, deepMerge: exports.deepMerge, getParserServices: exports.getParserServices, isObjectNotArray: exports.isObjectNotArray, nullThrows: exports.nullThrows, NullThrowsReasons: exports.NullThrowsReasons } = utils_1.ESLintUtils);
package.json +9 lines
--- +++ @@ -2,3 +2,3 @@   "name": "@typescript-eslint/eslint-plugin",-  "version": "8.66.0",+  "version": "8.67.0",   "description": "TypeScript plugin for ESLint",@@ -51,6 +51,6 @@     "ts-api-utils": "^2.5.0",-    "@typescript-eslint/scope-manager": "8.66.0",-    "@typescript-eslint/type-utils": "8.66.0",-    "@typescript-eslint/utils": "8.66.0",-    "@typescript-eslint/visitor-keys": "8.66.0"+    "@typescript-eslint/scope-manager": "8.67.0",+    "@typescript-eslint/type-utils": "8.67.0",+    "@typescript-eslint/visitor-keys": "8.67.0",+    "@typescript-eslint/utils": "8.67.0"   },@@ -61,3 +61,3 @@     "@types/react": "^18.3.21",-    "@typescript/native-preview": "7.0.0-dev.20260518.1",+    "@typescript/native": "npm:typescript@^7.0.2",     "@vitest/coverage-v8": "^4.0.18",@@ -78,4 +78,4 @@     "vitest": "^4.0.18",-    "@typescript-eslint/rule-schema-to-typescript-types": "8.66.0",-    "@typescript-eslint/rule-tester": "8.66.0"+    "@typescript-eslint/rule-schema-to-typescript-types": "8.67.0",+    "@typescript-eslint/rule-tester": "8.67.0"   },@@ -84,3 +84,3 @@     "typescript": ">=4.8.4 <6.1.0",-    "@typescript-eslint/parser": "^8.66.0"+    "@typescript-eslint/parser": "^8.67.0"   },
@typescript-eslint/parser npm
8.67.0 11d ago incident on record
DELETIONBURST ×7
latest 8.67.0 versions 4833 maintainers 2
8.59.4
8.60.0
8.60.1
8.61.0
8.61.1
8.62.0
8.62.1
8.63.0
8.64.0
8.65.0
8.66.0
8.67.0
DELETION
1.10.0 published then removed
high · registry-verified · 2019-06-09 · 7y ago
BURST
2 releases in 31m: 1.10.0, 1.10.1
info · registry-verified · 2019-06-09 · 7y ago
BURST
3 releases in 59m: 5.30.1, 5.30.2, 5.30.3
info · registry-verified · 2022-07-01 · 4y ago
BURST
2 releases in 44m: 5.35.0, 5.35.1
info · registry-verified · 2022-08-24 · 3y ago
BURST
2 releases in 45m: 5.59.10, 5.59.11
info · registry-verified · 2023-06-12 · 3y ago
BURST
2 releases in 41m: 5.62.0, 6.0.0
info · registry-verified · 2023-07-10 · 3y ago
BURST
2 releases in 30m: 7.0.0, 7.0.1
info · registry-verified · 2024-02-12 · 2y ago
BURST
2 releases in 20m: 7.14.0, 7.14.1
info · registry-verified · 2024-06-24 · 2y ago
release diff 8.66.0 → 8.67.0
+0 added · -0 removed · ~1 modified
package.json +6 lines
--- +++ @@ -2,3 +2,3 @@   "name": "@typescript-eslint/parser",-  "version": "8.66.0",+  "version": "8.67.0",   "description": "An ESLint custom parser which leverages TypeScript ESTree",@@ -44,9 +44,9 @@     "debug": "^4.4.3",-    "@typescript-eslint/scope-manager": "8.66.0",-    "@typescript-eslint/types": "8.66.0",-    "@typescript-eslint/typescript-estree": "8.66.0",-    "@typescript-eslint/visitor-keys": "8.66.0"+    "@typescript-eslint/typescript-estree": "8.67.0",+    "@typescript-eslint/visitor-keys": "8.67.0",+    "@typescript-eslint/types": "8.67.0",+    "@typescript-eslint/scope-manager": "8.67.0"   },   "devDependencies": {-    "@typescript/native-preview": "7.0.0-dev.20260518.1",+    "@typescript/native": "npm:typescript@^7.0.2",     "@vitest/coverage-v8": "^4.0.18",
ua-parser-js npm
2.0.10 3mo ago incident on record
DELETION ×3BURST ×11
latest 2.0.10 versions 94 maintainers 1
2.0.1
2.0.2
2.0.3
2.0.4
0.7.41
1.0.41
2.0.5
2.0.6
2.0.7
2.0.8
2.0.9
2.0.10
DELETION
0.7.29 published then removed
high · registry-verified · 2021-10-22 · 4y ago
DELETION
0.8.0 published then removed
high · registry-verified · 2021-10-22 · 4y ago
DELETION
1.0.0 published then removed
high · registry-verified · 2021-10-22 · 4y ago
BURST
3 releases in 1m: 0.7.29, 0.8.0, 1.0.0
info · registry-verified · 2021-10-22 · 4y ago
BURST
3 releases in 10m: 0.7.30, 0.8.1, 1.0.1
info · registry-verified · 2021-10-22 · 4y ago
BURST
2 releases in 0m: 0.7.32, 1.0.32
info · registry-verified · 2022-10-15 · 3y ago
BURST
2 releases in 0m: 1.0.33, 0.7.33
info · registry-verified · 2023-01-22 · 3y ago
BURST
2 releases in 0m: 0.7.34, 1.0.34
info · registry-verified · 2023-03-05 · 3y ago
BURST
2 releases in 0m: 0.7.35, 1.0.35
info · registry-verified · 2023-04-01 · 3y ago
BURST
2 releases in 3m: 0.7.36, 1.0.36
info · registry-verified · 2023-09-09 · 2y ago
BURST
2 releases in 4m: 0.7.37, 1.0.37
info · registry-verified · 2023-10-27 · 2y ago
BURST
2 releases in 1m: 0.7.38, 1.0.38
info · registry-verified · 2024-05-28 · 2y ago
BURST
2 releases in 5m: 0.7.40, 1.0.40
info · registry-verified · 2024-12-21 · 1y ago
BURST
2 releases in 1m: 0.7.41, 1.0.41
info · registry-verified · 2025-08-19 · 1y ago
release diff 2.0.9 → 2.0.10
+0 added · -0 removed · ~27 modified
dist/ua-parser.pack.js +2 lines · 1 flagged
--- +++ @@ -1,4 +1,4 @@-/* UAParser.js v2.0.9+/* UAParser.js v2.0.10    Copyright © 2012-2026 Faisal Salman <[email protected]>    AGPLv3 License */-((i,c)=>{function A(i){for(var e={},t=0;t<i.length;t++)e[i[t].toUpperCase()]=i[t];return e}function B(i){return Ti(i)?Oi(/[^\d\.]/g,i).split(".")[0]:c}function H(i,e){if(i&&e)for(var t,o,r,a,s,n=0;n<e.length&&!a;){for(var w=e[n],b=e[n+1],d=t=0;d<w.length&&!a&&w[d];)if(a=w[d++].exec(i))for(o=0;o<b.length;o++)s=a[++t],typeof(r=b[o])===l.OBJECT&&0<r.length?2===r.length?typeof r[1]==l.FUNCTION?this[r[0]]=r[1].call(this,s):this[r[0]]=r[1]:3<=r.length&&(typeof r[1]!==l.FUNCTION||r[1].exec&&r[1].test?3==r.length?this[r[0]]=s?s.replace(r[1],r[2]):c:4==r.length?this[r[0]]=s?r[3].call(this,s.replace(r[1],r[2])):c:4<r.length&&(this[r[0]]=s?r[3].apply(this,[s.replace(r[1],r[2])].concat(r.slice(4))):c):3<r.length?this[r[0]]=s?r[1].apply(this,r.slice(2)):c:this[r[0]]=s?r[1].call(this,s,r[2]):c):this[r]=s||c;n+=2}}function p(i,e){for(var t in e)if(typeof e[t]===l.OBJECT&&0<e[t].length){for(var o=0;o<e[t].length;o++)if(Ei(e[t][o],i))return"?"===t?c:t}else if(Ei(e[t],i))return"?"===t?c:t;return e.hasOwnProperty("*")?e["*"]:i}function M(e,i){var t=Ai.init[i],o=Ai.isIgnore[i]||0,r=Ai.isIgnoreRgx[i]||0,a=Ai.toString[i]||0;function s(){D.call(this,t)}return s.prototype.getItem=function(){return e},s.prototype.withClientHints=function(){return _?_.getHighEntropyValues(oi).then(function(i){return e.setCH(new Bi(i,!1)).parseCH().get()}):e.parseCH().get()},s.prototype.withFeatureCheck=function(){return e.detectFeature().get()},i!=v&&(s.prototype.is=function(i){var e,t=!1;for(e in this)if(this.hasOwnProperty(e)&&!Ei(o,e)&&q(r?Oi(r,this[e]):this[e])==q(r?Oi(r,i):i)){if(t=!0,i!=l.UNDEFINED)break}else if(i==l.UNDEFINED&&t){t=!t;break}return t},s.prototype.toString=function(){var i,e=d;for(i in a)typeof this[a[i]]!==l.UNDEFINED&&(e+=(e?" ":d)+this[a[i]]);return e||l.UNDEFINED}),s.prototype.then=function(i){function e(){for(var i in t)t.hasOwnProperty(i)&&(this[i]=t[i])}var t=this,o=(e.prototype={is:s.prototype.is,toString:s.prototype.toString,withClientHints:s.prototype.withClientHints,withFeatureCheck:s.prototype.withFeatureCheck},new e);return i(o),o},new s}var V="user-agent",d="",l={FUNCTION:"function",OBJECT:"object",STRING:"string",UNDEFINED:"undefined"},h="browser",u="cpu",m="device",f="engine",g="os",v="result",k="name",x="type",y="vendor",C="version",N="architecture",j="major",E="model",P="console",S="mobile",t="tablet",e="smarttv",o="wearable",R="xr",G="embedded",r="inapp",L="brands",T="formFactors",$="fullVersionList",I="platform",W="platformVersion",J="bitness",a="sec-ch-ua",X=a+"-full-version-list",Y=a+"-arch",Z=a+"-"+J,Q=a+"-form-factors",K=a+"-"+S,ii=a+"-"+E,ei=a+"-"+I,ti=ei+"-version",oi=[L,$,S,E,I,W,N,T,J],ri="Amazon",s="Apple",ai="ASUS",si="BlackBerry",n="Google",ni="Huawei",wi="Lenovo",bi="Honor",di="Microsoft",li="Motorola",ci="OnePlus",pi="OPPO",hi="Samsung",ui="Sony",mi="Xiaomi",fi="Zebra",gi="Chromium",w="Chromecast",vi="Edge",ki="Firefox",b="Opera",xi="Facebook",O="Mobile ",yi=" Browser",Ci="Windows",Ni=typeof i!==l.UNDEFINED,U=Ni&&i.navigator?i.navigator:c,_=U&&U.userAgentData?U.userAgentData:c,Ei=function(i,e){if(typeof i===l.OBJECT&&0<i.length){for(var t in i)if(q(e)==q(i[t]))return!0;return!1}return!!Ti(i)&&q(e)==q(i)},Si=function(i,e){for(var t in i)return/^(browser|cpu|device|engine|os)$/.test(t)||!!e&&Si(i[t])},Ti=function(i){return typeof i===l.STRING},Ii=function(i){if(!i)return c;for(var e,t=[],o=Oi(/\\?\"/g,i).split(","),r=0;r<o.length;r++)-1<o[r].indexOf(";")?(e=_i(o[r]).split(";v="),t[r]={brand:e[0],version:e[1]}):t[r]=_i(o[r]);return t},q=function(i){return Ti(i)?i.toLowerCase():i},D=function(i){for(var e in i)i.hasOwnProperty(e)&&(typeof(e=i[e])==l.OBJECT&&2==e.length?this[e[0]]=e[1]:this[e]=c);return this},Oi=function(i,e){return Ti(e)?e.replace(i,d):e},Ui=function(i){return Oi(/\\?\"/g,i)},_i=function(i,e){return i=Oi(/^\s\s*/,String(i)),typeof e===l.UNDEFINED?i:i.substring(0,e)},qi={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2",8.1:"6.3",10:["6.4","10.0"],NT:""},Di={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":c},Fi={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},zi={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[C,[k,O+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[C,[k,vi+" WebView"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[C,[k,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[k,C],[/opios[\/ ]+([\w\.]+)/i],[C,[k,b+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[C,[k,b+" GX"]],[/\bopr\/([\w\.]+)/i],[C,[k,b]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[C,[k,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[C,[k,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:hi|lg |ovi|qute)browser|palemoon)\/v?([-\w\.]+)/i,/(brave)(?: chrome)?\/([\d\.]+)/i,/(aloha|heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,/(qwant)(?:ios|mobile)\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[k,C],[/quark(?:pc)?\/([-\w\.]+)/i],[C,[k,"Quark"]],[/\bddg\/([\w\.]+)/i],[C,[k,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[C,[k,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[C,[k,"WeChat"]],[/konqueror\/([\w\.]+)/i],[C,[k,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[C,[k,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[C,[k,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[C,[k,"Smart "+wi+yi]],[/(av(?:ast|g|ira))\/([\w\.]+)/i],[[k,/(.+)/,"$1 Secure"+yi],C],[/norton\/([\w\.]+)/i],[C,[k,"Norton Private"+yi]],[/\bfocus\/([\w\.]+)/i],[C,[k,ki+" Focus"]],[/ mms\/([\w\.]+)$/i],[C,[k,b+" Neon"]],[/ opt\/([\w\.]+)$/i],[C,[k,b+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[C,[k,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[C,[k,"Dolphin"]],[/coast\/([\w\.]+)/i],[C,[k,b+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[C,[k,"MIUI"+yi]],[/fxios\/([\w\.-]+)/i],[C,[k,O+ki]],[/\bqihoobrowser\/?([\w\.]*)/i],[C,[k,"360"]],[/\b(qq)\/([\w\.]+)/i],[[k,/(.+)/,"$1Browser"],C],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[k,/(.+)/,"$1"+yi],C],[/samsungbrowser\/([\w\.]+)/i],[C,[k,hi+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[C,[k,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[k,"Sogou Mobile"],C],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[k,C],[/(lbbrowser|luakit|rekonq|steam(?= (clie|tenf|gameo)))/i],[k],[/ome\/([\w\.]+).+(iron(?= saf)|360(?=[es]e$))/i],[C,k],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[k,xi],C,[x,r]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(bing)(?:web|sapphire)\/([\w\.]+)/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[k,C,[x,r]],[/\bgsa\/([\w\.]+) .*safari\//i],[C,[k,"GSA"],[x,r]],[/(?:musical_ly|trill)(?:.+app_?version\/|_)([\w\.]+)/i],[C,[k,"TikTok"],[x,r]],[/\[(linkedin)app\]/i],[k,[x,r]],[/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i],[[k,/(.+)/,"Zalo"],C,[x,r]],[/(chromium)[\/ ]([-\w\.]+)/i],[k,C],[/ome-(lighthouse)$/i],[k,[x,"fetcher"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[C,[k,"Chrome Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[C,[k,vi+" WebView2"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[k,"Chrome WebView"],C],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[C,[k,"Android"+yi]],[/chrome\/([\w\.]+) mobile/i],[C,[k,O+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[k,C],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[C,[k,O+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[k,O+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[C,k],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[k,[C,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[k,C],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[k,O+ki],C],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[k,"Netscape"],C],[/(wolvic|librewolf)\/([\w\.]+)/i],[k,C],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[C,[k,ki+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[k,[C,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[k,[C,/[^\d\.]+./,d]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[N,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[N,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[N,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[N,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[N,"arm"]],[/ sun4\w[;\)]/i],[[N,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,/((ppc|powerpc)(64)?)( mac|;|\))/i,/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i],[[N,/ower/,d,q]],[/mc680.0/i],[[N,"68k"]],[/winnt.+\[axp/i],[[N,"alpha"]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[E,[y,hi],[x,t]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[E,[y,hi],[x,S]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i],[E,[y,s],[x,S]],[/\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,/\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i],[E,[y,s],[x,t]],[/(macintosh);/i],[E,[y,s]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[E,[y,"Sharp"],[x,S]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[E,[y,bi],[x,t]],[/honor([-\w ]+)[;\)]/i],[E,[y,bi],[x,S]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[E,[y,ni],[x,t]],[/(?:huawei) ?([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i],[E,[y,ni],[x,S]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[E,/_/g," "],[y,mi],[x,t]],[/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[E,/_/g," "],[y,mi],[x,S]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-l]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[E,[y,ci],[x,S]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[E,[y,pi],[x,S]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[E,[y,p,{OnePlus:["203","304","403","404","413","415"],"*":pi}],[x,t]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[E,[y,"BLU"],[x,S]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[E,[y,"Vivo"],[x,S]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[E,[y,"Realme"],[x,S]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[E,[y,wi],[x,t]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[E,[y,wi],[x,S]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[E,[y,li],[x,S]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[E,[y,li],[x,t]],[/\b(?:lg)?([vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[E,[y,"LG"],[x,t]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[E,[y,"LG"],[x,S]],[/(nokia) (t[12][01])/i],[y,E,[x,t]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i],[[E,/_/g," "],[x,S],[y,"Nokia"]],[/(pixel (c|tablet))\b/i],[E,[y,n],[x,t]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[E,[y,n],[x,S]],[/(google) (pixelbook( go)?)/i],[y,E],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[E,[y,ui],[x,S]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[E,"Xperia Tablet"],[y,ui],[x,t]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[E,[y,ri],[x,t]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[E,/(.+)/g,"Fire Phone $1"],[y,ri],[x,S]],[/(playbook);[-\w\),; ]+(rim)/i],[E,y,[x,t]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/(?:blackberry|\(bb10;) (\w+)/i],[E,[y,si],[x,S]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[E,[y,ai],[x,t]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[E,[y,ai],[x,S]],[/(nexus 9)/i],[E,[y,"HTC"],[x,t]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[y,[E,/_/g," "],[x,S]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[E,[y,"TCL"],[x,t]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[E,[y,"TCL"],[x,S]],[/(itel) ((\w+))/i],[[y,q],E,[x,p,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[E,[y,"Acer"],[x,t]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[E,[y,"Meizu"],[x,S]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[E,[y,"Ulefone"],[x,S]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[E,[y,"Energizer"],[x,S]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[E,[y,"Cat"],[x,S]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[E,[y,"Smartfren"],[x,S]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[E,[y,"Nothing"],[x,S]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[E,[y,"Archos"],[x,t]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[E,[y,"Archos"],[x,S]],[/; (n159v)/i],[E,[y,"HMD"],[x,S]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[y,E,[x,t]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i,/(hisense) ([ehv][\w ]+)\)/i,/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i],[y,E,[x,S]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[y,E,[x,t]],[/(surface duo)/i],[E,[y,di],[x,t]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[E,[y,"Fairphone"],[x,S]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[E,[y,"Nvidia"],[x,t]],[/(sprint) (\w+)/i],[y,E,[x,S]],[/(kin\.[onetw]{3})/i],[[E,/\./g," "],[y,di],[x,S]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[E,[y,fi],[x,t]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[E,[y,fi],[x,S]],[/(philips)[\w ]+tv/i,/smart-tv.+(samsung)/i],[y,[x,e]],[/hbbtv.+maple;(\d+)/i],[[E,/^/,"SmartTV"],[y,hi],[x,e]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[y,E,[x,e]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[y,"LG"],[x,e]],[/(apple) ?tv/i],[y,[E,s+" TV"],[x,e]],[/crkey.*devicetype\/chromecast/i],[[E,w+" Third Generation"],[y,n],[x,e]],[/crkey.*devicetype\/([^/]*)/i],[[E,/^/,"Chromecast "],[y,n],[x,e]],[/fuchsia.*crkey/i],[[E,w+" Nest Hub"],[y,n],[x,e]],[/crkey/i],[[E,w],[y,n],[x,e]],[/(portaltv)/i],[E,[y,xi],[x,e]],[/droid.+aft(\w+)( bui|\))/i],[E,[y,ri],[x,e]],[/(shield \w+ tv)/i],[E,[y,"Nvidia"],[x,e]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[E,[y,"Sharp"],[x,e]],[/(bravia[\w ]+)( bui|\))/i],[E,[y,ui],[x,e]],[/(mi(tv|box)-?\w+) bui/i],[E,[y,mi],[x,e]],[/Hbbtv.*(technisat) (.*);/i],[y,E,[x,e]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[y,/.+\/(\w+)/,"$1",p,{LG:"lge"}],[E,_i],[x,e]],[/(playstation \w+)/i],[E,[y,ui],[x,P]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[E,[y,di],[x,P]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i,/(valve).+(steam deck)/i,/droid.+; ((shield|rgcube|gr0006))( bui|\))/i],[[y,p,{Nvidia:"Shield",Anbernic:"RGCUBE",Logitech:"GR0006"}],E,[x,P]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[E,[y,hi],[x,o]],[/((pebble))app/i,/(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[y,E,[x,o]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[E,[y,pi],[x,o]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[E,[y,s],[x,o]],[/(opwwe\d{3})/i],[E,[y,ci],[x,o]],[/(moto 360)/i],[E,[y,li],[x,o]],[/(smartwatch 3)/i],[E,[y,ui],[x,o]],[/(g watch r)/i],[E,[y,"LG"],[x,o]],[/droid.+; (wt63?0{2,3})\)/i],[E,[y,fi],[x,o]],[/droid.+; (glass) \d/i],[E,[y,n],[x,R]],[/(pico) ([\w ]+) os\d/i],[y,E,[x,R]],[/(quest( \d| pro)?s?).+vr/i],[E,[y,xi],[x,R]],[/mobile vr; rv.+firefox/i],[[x,R]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[y,[x,G]],[/(aeobc)\b/i],[E,[y,ri],[x,G]],[/(homepod).+mac os/i],[E,[y,s],[x,G]],[/windows iot/i],[[x,G]],[/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i],[E,[x,e]],[/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i],[[x,e]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i],[E,[x,p,{mobile:"Mobile",xr:"VR","*":t}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[x,t]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[x,S]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[E,[y,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[C,[k,vi+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[k,C],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[C,[k,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links|dillo)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[k,C],[/ladybird\//i],[[k,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[C,k]],os:[[/(windows nt) (6\.[23]); arm/i],[[k,/N/,"R"],[C,p,qi]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[k,C],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[C,/(;|\))/g,"",p,qi],[k,Ci]],[/(windows ce)\/?([\d\.]*)/i],[k,C],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,/\btvos ?([\w\.]+)/i,/cfnetwork\/.+darwin/i],[[C,/_/g,"."],[k,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[k,"macOS"],[C,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[C,[k,w+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[C,[k,w+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[C,[k,w+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[C,[k,w+" Linux"]],[/crkey\/([\d\.]+)/i],[C,[k,w]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[C,k],[/(ubuntu) ([\w\.]+) like android/i],[[k,/(.+)/,"$1 Touch"],C],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[k,C],[/\(bb(10);/i],[C,[k,si]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[C,[k,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile[;\w ]*|tablet|tv|[^\)]*(?:viera|lg(?:l25|-d300)|alcatel ?o.+|y300-f1)); rv:([\w\.]+)\).+gecko\//i],[C,[k,ki+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[C,[k,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[C,p,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[k,"webOS"]],[/watch(?: ?os[,\/ ]|\d,\d\/)([\d\.]+)/i],[C,[k,"watchOS"]],[/cros [\w]+(?:\)| ([\w\.]+)\b)/i],[C,[k,"Chrome OS"]],[/kepler ([\w\.]+); (aft|aeo)/i],[C,[k,"Vega OS"]],[/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[k,C],[/(sunos) ?([\d\.]*)/i],[[k,"Solaris"],C],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[k,C]]},Ai=(b={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}},D.call(b.init,[[h,[k,C,j,x]],[u,[N]],[m,[x,E,y]],[f,[k,C]],[g,[k,C]]]),D.call(b.isIgnore,[[h,[C,j]],[f,[C]],[g,[C]]]),D.call(b.isIgnoreRgx,[[h,/ ?browser$/i],[g,/ ?os$/i]]),D.call(b.toString,[[h,[k,C]],[u,[N]],[m,[y,E]],[f,[k,C]],[g,[k,C]]]),b);function Bi(i,e){if(i=i||{},D.call(this,oi),e)D.call(this,[[L,Ii(i[a])],[$,Ii(i[X])],[S,/\?1/.test(i[K])],[E,Ui(i[ii])],[I,Ui(i[ei])],[W,Ui(i[ti])],[N,Ui(i[Y])],[T,Ii(i[Q])],[J,Ui(i[Z])]]);else for(var t in i)this.hasOwnProperty(t)&&typeof i[t]!==l.UNDEFINED&&(this[t]=i[t])}function F(i,e,t,o){return D.call(this,[["itemType",i],["ua",e],["uaCH",o],["rgxMap",t],["data",M(this,i)]]),this}function z(i,e,t){if(typeof i===l.OBJECT?(e=Si(i,!0)?(typeof e===l.OBJECT&&(t=e),i):(t=i,c),i=c):typeof i!==l.STRING||Si(e,!0)||(t=e,e=c),t)if(typeof t.append===l.FUNCTION){var o={};t.forEach(function(i,e){o[String(e).toLowerCase()]=i}),t=o}else{var r,a={};for(r in t)t.hasOwnProperty(r)&&(a[String(r).toLowerCase()]=t[r]);t=a}var s,n,w,b;return this instanceof z?(s=typeof i===l.STRING?i:t&&t[V]?t[V]:U&&U.userAgent?U.userAgent:d,n=new Bi(t,!0),w=e?((i,e)=>{var t,o={},r=e;if(!Si(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(zi,e):zi,D.call(this,[["getBrowser",(b=function(i){return i==v?function(){return new F(i,s,w,n).set("ua",s).set(h,this.getBrowser()).set(u,this.getCPU()).set(m,this.getDevice()).set(f,this.getEngine()).set(g,this.getOS()).get()}:function(){return new F(i,s,w[i],n).parseUA().get()}})(h)],["getCPU",b(u)],["getDevice",b(m)],["getEngine",b(f)],["getOS",b(g)],["getResult",b(v)],["getUA",function(){return s}],["setUA",function(i){return Ti(i)&&(s=_i(i,500)),this}]]).setUA(s),this):new z(i,e,t).getResult()}F.prototype.get=function(i){return i?this.data.hasOwnProperty(i)?this.data[i]:c:this.data},F.prototype.set=function(i,e){return this.data[i]=e,this},F.prototype.setCH=function(i){return this.uaCH=i,this},F.prototype.detectFeature=function(){if(U&&U.userAgent==this.ua)switch(this.itemType){case h:U.brave&&typeof U.brave.isBrave==l.FUNCTION&&this.set(k,"Brave");break;case m:!this.get(x)&&_&&_[S]&&this.set(x,S),"Macintosh"==this.get(E)&&U&&typeof U.standalone!==l.UNDEFINED&&U.maxTouchPoints&&2<U.maxTouchPoints&&this.set(E,"iPad").set(x,t);break;case g:!this.get(k)&&_&&_[I]&&this.set(k,_[I]);break;case v:var e=this.data,i=function(i){return e[i].getItem().detectFeature().get()};this.set(h,i(h)).set(u,i(u)).set(m,i(m)).set(f,i(f)).set(g,i(g))}return this},F.prototype.parseUA=function(){switch(this.itemType!=v&&H.call(this.data,this.ua,this.rgxMap),this.itemType){case h:this.set(j,B(this.get(C)));break;case g:var i;"iOS"==this.get(k)&&"18.6"==this.get(C)&&(i=/\) Version\/([\d\.]+)/.exec(this.ua))&&26<=parseInt(i[1].substring(0,2),10)&&this.set(C,i[1])}return this},F.prototype.parseCH=function(){var i,e=this.uaCH,t=this.rgxMap;switch(this.itemType){case h:case f:var o,r=e[$]||e[L];if(r)for(var a=0;a<r.length;a++){var s=r[a].brand||r[a],n=r[a].version;this.itemType==h&&!/not.a.brand/i.test(s)&&(!o||/Chrom/.test(o)&&s!=gi||o==vi&&/WebView2/.test(s))&&(s=p(s,Fi),(o=this.get(k))&&!/Chrom/.test(o)&&/Chrom/.test(s)||this.set(k,s).set(C,n).set(j,B(n)),o=s),this.itemType==f&&s==gi&&this.set(C,n)}break;case u:var w=e[N];w&&("64"==e[J]&&(w+="64"),H.call(this.data,w+";",t));break;case m:if(e[S]&&this.set(x,S),e[E]&&(this.set(E,e[E]),this.get(x)&&this.get(y)||(H.call(w={},"droid 9; "+e[E]+")",t),!this.get(x)&&w.type&&this.set(x,w.type),!this.get(y)&&w.vendor&&this.set(y,w.vendor))),e[T]){if("string"!=typeof e[T])for(var b=0;!i&&b<e[T].length;)i=p(e[T][b++],Di);else i=p(e[T],Di);this.set(x,i)}break;case g:var d,w=e[I];w&&(d=e[W],w==Ci&&(d=13<=parseInt(B(d),10)?"11":"10"),this.set(k,w).set(C,d)),this.get(k)==Ci&&"Xbox"==e[E]&&this.set(k,"Xbox").set(C,c);break;case v:var l=this.data,w=function(i){return l[i].getItem().setCH(e).parseCH().get()};this.set(h,w(h)).set(u,w(u)).set(m,w(m)).set(f,w(f)).set(g,w(g))}return this},z.VERSION="2.0.9",z.BROWSER=A([k,C,j,x]),z.CPU=A([N]),z.DEVICE=A([E,y,x,P,S,e,t,o,G]),z.ENGINE=z.OS=A([k,C]),typeof exports!==l.UNDEFINED?(exports=typeof module!==l.UNDEFINED&&module.exports?module.exports=z:exports).UAParser=z:typeof define===l.FUNCTION&&define.amd?define(function(){return z}):Ni&&(i.UAParser=z);var Hi,Mi=Ni&&(i.jQuery||i.Zepto);Mi&&!Mi.ua&&(Hi=new z,Mi.ua=Hi.getResult(),Mi.ua.get=function(){return Hi.getUA()},Mi.ua.set=function(i){Hi.setUA(i);var e,t=Hi.getResult();for(e in t)Mi.ua[e]=t[e]})})("object"==typeof window?window:this);+((i,c)=>{function B(i){for(var e={},t=0;t<i.length;t++)e[i[t].toUpperCase()]=i[t];return e}function H(i){return Ii(i)?_i(/[^\d\.]/g,i).split(".")[0]:c}function A(i,e){if(i&&e)for(var t,o,r,a,s,n=0;n<e.length&&!a;){for(var w=e[n],b=e[n+1],d=t=0;d<w.length&&!a&&w[d];)if(a=w[d++].exec(i))for(o=0;o<b.length;o++)s=a[++t],typeof(r=b[o])===l.OBJECT&&0<r.length?2===r.length?typeof r[1]==l.FUNCTION?this[r[0]]=r[1].call(this,s):this[r[0]]=r[1]:3<=r.length&&(typeof r[1]!==l.FUNCTION||r[1].exec&&r[1].test?3==r.length?this[r[0]]=s?s.replace(r[1],r[2]):c:4==r.length?this[r[0]]=s?r[3].call(this,s.replace(r[1],r[2])):c:4<r.length&&(this[r[0]]=s?r[3].apply(this,[s.replace(r[1],r[2])].concat(r.slice(4))):c):3<r.length?this[r[0]]=s?r[1].apply(this,r.slice(2)):c:this[r[0]]=s?r[1].call(this,s,r[2]):c):this[r]=s||c;n+=2}}function p(i,e){for(var t in e)if(typeof e[t]===l.OBJECT&&0<e[t].length){for(var o=0;o<e[t].length;o++)if(Si(e[t][o],i))return"?"===t?c:t}else if(Si(e[t],i))return"?"===t?c:t;return e.hasOwnProperty("*")?e["*"]:i}function M(e,i){var t=Hi.init[i],o=Hi.isIgnore[i]||0,r=Hi.isIgnoreRgx[i]||0,a=Hi.toString[i]||0;function s(){D.call(this,t)}return s.prototype.getItem=function(){return e},s.prototype.withClientHints=function(){return _?_.getHighEntropyValues(ri).then(function(i){return e.setCH(new Ai(i,!1)).parseCH().get()}):e.parseCH().get()},s.prototype.withFeatureCheck=function(){return e.detectFeature().get()},i!=v&&(s.prototype.is=function(i){var e,t=!1;for(e in this)if(this.hasOwnProperty(e)&&!Si(o,e)&&q(r?_i(r,this[e]):this[e])==q(r?_i(r,i):i)){if(t=!0,i!=l.UNDEFINED)break}else if(i==l.UNDEFINED&&t){t=!t;break}return t},s.prototype.toString=function(){var i,e=d;for(i in a)typeof this[a[i]]!==l.UNDEFINED&&(e+=(e?" ":d)+this[a[i]]);return e||l.UNDEFINED}),s.prototype.then=function(i){function e(){for(var i in t)t.hasOwnProperty(i)&&(this[i]=t[i])}var t=this,o=(e.prototype={is:s.prototype.is,toString:s.prototype.toString,withClientHints:s.prototype.withClientHints,withFeatureCheck:s.prototype.withFeatureCheck},new e);return i(o),o},new s}var P=500,V="user-agent",d="",l={FUNCTION:"function",OBJECT:"object",STRING:"string",UNDEFINED:"undefined"},u="browser",h="cpu",m="device",f="engine",g="os",v="result",k="name",x="type",y="vendor",C="version",N="architecture",j="major",E="model",R="console",S="mobile",t="tablet",e="smarttv",o="wearable",G="xr",L="embedded",r="inapp",$="brands",T="formFactors",W="fullVersionList",I="platform",J="platformVersion",X="bitness",a="sec-ch-ua",Y=a+"-full-version-list",Z=a+"-arch",Q=a+"-"+X,K=a+"-form-factors",ii=a+"-"+S,ei=a+"-"+E,ti=a+"-"+I,oi=ti+"-version",ri=[$,W,S,E,I,J,N,T,X],ai="Amazon",s="Apple",si="ASUS",ni="BlackBerry",n="Google",wi="Huawei",bi="Lenovo",di="Honor",li="Microsoft",ci="Motorola",pi="OnePlus",ui="OPPO",hi="Samsung",mi="Sony",fi="Xiaomi",gi="Zebra",vi="Chromium",w="Chromecast",ki="Edge",xi="Firefox",b="Opera",yi="Facebook",Ci="Mobile ",O=" Browser",Ni="Windows",Ei=typeof i!==l.UNDEFINED,U=Ei&&i.navigator?i.navigator:c,_=U&&U.userAgentData?U.userAgentData:c,Si=function(i,e){if(typeof i===l.OBJECT&&0<i.length){for(var t in i)if(q(e)==q(i[t]))return!0;return!1}return!!Ii(i)&&q(e)==q(i)},Ti=function(i,e){for(var t in i)return/^(browser|cpu|device|engine|os)$/.test(t)||!!e&&Ti(i[t])},Ii=function(i){return typeof i===l.STRING},Oi=function(i){if(!i)return c;for(var e,t=[],o=Ui(i).split(","),r=0;r<o.length;r++)-1<o[r].indexOf(";")?(e=qi(o[r]).split(";v="),t[r]={brand:e[0],version:e[1]}):t[r]=qi(o[r]);return t},q=function(i){return Ii(i)?i.toLowerCase():i},Ui=function(i){return Ii(i)?qi(_i(/\\?\"/g,i),P):c},D=function(i){for(var e in i)i.hasOwnProperty(e)&&(typeof(e=i[e])==l.OBJECT&&2==e.length?this[e[0]]=e[1]:this[e]=c);return this},_i=function(i,e){return Ii(e)?e.replace(i,d):e},qi=function(i,e){return i=_i(/^\s\s*/,String(i)),typeof e===l.UNDEFINED?i:i.substring(0,e)},Di={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2",8.1:"6.3",10:["6.4","10.0"],NT:""},Fi={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":c},zi={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},Bi={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[C,[k,Ci+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[C,[k,ki+" WebView"],[x,r]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[C,[k,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[k,C],[/opios[\/ ]+([\w\.]+)/i],[C,[k,b+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[C,[k,b+" GX"]],[/\bopr\/([\w\.]+)/i],[C,[k,b]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[C,[k,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[C,[k,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:hi|lg |ovi|qute)browser|palemoon)\/v?([-\w\.]+)/i,/(brave)(?: chrome)?\/([\d\.]+)/i,/(aloha|heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,/(qwant)(?:ios|mobile)\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[k,C],[/quark(?:pc)?\/([-\w\.]+)/i],[C,[k,"Quark"]],[/\bddg\/([\w\.]+)/i],[C,[k,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i],[C,[k,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[C,[k,"WeChat"]],[/konqueror\/([\w\.]+)/i],[C,[k,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[C,[k,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[C,[k,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[C,[k,"Smart "+bi+O]],[/(av(?:ast|g|ira))\/([\w\.]+)/i],[[k,/(.+)/,"$1 Secure"+O],C],[/norton\/([\w\.]+)/i],[C,[k,"Norton Private"+O]],[/\bfocus\/([\w\.]+)/i],[C,[k,xi+" Focus"]],[/ mms\/([\w\.]+)$/i],[C,[k,b+" Neon"]],[/ opt\/([\w\.]+)$/i],[C,[k,b+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[C,[k,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[C,[k,"Dolphin"]],[/coast\/([\w\.]+)/i],[C,[k,b+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[C,[k,"MIUI"+O]],[/fxios\/([\w\.-]+)/i],[C,[k,Ci+xi]],[/\bqihoobrowser\/?([\w\.]*)/i],[C,[k,"360"]],[/\b(qq)\/([\w\.]+)/i],[[k,/(.+)/,"$1Browser"],C],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[k,/(.+)/,"$1"+O],C],[/ HBPC\/([\w\.]+)/],[C,[k,wi+O]],[/samsungbrowser\/([\w\.]+)/i],[C,[k,hi+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[C,[k,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[k,"Sogou Mobile"],C],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[k,C],[/(lbbrowser|luakit|rekonq|steam(?= (clie|tenf|gameo)))/i],[k],[/ome\/([\w\.]+).+(iron(?= saf)|360(?=[es]e$))/i],[C,k],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[k,yi],C,[x,r]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(bing)(?:web|sapphire)\/([\w\.]+)/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[k,C,[x,r]],[/\bgsa\/([\w\.]+) .*safari\//i],[C,[k,"GSA"],[x,r]],[/(?:musical_ly|trill)(?:.+app_?version\/|_)([\w\.]+)/i],[C,[k,"TikTok"],[x,r]],[/\[(linkedin)app\]/i],[k,[x,r]],[/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i],[[k,/(.+)/,"Zalo"],C,[x,r]],[/(chromium)[\/ ]([-\w\.]+)/i],[k,C],[/ome-(lighthouse)$/i],[k,[x,"fetcher"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[C,[k,"Chrome Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[C,[k,ki+" WebView2"],[x,r]],[/; wv\).+(chrome)\/([\w\.]+)/i],[[k,"Chrome WebView"],C,[x,r]],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[C,[k,"Android"+O]],[/chrome\/([\w\.]+) mobile/i],[C,[k,Ci+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[k,C],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[C,[k,Ci+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[k,Ci+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[C,k],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[k,[C,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[k,C],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[k,Ci+xi],C],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[k,"Netscape"],C],[/(wolvic|librewolf)\/([\w\.]+)/i],[k,C],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[C,[k,xi+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[k,[C,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[k,[C,/[^\d\.]+./,d]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[N,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[N,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[N,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[N,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[N,"arm"]],[/ sun4\w[;\)]/i],[[N,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,/((ppc|powerpc)(64)?)( mac|;|\))/i,/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i],[[N,/ower/,d,q]],[/mc680.0/i],[[N,"68k"]],[/winnt.+\[axp/i],[[N,"alpha"]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[E,[y,hi],[x,t]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[E,[y,hi],[x,S]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i],[E,[y,s],[x,S]],[/\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,/\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i],[E,[y,s],[x,t]],[/(macintosh);/i],[E,[y,s]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[E,[y,"Sharp"],[x,S]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[E,[y,di],[x,t]],[/honor([-\w ]+)[;\)]/i],[E,[y,di],[x,S]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[E,[y,wi],[x,t]],[/(?:huawei) ?([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i],[E,[y,wi],[x,S]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[E,/_/g," "],[y,fi],[x,t]],[/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,/; ([\w ]+) miui\/v?\d/i],[[E,/_/g," "],[y,fi],[x,S]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-l]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[E,[y,pi],[x,S]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[E,[y,ui],[x,S]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[E,[y,p,{OnePlus:["203","304","403","404","413","415"],"*":ui}],[x,t]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[E,[y,"BLU"],[x,S]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[E,[y,"Vivo"],[x,S]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[E,[y,"Realme"],[x,S]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[E,[y,bi],[x,t]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[E,[y,bi],[x,S]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[E,[y,ci],[x,S]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[E,[y,ci],[x,t]],[/\b(?:lg)?([vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[E,[y,"LG"],[x,t]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[E,[y,"LG"],[x,S]],[/(nokia) (t[12][01])/i],[y,E,[x,t]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i],[[E,/_/g," "],[x,S],[y,"Nokia"]],[/(pixel (c|tablet))\b/i],[E,[y,n],[x,t]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[E,[y,n],[x,S]],[/(google) (pixelbook( go)?)/i],[y,E],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[E,[y,mi],[x,S]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[E,"Xperia Tablet"],[y,mi],[x,t]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[E,[y,ai],[x,t]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[E,/(.+)/g,"Fire Phone $1"],[y,ai],[x,S]],[/(playbook);[-\w\),; ]+(rim)/i],[E,y,[x,t]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/(?:blackberry|\(bb10;) (\w+)/i],[E,[y,ni],[x,S]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[E,[y,si],[x,t]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[E,[y,si],[x,S]],[/(nexus 9)/i],[E,[y,"HTC"],[x,t]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[y,[E,/_/g," "],[x,S]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[E,[y,"TCL"],[x,t]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[E,[y,"TCL"],[x,S]],[/(itel) ((\w+))/i],[[y,q],E,[x,p,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[E,[y,"Acer"],[x,t]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[E,[y,"Meizu"],[x,S]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[E,[y,"Ulefone"],[x,S]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[E,[y,"Energizer"],[x,S]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[E,[y,"Cat"],[x,S]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[E,[y,"Smartfren"],[x,S]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[E,[y,"Nothing"],[x,S]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[E,[y,"Archos"],[x,t]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[E,[y,"Archos"],[x,S]],[/blackview ([-\w ]+)( b|\))/i,/; (bv\d{4}[-\w ]*)( b|\))/i],[E,[y,"Blackview"],[x,S]],[/; (n159v)/i],[E,[y,"HMD"],[x,S]],[/((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i],[E,[x,function(i,e){return e.test.test(i)?e.ifTrue:e.ifFalse},{test:/ta?b/i,ifTrue:t,ifFalse:S}],[y,"T-Mobile"]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[y,E,[x,t]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i,/(hisense) ([ehv][\w ]+)\)/i,/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i],[y,E,[x,S]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[y,E,[x,t]],[/(surface duo)/i],[E,[y,li],[x,t]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[E,[y,"Fairphone"],[x,S]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[E,[y,"Nvidia"],[x,t]],[/(sprint) (\w+)/i],[y,E,[x,S]],[/(kin\.[onetw]{3})/i],[[E,/\./g," "],[y,li],[x,S]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[E,[y,gi],[x,t]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[E,[y,gi],[x,S]],[/(philips)[\w ]+tv/i,/smart-tv.+(samsung)/i],[y,[x,e]],[/hbbtv.+maple;(\d+)/i],[[E,/^/,"SmartTV"],[y,hi],[x,e]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[y,E,[x,e]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[y,"LG"],[x,e]],[/(apple) ?tv/i],[y,[E,s+" TV"],[x,e]],[/crkey.*devicetype\/chromecast/i],[[E,w+" Third Generation"],[y,n],[x,e]],[/crkey.*devicetype\/([^/]*)/i],[[E,/^/,"Chromecast "],[y,n],[x,e]],[/fuchsia.*crkey/i],[[E,w+" Nest Hub"],[y,n],[x,e]],[/crkey/i],[[E,w],[y,n],[x,e]],[/(portaltv)/i],[E,[y,yi],[x,e]],[/droid.+aft(\w+)( bui|\))/i],[E,[y,ai],[x,e]],[/(shield \w+ tv)/i],[E,[y,"Nvidia"],[x,e]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[E,[y,"Sharp"],[x,e]],[/(bravia[\w ]+)( bui|\))/i],[E,[y,mi],[x,e]],[/(mi(tv|box)-?\w+) bui/i],[E,[y,fi],[x,e]],[/Hbbtv.*(technisat) (.*);/i],[y,E,[x,e]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[y,/.+\/(\w+)/,"$1",p,{LG:"lge"}],[E,qi],[x,e]],[/(playstation \w+)/i],[E,[y,mi],[x,R]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[E,[y,li],[x,R]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i,/(valve).+(steam deck)/i,/droid.+; ((shield|rgcube|gr0006))( bui|\))/i],[[y,p,{Nvidia:"Shield",Anbernic:"RGCUBE",Logitech:"GR0006"}],E,[x,R]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[E,[y,hi],[x,o]],[/((pebble))app/i,/(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[y,E,[x,o]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[E,[y,ui],[x,o]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[E,[y,s],[x,o]],[/(opwwe\d{3})/i],[E,[y,pi],[x,o]],[/(moto 360)/i],[E,[y,ci],[x,o]],[/(smartwatch 3)/i],[E,[y,mi],[x,o]],[/(g watch r)/i],[E,[y,"LG"],[x,o]],[/droid.+; (wt63?0{2,3})\)/i],[E,[y,gi],[x,o]],[/droid.+; (glass) \d/i],[E,[y,n],[x,G]],[/(pico) ([\w ]+) os\d/i],[y,E,[x,G]],[/(quest( \d| pro)?s?).+vr/i],[E,[y,yi],[x,G]],[/mobile vr; rv.+firefox/i],[[x,G]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[y,[x,L]],[/(aeobc)\b/i],[E,[y,ai],[x,L]],[/(homepod).+mac os/i],[E,[y,s],[x,L]],[/windows iot/i],[[x,L]],[/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i],[E,[x,e]],[/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i],[[x,e]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i],[E,[x,p,{mobile:"Mobile",xr:"VR","*":t}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[x,t]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[x,S]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[E,[y,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[C,[k,ki+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[k,C],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[C,[k,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links|dillo)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[k,C],[/ladybird\//i],[[k,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[C,k]],os:[[/(windows nt) (6\.[23]); arm/i],[[k,/N/,"R"],[C,p,Di]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[k,C],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[C,/(;|\))/g,"",p,Di],[k,Ni]],[/(windows ce)\/?([\d\.]*)/i],[k,C],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,/\btvos ?([\w\.]+)/i,/cfnetwork\/.+darwin/i],[[C,/_/g,"."],[k,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[k,"macOS"],[C,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[C,[k,w+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[C,[k,w+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[C,[k,w+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[C,[k,w+" Linux"]],[/crkey\/([\d\.]+)/i],[C,[k,w]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[C,k],[/(ubuntu) ([\w\.]+) like android/i],[[k,/(.+)/,"$1 Touch"],C],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[k,C],[/\(bb(10);/i],[C,[k,ni]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[C,[k,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile[;\w ]*|tablet|tv|[^\)]*(?:viera|lg(?:l25|-d300)|alcatel ?o.+|y300-f1)); rv:([\w\.]+)\).+gecko\//i],[C,[k,xi+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[C,[k,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[C,p,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[k,"webOS"]],[/watch(?: ?os[,\/ ]|\d,\d\/)([\d\.]+)/i],[C,[k,"watchOS"]],[/cros [\w]+(?:\)| ([\w\.]+)\b)/i],[C,[k,"Chrome OS"]],[/kepler ([\w\.]+); (aft|aeo)/i],[C,[k,"Vega OS"]],[/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[k,C],[/(sunos) ?([\d\.]*)/i],[[k,"Solaris"],C],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[k,C]]},Hi=(b={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}},D.call(b.init,[[u,[k,C,j,x]],[h,[N]],[m,[x,E,y]],[f,[k,C]],[g,[k,C]]]),D.call(b.isIgnore,[[u,[C,j]],[f,[C]],[g,[C]]]),D.call(b.isIgnoreRgx,[[u,/ ?browser$/i],[g,/ ?os$/i]]),D.call(b.toString,[[u,[k,C]],[h,[N]],[m,[y,E]],[f,[k,C]],[g,[k,C]]]),b);function Ai(i,e){if(i=i||{},D.call(this,ri),e)D.call(this,[[$,Oi(i[a])],[W,Oi(i[Y])],[S,/\?1/.test(i[ii])],[E,Ui(i[ei])],[I,Ui(i[ti])],[J,Ui(i[oi])],[N,Ui(i[Z])],[T,Oi(i[K])],[X,Ui(i[Q])]]);else for(var t in i)this.hasOwnProperty(t)&&typeof i[t]!==l.UNDEFINED&&(this[t]=i[t])}function F(i,e,t,o){return D.call(this,[["itemType",i],["ua",e],["uaCH",o],["rgxMap",t],["data",M(this,i)]]),this}function z(i,e,t){if(typeof i===l.OBJECT?(e=Ti(i,!0)?(typeof e===l.OBJECT&&(t=e),i):(t=i,c),i=c):typeof i!==l.STRING||Ti(e,!0)||(t=e,e=c),t)if(typeof t.append===l.FUNCTION){var o={};t.forEach(function(i,e){o[String(e).toLowerCase()]=i}),t=o}else{var r,a={};for(r in t)t.hasOwnProperty(r)&&(a[String(r).toLowerCase()]=t[r]);t=a}var s,n,w,b;return this instanceof z?(s=typeof i===l.STRING?i:t&&t[V]?t[V]:U&&U.userAgent?U.userAgent:d,n=new Ai(t,!0),w=Bi,D.call(this,[["getBrowser",(b=function(i){return i==v?function(){return new F(i,s,w,n).set("ua",s).set(u,this.getBrowser()).set(h,this.getCPU()).set(m,this.getDevice()).set(f,this.getEngine()).set(g,this.getOS()).get()}:function(){return new F(i,s,w[i],n).parseUA().get()}})(u)],["getCPU",b(h)],["getDevice",b(m)],["getEngine",b(f)],["getOS",b(g)],["getResult",b(v)],["getUA",function(){return s}],["setUA",function(i){return Ii(i)&&(s=qi(i,P)),this}],["useExtension",function(i){return i&&(w=((i,e)=>{var t,o={},r=e;if(!Ti(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(w,i)),this}]]).setUA(s).useExtension(e),this):new z(i,e,t).getResult()}F.prototype.get=function(i){return i?this.data.hasOwnProperty(i)?this.data[i]:c:this.data},F.prototype.set=function(i,e){return this.data[i]=e,this},F.prototype.setCH=function(i){return this.uaCH=i,this},F.prototype.detectFeature=function(){if(U&&U.userAgent==this.ua)switch(this.itemType){case u:U.brave&&typeof U.brave.isBrave==l.FUNCTION&&this.set(k,"Brave");break;case m:!this.get(x)&&_&&_[S]&&this.set(x,S),"Macintosh"==this.get(E)&&U&&typeof U.standalone!==l.UNDEFINED&&U.maxTouchPoints&&2<U.maxTouchPoints&&this.set(E,"iPad").set(x,t);break;case g:!this.get(k)&&_&&_[I]&&this.set(k,_[I]);break;case v:var e=this.data,i=function(i){return e[i].getItem().detectFeature().get()};this.set(u,i(u)).set(h,i(h)).set(m,i(m)).set(f,i(f)).set(g,i(g))}return this},F.prototype.parseUA=function(){switch(this.itemType!=v&&A.call(this.data,this.ua,this.rgxMap),this.itemType){case u:this.set(j,H(this.get(C)));break;case g:var i;"iOS"==this.get(k)&&this.get(C)&&/^1[89][^\d]/.exec(this.get(C))&&(i=/\) Version\/((\d+)[\d\.]*)/.exec(this.ua))&&26<=parseInt(i[2],10)&&this.set(C,i[1])}return this},F.prototype.parseCH=function(){var i,e=this.uaCH,t=this.rgxMap;switch(this.itemType){case u:case f:var o,r=e[W]||e[$];if(r)for(var a=0;a<r.length;a++){var s=r[a].brand||r[a],n=r[a].version;this.itemType==u&&!/not.a.brand/i.test(s)&&(!o||/Chrom/.test(o)&&s!=vi||o==ki&&/WebView2/.test(s))&&(s=p(s,zi),(o=this.get(k))&&!/Chrom/.test(o)&&/Chrom/.test(s)||this.set(k,s).set(C,n).set(j,H(n)),o=s),this.itemType==f&&s==vi&&this.set(C,n)}break;case h:var w=e[N];w&&("64"==e[X]&&(w+="64"),A.call(this.data,w+";",t));break;case m:if(e[S]&&this.set(x,S),e[E]&&(this.set(E,e[E]),this.get(x)&&this.get(y)||(A.call(w={},"droid 9; "+e[E]+")",t),!this.get(x)&&w.type&&this.set(x,w.type),!this.get(y)&&w.vendor&&this.set(y,w.vendor))),e[T]){if("string"!=typeof e[T])for(var b=0;!i&&b<e[T].length;)i=p(e[T][b++],Fi);else i=p(e[T],Fi);this.set(x,i)}break;case g:var d,w=e[I];w&&(d=e[J],w==Ni&&(d=13<=parseInt(H(d),10)?"11":"10"),this.set(k,w).set(C,d)),this.get(k)==Ni&&"Xbox"==e[E]&&this.set(k,"Xbox").set(C,c);break;case v:var l=this.data,w=function(i){return l[i].getItem().setCH(e).parseCH().get()};this.set(u,w(u)).set(h,w(h)).set(m,w(m)).set(f,w(f)).set(g,w(g))}return this},z.VERSION="2.0.10",z.BROWSER=B([k,C,j,x]),z.CPU=B([N]),z.DEVICE=B([E,y,x,R,S,e,t,o,L]),z.ENGINE=z.OS=B([k,C]),typeof exports!==l.UNDEFINED?(exports=typeof module!==l.UNDEFINED&&module.exports?module.exports=z:exports).UAParser=z:typeof define===l.FUNCTION&&define.amd?define(function(){return z}):Ei&&(i.UAParser=z);var Mi,Pi=Ei&&(i.jQuery||i.Zepto);Pi&&!Pi.ua&&(Mi=new z,Pi.ua=Mi.getResult(),Pi.ua.get=function(){return Mi.getUA()},Pi.ua.set=function(i){Mi.setUA(i);var e,t=Mi.getResult();for(e in t)Pi.ua[e]=t[e]})})("object"==typeof window?window:this);
dist/ua-parser.pack.mjs +2 lines · 1 flagged
--- +++ @@ -1,4 +1,4 @@-/* UAParser.js v2.0.9+/* UAParser.js v2.0.10    Copyright © 2012-2026 Faisal Salman <[email protected]>    AGPLv3 License */-function B(i){for(var e={},o=0;o<i.length;o++)e[i[o].toUpperCase()]=i[o];return e}function H(i){return Si(i)?z(/[^\d\.]/g,i).split(".")[0]:void 0}function A(i,e){if(i&&e)for(var o,t,r,a,s,n=0;n<e.length&&!a;){for(var w=e[n],d=e[n+1],b=o=0;b<w.length&&!a&&w[b];)if(a=w[b++].exec(i))for(t=0;t<d.length;t++)s=a[++o],typeof(r=d[t])===l.OBJECT&&0<r.length?2===r.length?typeof r[1]==l.FUNCTION?this[r[0]]=r[1].call(this,s):this[r[0]]=r[1]:3<=r.length&&(typeof r[1]!==l.FUNCTION||r[1].exec&&r[1].test?3==r.length?this[r[0]]=s?s.replace(r[1],r[2]):void 0:4==r.length?this[r[0]]=s?r[3].call(this,s.replace(r[1],r[2])):void 0:4<r.length&&(this[r[0]]=s?r[3].apply(this,[s.replace(r[1],r[2])].concat(r.slice(4))):void 0):3<r.length?this[r[0]]=s?r[1].apply(this,r.slice(2)):void 0:this[r[0]]=s?r[1].call(this,s,r[2]):void 0):this[r]=s||void 0;n+=2}}function c(i,e){for(var o in e)if(typeof e[o]===l.OBJECT&&0<e[o].length){for(var t=0;t<e[o].length;t++)if(Ni(e[o][t],i))return"?"===o?void 0:o}else if(Ni(e[o],i))return"?"===o?void 0:o;return e.hasOwnProperty("*")?e["*"]:i}function M(e,i){var o=Di.init[i],t=Di.isIgnore[i]||0,r=Di.isIgnoreRgx[i]||0,a=Di.toString[i]||0;function s(){U.call(this,o)}return s.prototype.getItem=function(){return e},s.prototype.withClientHints=function(){return _?_.getHighEntropyValues(ti).then(function(i){return e.setCH(new Fi(i,!1)).parseCH().get()}):e.parseCH().get()},s.prototype.withFeatureCheck=function(){return e.detectFeature().get()},i!=f&&(s.prototype.is=function(i){var e,o=!1;for(e in this)if(this.hasOwnProperty(e)&&!Ni(t,e)&&q(r?z(r,this[e]):this[e])==q(r?z(r,i):i)){if(o=!0,i!=l.UNDEFINED)break}else if(i==l.UNDEFINED&&o){o=!o;break}return o},s.prototype.toString=function(){var i,e=b;for(i in a)typeof this[a[i]]!==l.UNDEFINED&&(e+=(e?" ":b)+this[a[i]]);return e||l.UNDEFINED}),s.prototype.then=function(i){function e(){for(var i in o)o.hasOwnProperty(i)&&(this[i]=o[i])}var o=this,t=(e.prototype={is:s.prototype.is,toString:s.prototype.toString,withClientHints:s.prototype.withClientHints,withFeatureCheck:s.prototype.withFeatureCheck},new e);return i(t),t},new s}var V="user-agent",b="",l={FUNCTION:"function",OBJECT:"object",STRING:"string",UNDEFINED:"undefined"},h="browser",p="cpu",u="device",m="engine",g="os",f="result",v="name",k="type",x="vendor",y="version",C="architecture",P="major",N="model",j="console",E="mobile",o="tablet",i="smarttv",e="wearable",R="xr",G="embedded",t="inapp",L="brands",S="formFactors",$="fullVersionList",T="platform",W="platformVersion",J="bitness",r="sec-ch-ua",X=r+"-full-version-list",Y=r+"-arch",Z=r+"-"+J,K=r+"-form-factors",Q=r+"-"+E,ii=r+"-"+N,ei=r+"-"+T,oi=ei+"-version",ti=[L,$,E,N,T,W,C,S,J],ri="Amazon",a="Apple",ai="ASUS",si="BlackBerry",s="Google",ni="Huawei",wi="Lenovo",di="Honor",bi="LG",li="Microsoft",ci="Motorola",hi="OnePlus",pi="OPPO",ui="Samsung",mi="Sony",gi="Xiaomi",fi="Zebra",vi="Chromium",n="Chromecast",ki="Edge",xi="Firefox",w="Opera",yi="Facebook",d="Mobile ",O=" Browser",Ci="Windows",I=typeof window!==l.UNDEFINED&&window.navigator?window.navigator:void 0,_=I&&I.userAgentData?I.userAgentData:void 0,Ni=function(i,e){if(typeof i===l.OBJECT&&0<i.length){for(var o in i)if(q(e)==q(i[o]))return!0;return!1}return!!Si(i)&&q(e)==q(i)},Ei=function(i,e){for(var o in i)return/^(browser|cpu|device|engine|os)$/.test(o)||!!e&&Ei(i[o])},Si=function(i){return typeof i===l.STRING},Ti=function(i){if(i){for(var e,o=[],t=z(/\\?\"/g,i).split(","),r=0;r<t.length;r++)-1<t[r].indexOf(";")?(e=Ii(t[r]).split(";v="),o[r]={brand:e[0],version:e[1]}):o[r]=Ii(t[r]);return o}},q=function(i){return Si(i)?i.toLowerCase():i},U=function(i){for(var e in i)i.hasOwnProperty(e)&&(typeof(e=i[e])==l.OBJECT&&2==e.length?this[e[0]]=e[1]:this[e]=void 0);return this},z=function(i,e){return Si(e)?e.replace(i,b):e},Oi=function(i){return z(/\\?\"/g,i)},Ii=function(i,e){return i=z(/^\s\s*/,String(i)),typeof e===l.UNDEFINED?i:i.substring(0,e)},_i={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2",8.1:"6.3",10:["6.4","10.0"],NT:""},qi={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":void 0},Ui={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},zi={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[y,[v,d+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[y,[v,ki+" WebView"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[y,[v,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[v,y],[/opios[\/ ]+([\w\.]+)/i],[y,[v,w+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[y,[v,w+" GX"]],[/\bopr\/([\w\.]+)/i],[y,[v,w]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[y,[v,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[y,[v,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:hi|lg |ovi|qute)browser|palemoon)\/v?([-\w\.]+)/i,/(brave)(?: chrome)?\/([\d\.]+)/i,/(aloha|heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,/(qwant)(?:ios|mobile)\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[v,y],[/quark(?:pc)?\/([-\w\.]+)/i],[y,[v,"Quark"]],[/\bddg\/([\w\.]+)/i],[y,[v,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[y,[v,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[y,[v,"WeChat"]],[/konqueror\/([\w\.]+)/i],[y,[v,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[y,[v,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[y,[v,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[y,[v,"Smart "+wi+O]],[/(av(?:ast|g|ira))\/([\w\.]+)/i],[[v,/(.+)/,"$1 Secure"+O],y],[/norton\/([\w\.]+)/i],[y,[v,"Norton Private"+O]],[/\bfocus\/([\w\.]+)/i],[y,[v,xi+" Focus"]],[/ mms\/([\w\.]+)$/i],[y,[v,w+" Neon"]],[/ opt\/([\w\.]+)$/i],[y,[v,w+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[y,[v,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[y,[v,"Dolphin"]],[/coast\/([\w\.]+)/i],[y,[v,w+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[y,[v,"MIUI"+O]],[/fxios\/([\w\.-]+)/i],[y,[v,d+xi]],[/\bqihoobrowser\/?([\w\.]*)/i],[y,[v,"360"]],[/\b(qq)\/([\w\.]+)/i],[[v,/(.+)/,"$1Browser"],y],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[v,/(.+)/,"$1"+O],y],[/samsungbrowser\/([\w\.]+)/i],[y,[v,ui+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[y,[v,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[v,"Sogou Mobile"],y],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[v,y],[/(lbbrowser|luakit|rekonq|steam(?= (clie|tenf|gameo)))/i],[v],[/ome\/([\w\.]+).+(iron(?= saf)|360(?=[es]e$))/i],[y,v],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[v,yi],y,[k,t]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(bing)(?:web|sapphire)\/([\w\.]+)/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[v,y,[k,t]],[/\bgsa\/([\w\.]+) .*safari\//i],[y,[v,"GSA"],[k,t]],[/(?:musical_ly|trill)(?:.+app_?version\/|_)([\w\.]+)/i],[y,[v,"TikTok"],[k,t]],[/\[(linkedin)app\]/i],[v,[k,t]],[/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i],[[v,/(.+)/,"Zalo"],y,[k,t]],[/(chromium)[\/ ]([-\w\.]+)/i],[v,y],[/ome-(lighthouse)$/i],[v,[k,"fetcher"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[y,[v,"Chrome Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[y,[v,ki+" WebView2"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[v,"Chrome WebView"],y],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[y,[v,"Android"+O]],[/chrome\/([\w\.]+) mobile/i],[y,[v,d+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[v,y],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[y,[v,d+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[v,d+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[y,v],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[v,[y,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[v,y],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[v,d+xi],y],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[v,"Netscape"],y],[/(wolvic|librewolf)\/([\w\.]+)/i],[v,y],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[y,[v,xi+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[v,[y,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[v,[y,/[^\d\.]+./,b]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[C,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[C,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[C,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[C,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[C,"arm"]],[/ sun4\w[;\)]/i],[[C,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,/((ppc|powerpc)(64)?)( mac|;|\))/i,/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i],[[C,/ower/,b,q]],[/mc680.0/i],[[C,"68k"]],[/winnt.+\[axp/i],[[C,"alpha"]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[N,[x,ui],[k,o]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[N,[x,ui],[k,E]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i],[N,[x,a],[k,E]],[/\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,/\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i],[N,[x,a],[k,o]],[/(macintosh);/i],[N,[x,a]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[N,[x,"Sharp"],[k,E]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[N,[x,di],[k,o]],[/honor([-\w ]+)[;\)]/i],[N,[x,di],[k,E]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[N,[x,ni],[k,o]],[/(?:huawei) ?([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i],[N,[x,ni],[k,E]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[N,/_/g," "],[x,gi],[k,o]],[/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[N,/_/g," "],[x,gi],[k,E]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-l]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[N,[x,hi],[k,E]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[N,[x,pi],[k,E]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[N,[x,c,{OnePlus:["203","304","403","404","413","415"],"*":pi}],[k,o]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[N,[x,"BLU"],[k,E]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[N,[x,"Vivo"],[k,E]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[N,[x,"Realme"],[k,E]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[N,[x,wi],[k,o]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[N,[x,wi],[k,E]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[N,[x,ci],[k,E]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[N,[x,ci],[k,o]],[/\b(?:lg)?([vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[N,[x,bi],[k,o]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[N,[x,bi],[k,E]],[/(nokia) (t[12][01])/i],[x,N,[k,o]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i],[[N,/_/g," "],[k,E],[x,"Nokia"]],[/(pixel (c|tablet))\b/i],[N,[x,s],[k,o]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[N,[x,s],[k,E]],[/(google) (pixelbook( go)?)/i],[x,N],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[N,[x,mi],[k,E]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[N,"Xperia Tablet"],[x,mi],[k,o]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[N,[x,ri],[k,o]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[N,/(.+)/g,"Fire Phone $1"],[x,ri],[k,E]],[/(playbook);[-\w\),; ]+(rim)/i],[N,x,[k,o]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/(?:blackberry|\(bb10;) (\w+)/i],[N,[x,si],[k,E]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[N,[x,ai],[k,o]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[N,[x,ai],[k,E]],[/(nexus 9)/i],[N,[x,"HTC"],[k,o]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[x,[N,/_/g," "],[k,E]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[N,[x,"TCL"],[k,o]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[N,[x,"TCL"],[k,E]],[/(itel) ((\w+))/i],[[x,q],N,[k,c,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[N,[x,"Acer"],[k,o]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[N,[x,"Meizu"],[k,E]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[N,[x,"Ulefone"],[k,E]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[N,[x,"Energizer"],[k,E]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[N,[x,"Cat"],[k,E]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[N,[x,"Smartfren"],[k,E]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[N,[x,"Nothing"],[k,E]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[N,[x,"Archos"],[k,o]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[N,[x,"Archos"],[k,E]],[/; (n159v)/i],[N,[x,"HMD"],[k,E]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[x,N,[k,o]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i,/(hisense) ([ehv][\w ]+)\)/i,/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i],[x,N,[k,E]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[x,N,[k,o]],[/(surface duo)/i],[N,[x,li],[k,o]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[N,[x,"Fairphone"],[k,E]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[N,[x,"Nvidia"],[k,o]],[/(sprint) (\w+)/i],[x,N,[k,E]],[/(kin\.[onetw]{3})/i],[[N,/\./g," "],[x,li],[k,E]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[N,[x,fi],[k,o]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[N,[x,fi],[k,E]],[/(philips)[\w ]+tv/i,/smart-tv.+(samsung)/i],[x,[k,i]],[/hbbtv.+maple;(\d+)/i],[[N,/^/,"SmartTV"],[x,ui],[k,i]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[x,N,[k,i]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[x,bi],[k,i]],[/(apple) ?tv/i],[x,[N,a+" TV"],[k,i]],[/crkey.*devicetype\/chromecast/i],[[N,n+" Third Generation"],[x,s],[k,i]],[/crkey.*devicetype\/([^/]*)/i],[[N,/^/,"Chromecast "],[x,s],[k,i]],[/fuchsia.*crkey/i],[[N,n+" Nest Hub"],[x,s],[k,i]],[/crkey/i],[[N,n],[x,s],[k,i]],[/(portaltv)/i],[N,[x,yi],[k,i]],[/droid.+aft(\w+)( bui|\))/i],[N,[x,ri],[k,i]],[/(shield \w+ tv)/i],[N,[x,"Nvidia"],[k,i]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[N,[x,"Sharp"],[k,i]],[/(bravia[\w ]+)( bui|\))/i],[N,[x,mi],[k,i]],[/(mi(tv|box)-?\w+) bui/i],[N,[x,gi],[k,i]],[/Hbbtv.*(technisat) (.*);/i],[x,N,[k,i]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[x,/.+\/(\w+)/,"$1",c,{LG:"lge"}],[N,Ii],[k,i]],[/(playstation \w+)/i],[N,[x,mi],[k,j]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[N,[x,li],[k,j]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i,/(valve).+(steam deck)/i,/droid.+; ((shield|rgcube|gr0006))( bui|\))/i],[[x,c,{Nvidia:"Shield",Anbernic:"RGCUBE",Logitech:"GR0006"}],N,[k,j]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[N,[x,ui],[k,e]],[/((pebble))app/i,/(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[x,N,[k,e]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[N,[x,pi],[k,e]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[N,[x,a],[k,e]],[/(opwwe\d{3})/i],[N,[x,hi],[k,e]],[/(moto 360)/i],[N,[x,ci],[k,e]],[/(smartwatch 3)/i],[N,[x,mi],[k,e]],[/(g watch r)/i],[N,[x,bi],[k,e]],[/droid.+; (wt63?0{2,3})\)/i],[N,[x,fi],[k,e]],[/droid.+; (glass) \d/i],[N,[x,s],[k,R]],[/(pico) ([\w ]+) os\d/i],[x,N,[k,R]],[/(quest( \d| pro)?s?).+vr/i],[N,[x,yi],[k,R]],[/mobile vr; rv.+firefox/i],[[k,R]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[x,[k,G]],[/(aeobc)\b/i],[N,[x,ri],[k,G]],[/(homepod).+mac os/i],[N,[x,a],[k,G]],[/windows iot/i],[[k,G]],[/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i],[N,[k,i]],[/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i],[[k,i]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i],[N,[k,c,{mobile:"Mobile",xr:"VR","*":o}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[k,o]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[k,E]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[N,[x,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[y,[v,ki+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[v,y],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[y,[v,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links|dillo)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[v,y],[/ladybird\//i],[[v,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[y,v]],os:[[/(windows nt) (6\.[23]); arm/i],[[v,/N/,"R"],[y,c,_i]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[v,y],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[y,/(;|\))/g,"",c,_i],[v,Ci]],[/(windows ce)\/?([\d\.]*)/i],[v,y],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,/\btvos ?([\w\.]+)/i,/cfnetwork\/.+darwin/i],[[y,/_/g,"."],[v,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[v,"macOS"],[y,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[y,[v,n+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[y,[v,n+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[y,[v,n+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[y,[v,n+" Linux"]],[/crkey\/([\d\.]+)/i],[y,[v,n]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[y,v],[/(ubuntu) ([\w\.]+) like android/i],[[v,/(.+)/,"$1 Touch"],y],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[v,y],[/\(bb(10);/i],[y,[v,si]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[y,[v,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile[;\w ]*|tablet|tv|[^\)]*(?:viera|lg(?:l25|-d300)|alcatel ?o.+|y300-f1)); rv:([\w\.]+)\).+gecko\//i],[y,[v,xi+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[y,[v,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[y,c,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[v,"webOS"]],[/watch(?: ?os[,\/ ]|\d,\d\/)([\d\.]+)/i],[y,[v,"watchOS"]],[/cros [\w]+(?:\)| ([\w\.]+)\b)/i],[y,[v,"Chrome OS"]],[/kepler ([\w\.]+); (aft|aeo)/i],[y,[v,"Vega OS"]],[/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[v,y],[/(sunos) ?([\d\.]*)/i],[[v,"Solaris"],y],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[v,y]]},Di=(w={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}},U.call(w.init,[[h,[v,y,P,k]],[p,[C]],[u,[k,N,x]],[m,[v,y]],[g,[v,y]]]),U.call(w.isIgnore,[[h,[y,P]],[m,[y]],[g,[y]]]),U.call(w.isIgnoreRgx,[[h,/ ?browser$/i],[g,/ ?os$/i]]),U.call(w.toString,[[h,[v,y]],[p,[C]],[u,[x,N]],[m,[v,y]],[g,[v,y]]]),w);function Fi(i,e){if(i=i||{},U.call(this,ti),e)U.call(this,[[L,Ti(i[r])],[$,Ti(i[X])],[E,/\?1/.test(i[Q])],[N,Oi(i[ii])],[T,Oi(i[ei])],[W,Oi(i[oi])],[C,Oi(i[Y])],[S,Ti(i[K])],[J,Oi(i[Z])]]);else for(var o in i)this.hasOwnProperty(o)&&typeof i[o]!==l.UNDEFINED&&(this[o]=i[o])}function D(i,e,o,t){return U.call(this,[["itemType",i],["ua",e],["uaCH",t],["rgxMap",o],["data",M(this,i)]]),this}function F(i,e,o){if(typeof i===l.OBJECT?(e=Ei(i,!0)?(typeof e===l.OBJECT&&(o=e),i):void(o=i),i=void 0):typeof i!==l.STRING||Ei(e,!0)||(o=e,e=void 0),o)if(typeof o.append===l.FUNCTION){var t={};o.forEach(function(i,e){t[String(e).toLowerCase()]=i}),o=t}else{var r,a={};for(r in o)o.hasOwnProperty(r)&&(a[String(r).toLowerCase()]=o[r]);o=a}var s,n,w,d;return this instanceof F?(s=typeof i===l.STRING?i:o&&o[V]?o[V]:I&&I.userAgent?I.userAgent:b,n=new Fi(o,!0),w=e?((i,e)=>{var o,t={},r=e;if(!Ei(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(o in i)t[o]=r[o]&&r[o].length%2==0?r[o].concat(i[o]):i[o];return t})(zi,e):zi,U.call(this,[["getBrowser",(d=function(i){return i==f?function(){return new D(i,s,w,n).set("ua",s).set(h,this.getBrowser()).set(p,this.getCPU()).set(u,this.getDevice()).set(m,this.getEngine()).set(g,this.getOS()).get()}:function(){return new D(i,s,w[i],n).parseUA().get()}})(h)],["getCPU",d(p)],["getDevice",d(u)],["getEngine",d(m)],["getOS",d(g)],["getResult",d(f)],["getUA",function(){return s}],["setUA",function(i){return Si(i)&&(s=Ii(i,500)),this}]]).setUA(s),this):new F(i,e,o).getResult()}D.prototype.get=function(i){return i?this.data.hasOwnProperty(i)?this.data[i]:void 0:this.data},D.prototype.set=function(i,e){return this.data[i]=e,this},D.prototype.setCH=function(i){return this.uaCH=i,this},D.prototype.detectFeature=function(){if(I&&I.userAgent==this.ua)switch(this.itemType){case h:I.brave&&typeof I.brave.isBrave==l.FUNCTION&&this.set(v,"Brave");break;case u:!this.get(k)&&_&&_[E]&&this.set(k,E),"Macintosh"==this.get(N)&&I&&typeof I.standalone!==l.UNDEFINED&&I.maxTouchPoints&&2<I.maxTouchPoints&&this.set(N,"iPad").set(k,o);break;case g:!this.get(v)&&_&&_[T]&&this.set(v,_[T]);break;case f:var e=this.data,i=function(i){return e[i].getItem().detectFeature().get()};this.set(h,i(h)).set(p,i(p)).set(u,i(u)).set(m,i(m)).set(g,i(g))}return this},D.prototype.parseUA=function(){switch(this.itemType!=f&&A.call(this.data,this.ua,this.rgxMap),this.itemType){case h:this.set(P,H(this.get(y)));break;case g:var i;"iOS"==this.get(v)&&"18.6"==this.get(y)&&(i=/\) Version\/([\d\.]+)/.exec(this.ua))&&26<=parseInt(i[1].substring(0,2),10)&&this.set(y,i[1])}return this},D.prototype.parseCH=function(){var i,e=this.uaCH,o=this.rgxMap;switch(this.itemType){case h:case m:var t,r=e[$]||e[L];if(r)for(var a=0;a<r.length;a++){var s=r[a].brand||r[a],n=r[a].version;this.itemType==h&&!/not.a.brand/i.test(s)&&(!t||/Chrom/.test(t)&&s!=vi||t==ki&&/WebView2/.test(s))&&(s=c(s,Ui),(t=this.get(v))&&!/Chrom/.test(t)&&/Chrom/.test(s)||this.set(v,s).set(y,n).set(P,H(n)),t=s),this.itemType==m&&s==vi&&this.set(y,n)}break;case p:var w=e[C];w&&("64"==e[J]&&(w+="64"),A.call(this.data,w+";",o));break;case u:if(e[E]&&this.set(k,E),e[N]&&(this.set(N,e[N]),this.get(k)&&this.get(x)||(A.call(w={},"droid 9; "+e[N]+")",o),!this.get(k)&&w.type&&this.set(k,w.type),!this.get(x)&&w.vendor&&this.set(x,w.vendor))),e[S]){if("string"!=typeof e[S])for(var d=0;!i&&d<e[S].length;)i=c(e[S][d++],qi);else i=c(e[S],qi);this.set(k,i)}break;case g:var b,w=e[T];w&&(b=e[W],w==Ci&&(b=13<=parseInt(H(b),10)?"11":"10"),this.set(v,w).set(y,b)),this.get(v)==Ci&&"Xbox"==e[N]&&this.set(v,"Xbox").set(y,void 0);break;case f:var l=this.data,w=function(i){return l[i].getItem().setCH(e).parseCH().get()};this.set(h,w(h)).set(p,w(p)).set(u,w(u)).set(m,w(m)).set(g,w(g))}return this},F.VERSION="2.0.9",F.BROWSER=B([v,y,P,k]),F.CPU=B([C]),F.DEVICE=B([N,x,k,j,E,i,o,e,G]),F.ENGINE=F.OS=B([v,y]);export{F as UAParser};+function D(i){for(var e={},t=0;t<i.length;t++)e[i[t].toUpperCase()]=i[t];return e}function H(i){return q(i)?Ii(/[^\d\.]/g,i).split(".")[0]:void 0}function M(i,e){if(i&&e)for(var t,o,r,a,s,n=0;n<e.length&&!a;){for(var w=e[n],b=e[n+1],d=t=0;d<w.length&&!a&&w[d];)if(a=w[d++].exec(i))for(o=0;o<b.length;o++)s=a[++t],typeof(r=b[o])===l.OBJECT&&0<r.length?2===r.length?typeof r[1]==l.FUNCTION?this[r[0]]=r[1].call(this,s):this[r[0]]=r[1]:3<=r.length&&(typeof r[1]!==l.FUNCTION||r[1].exec&&r[1].test?3==r.length?this[r[0]]=s?s.replace(r[1],r[2]):void 0:4==r.length?this[r[0]]=s?r[3].call(this,s.replace(r[1],r[2])):void 0:4<r.length&&(this[r[0]]=s?r[3].apply(this,[s.replace(r[1],r[2])].concat(r.slice(4))):void 0):3<r.length?this[r[0]]=s?r[1].apply(this,r.slice(2)):void 0:this[r[0]]=s?r[1].call(this,s,r[2]):void 0):this[r]=s||void 0;n+=2}}function c(i,e){for(var t in e)if(typeof e[t]===l.OBJECT&&0<e[t].length){for(var o=0;o<e[t].length;o++)if(Ni(e[t][o],i))return"?"===t?void 0:t}else if(Ni(e[t],i))return"?"===t?void 0:t;return e.hasOwnProperty("*")?e["*"]:i}function A(e,i){var t=Bi.init[i],o=Bi.isIgnore[i]||0,r=Bi.isIgnoreRgx[i]||0,a=Bi.toString[i]||0;function s(){z.call(this,t)}return s.prototype.getItem=function(){return e},s.prototype.withClientHints=function(){return _?_.getHighEntropyValues(ri).then(function(i){return e.setCH(new Di(i,!1)).parseCH().get()}):e.parseCH().get()},s.prototype.withFeatureCheck=function(){return e.detectFeature().get()},i!=g&&(s.prototype.is=function(i){var e,t=!1;for(e in this)if(this.hasOwnProperty(e)&&!Ni(o,e)&&U(r?Ii(r,this[e]):this[e])==U(r?Ii(r,i):i)){if(t=!0,i!=l.UNDEFINED)break}else if(i==l.UNDEFINED&&t){t=!t;break}return t},s.prototype.toString=function(){var i,e=d;for(i in a)typeof this[a[i]]!==l.UNDEFINED&&(e+=(e?" ":d)+this[a[i]]);return e||l.UNDEFINED}),s.prototype.then=function(i){function e(){for(var i in t)t.hasOwnProperty(i)&&(this[i]=t[i])}var t=this,o=(e.prototype={is:s.prototype.is,toString:s.prototype.toString,withClientHints:s.prototype.withClientHints,withFeatureCheck:s.prototype.withFeatureCheck},new e);return i(o),o},new s}var V=500,P="user-agent",d="",l={FUNCTION:"function",OBJECT:"object",STRING:"string",UNDEFINED:"undefined"},h="browser",p="cpu",u="device",m="engine",f="os",g="result",v="name",k="type",x="vendor",y="version",C="architecture",j="major",E="model",R="console",N="mobile",t="tablet",i="smarttv",e="wearable",G="xr",L="embedded",o="inapp",$="brands",S="formFactors",W="fullVersionList",T="platform",J="platformVersion",X="bitness",r="sec-ch-ua",Y=r+"-full-version-list",Z=r+"-arch",K=r+"-"+X,Q=r+"-form-factors",ii=r+"-"+N,ei=r+"-"+E,ti=r+"-"+T,oi=ti+"-version",ri=[$,W,N,E,T,J,C,S,X],ai="Amazon",a="Apple",si="ASUS",ni="BlackBerry",s="Google",wi="Huawei",bi="Lenovo",di="Honor",li="LG",ci="Microsoft",hi="Motorola",pi="OnePlus",ui="OPPO",mi="Samsung",fi="Sony",gi="Xiaomi",vi="Zebra",ki="Chromium",n="Chromecast",xi="Edge",yi="Firefox",w="Opera",Ci="Facebook",b="Mobile ",O=" Browser",Ei="Windows",I=typeof window!==l.UNDEFINED&&window.navigator?window.navigator:void 0,_=I&&I.userAgentData?I.userAgentData:void 0,Ni=function(i,e){if(typeof i===l.OBJECT&&0<i.length){for(var t in i)if(U(e)==U(i[t]))return!0;return!1}return!!q(i)&&U(e)==U(i)},Si=function(i,e){for(var t in i)return/^(browser|cpu|device|engine|os)$/.test(t)||!!e&&Si(i[t])},q=function(i){return typeof i===l.STRING},Ti=function(i){if(i){for(var e,t=[],o=Oi(i).split(","),r=0;r<o.length;r++)-1<o[r].indexOf(";")?(e=_i(o[r]).split(";v="),t[r]={brand:e[0],version:e[1]}):t[r]=_i(o[r]);return t}},U=function(i){return q(i)?i.toLowerCase():i},Oi=function(i){return q(i)?_i(Ii(/\\?\"/g,i),V):void 0},z=function(i){for(var e in i)i.hasOwnProperty(e)&&(typeof(e=i[e])==l.OBJECT&&2==e.length?this[e[0]]=e[1]:this[e]=void 0);return this},Ii=function(i,e){return q(e)?e.replace(i,d):e},_i=function(i,e){return i=Ii(/^\s\s*/,String(i)),typeof e===l.UNDEFINED?i:i.substring(0,e)},qi={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2",8.1:"6.3",10:["6.4","10.0"],NT:""},Ui={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":void 0},zi={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},Fi={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[y,[v,b+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[y,[v,xi+" WebView"],[k,o]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[y,[v,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[v,y],[/opios[\/ ]+([\w\.]+)/i],[y,[v,w+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[y,[v,w+" GX"]],[/\bopr\/([\w\.]+)/i],[y,[v,w]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[y,[v,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[y,[v,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:hi|lg |ovi|qute)browser|palemoon)\/v?([-\w\.]+)/i,/(brave)(?: chrome)?\/([\d\.]+)/i,/(aloha|heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,/(qwant)(?:ios|mobile)\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[v,y],[/quark(?:pc)?\/([-\w\.]+)/i],[y,[v,"Quark"]],[/\bddg\/([\w\.]+)/i],[y,[v,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i],[y,[v,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[y,[v,"WeChat"]],[/konqueror\/([\w\.]+)/i],[y,[v,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[y,[v,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[y,[v,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[y,[v,"Smart "+bi+O]],[/(av(?:ast|g|ira))\/([\w\.]+)/i],[[v,/(.+)/,"$1 Secure"+O],y],[/norton\/([\w\.]+)/i],[y,[v,"Norton Private"+O]],[/\bfocus\/([\w\.]+)/i],[y,[v,yi+" Focus"]],[/ mms\/([\w\.]+)$/i],[y,[v,w+" Neon"]],[/ opt\/([\w\.]+)$/i],[y,[v,w+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[y,[v,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[y,[v,"Dolphin"]],[/coast\/([\w\.]+)/i],[y,[v,w+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[y,[v,"MIUI"+O]],[/fxios\/([\w\.-]+)/i],[y,[v,b+yi]],[/\bqihoobrowser\/?([\w\.]*)/i],[y,[v,"360"]],[/\b(qq)\/([\w\.]+)/i],[[v,/(.+)/,"$1Browser"],y],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[v,/(.+)/,"$1"+O],y],[/ HBPC\/([\w\.]+)/],[y,[v,wi+O]],[/samsungbrowser\/([\w\.]+)/i],[y,[v,mi+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[y,[v,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[v,"Sogou Mobile"],y],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[v,y],[/(lbbrowser|luakit|rekonq|steam(?= (clie|tenf|gameo)))/i],[v],[/ome\/([\w\.]+).+(iron(?= saf)|360(?=[es]e$))/i],[y,v],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[v,Ci],y,[k,o]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(bing)(?:web|sapphire)\/([\w\.]+)/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[v,y,[k,o]],[/\bgsa\/([\w\.]+) .*safari\//i],[y,[v,"GSA"],[k,o]],[/(?:musical_ly|trill)(?:.+app_?version\/|_)([\w\.]+)/i],[y,[v,"TikTok"],[k,o]],[/\[(linkedin)app\]/i],[v,[k,o]],[/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i],[[v,/(.+)/,"Zalo"],y,[k,o]],[/(chromium)[\/ ]([-\w\.]+)/i],[v,y],[/ome-(lighthouse)$/i],[v,[k,"fetcher"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[y,[v,"Chrome Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[y,[v,xi+" WebView2"],[k,o]],[/; wv\).+(chrome)\/([\w\.]+)/i],[[v,"Chrome WebView"],y,[k,o]],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[y,[v,"Android"+O]],[/chrome\/([\w\.]+) mobile/i],[y,[v,b+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[v,y],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[y,[v,b+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[v,b+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[y,v],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[v,[y,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[v,y],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[v,b+yi],y],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[v,"Netscape"],y],[/(wolvic|librewolf)\/([\w\.]+)/i],[v,y],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[y,[v,yi+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[v,[y,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[v,[y,/[^\d\.]+./,d]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[C,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[C,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[C,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[C,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[C,"arm"]],[/ sun4\w[;\)]/i],[[C,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,/((ppc|powerpc)(64)?)( mac|;|\))/i,/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i],[[C,/ower/,d,U]],[/mc680.0/i],[[C,"68k"]],[/winnt.+\[axp/i],[[C,"alpha"]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[E,[x,mi],[k,t]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[E,[x,mi],[k,N]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i],[E,[x,a],[k,N]],[/\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,/\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i],[E,[x,a],[k,t]],[/(macintosh);/i],[E,[x,a]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[E,[x,"Sharp"],[k,N]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[E,[x,di],[k,t]],[/honor([-\w ]+)[;\)]/i],[E,[x,di],[k,N]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[E,[x,wi],[k,t]],[/(?:huawei) ?([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i],[E,[x,wi],[k,N]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[E,/_/g," "],[x,gi],[k,t]],[/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,/; ([\w ]+) miui\/v?\d/i],[[E,/_/g," "],[x,gi],[k,N]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-l]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[E,[x,pi],[k,N]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[E,[x,ui],[k,N]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[E,[x,c,{OnePlus:["203","304","403","404","413","415"],"*":ui}],[k,t]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[E,[x,"BLU"],[k,N]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[E,[x,"Vivo"],[k,N]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[E,[x,"Realme"],[k,N]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[E,[x,bi],[k,t]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[E,[x,bi],[k,N]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[E,[x,hi],[k,N]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[E,[x,hi],[k,t]],[/\b(?:lg)?([vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[E,[x,li],[k,t]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[E,[x,li],[k,N]],[/(nokia) (t[12][01])/i],[x,E,[k,t]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i],[[E,/_/g," "],[k,N],[x,"Nokia"]],[/(pixel (c|tablet))\b/i],[E,[x,s],[k,t]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[E,[x,s],[k,N]],[/(google) (pixelbook( go)?)/i],[x,E],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[E,[x,fi],[k,N]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[E,"Xperia Tablet"],[x,fi],[k,t]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[E,[x,ai],[k,t]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[E,/(.+)/g,"Fire Phone $1"],[x,ai],[k,N]],[/(playbook);[-\w\),; ]+(rim)/i],[E,x,[k,t]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/(?:blackberry|\(bb10;) (\w+)/i],[E,[x,ni],[k,N]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[E,[x,si],[k,t]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[E,[x,si],[k,N]],[/(nexus 9)/i],[E,[x,"HTC"],[k,t]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[x,[E,/_/g," "],[k,N]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[E,[x,"TCL"],[k,t]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[E,[x,"TCL"],[k,N]],[/(itel) ((\w+))/i],[[x,U],E,[k,c,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[E,[x,"Acer"],[k,t]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[E,[x,"Meizu"],[k,N]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[E,[x,"Ulefone"],[k,N]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[E,[x,"Energizer"],[k,N]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[E,[x,"Cat"],[k,N]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[E,[x,"Smartfren"],[k,N]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[E,[x,"Nothing"],[k,N]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[E,[x,"Archos"],[k,t]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[E,[x,"Archos"],[k,N]],[/blackview ([-\w ]+)( b|\))/i,/; (bv\d{4}[-\w ]*)( b|\))/i],[E,[x,"Blackview"],[k,N]],[/; (n159v)/i],[E,[x,"HMD"],[k,N]],[/((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i],[E,[k,function(i,e){return e.test.test(i)?e.ifTrue:e.ifFalse},{test:/ta?b/i,ifTrue:t,ifFalse:N}],[x,"T-Mobile"]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[x,E,[k,t]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i,/(hisense) ([ehv][\w ]+)\)/i,/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i],[x,E,[k,N]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[x,E,[k,t]],[/(surface duo)/i],[E,[x,ci],[k,t]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[E,[x,"Fairphone"],[k,N]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[E,[x,"Nvidia"],[k,t]],[/(sprint) (\w+)/i],[x,E,[k,N]],[/(kin\.[onetw]{3})/i],[[E,/\./g," "],[x,ci],[k,N]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[E,[x,vi],[k,t]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[E,[x,vi],[k,N]],[/(philips)[\w ]+tv/i,/smart-tv.+(samsung)/i],[x,[k,i]],[/hbbtv.+maple;(\d+)/i],[[E,/^/,"SmartTV"],[x,mi],[k,i]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[x,E,[k,i]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[x,li],[k,i]],[/(apple) ?tv/i],[x,[E,a+" TV"],[k,i]],[/crkey.*devicetype\/chromecast/i],[[E,n+" Third Generation"],[x,s],[k,i]],[/crkey.*devicetype\/([^/]*)/i],[[E,/^/,"Chromecast "],[x,s],[k,i]],[/fuchsia.*crkey/i],[[E,n+" Nest Hub"],[x,s],[k,i]],[/crkey/i],[[E,n],[x,s],[k,i]],[/(portaltv)/i],[E,[x,Ci],[k,i]],[/droid.+aft(\w+)( bui|\))/i],[E,[x,ai],[k,i]],[/(shield \w+ tv)/i],[E,[x,"Nvidia"],[k,i]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[E,[x,"Sharp"],[k,i]],[/(bravia[\w ]+)( bui|\))/i],[E,[x,fi],[k,i]],[/(mi(tv|box)-?\w+) bui/i],[E,[x,gi],[k,i]],[/Hbbtv.*(technisat) (.*);/i],[x,E,[k,i]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[x,/.+\/(\w+)/,"$1",c,{LG:"lge"}],[E,_i],[k,i]],[/(playstation \w+)/i],[E,[x,fi],[k,R]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[E,[x,ci],[k,R]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i,/(valve).+(steam deck)/i,/droid.+; ((shield|rgcube|gr0006))( bui|\))/i],[[x,c,{Nvidia:"Shield",Anbernic:"RGCUBE",Logitech:"GR0006"}],E,[k,R]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[E,[x,mi],[k,e]],[/((pebble))app/i,/(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[x,E,[k,e]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[E,[x,ui],[k,e]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[E,[x,a],[k,e]],[/(opwwe\d{3})/i],[E,[x,pi],[k,e]],[/(moto 360)/i],[E,[x,hi],[k,e]],[/(smartwatch 3)/i],[E,[x,fi],[k,e]],[/(g watch r)/i],[E,[x,li],[k,e]],[/droid.+; (wt63?0{2,3})\)/i],[E,[x,vi],[k,e]],[/droid.+; (glass) \d/i],[E,[x,s],[k,G]],[/(pico) ([\w ]+) os\d/i],[x,E,[k,G]],[/(quest( \d| pro)?s?).+vr/i],[E,[x,Ci],[k,G]],[/mobile vr; rv.+firefox/i],[[k,G]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[x,[k,L]],[/(aeobc)\b/i],[E,[x,ai],[k,L]],[/(homepod).+mac os/i],[E,[x,a],[k,L]],[/windows iot/i],[[k,L]],[/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i],[E,[k,i]],[/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i],[[k,i]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i],[E,[k,c,{mobile:"Mobile",xr:"VR","*":t}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[k,t]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[k,N]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[E,[x,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[y,[v,xi+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[v,y],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[y,[v,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links|dillo)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[v,y],[/ladybird\//i],[[v,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[y,v]],os:[[/(windows nt) (6\.[23]); arm/i],[[v,/N/,"R"],[y,c,qi]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[v,y],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[y,/(;|\))/g,"",c,qi],[v,Ei]],[/(windows ce)\/?([\d\.]*)/i],[v,y],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,/\btvos ?([\w\.]+)/i,/cfnetwork\/.+darwin/i],[[y,/_/g,"."],[v,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[v,"macOS"],[y,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[y,[v,n+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[y,[v,n+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[y,[v,n+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[y,[v,n+" Linux"]],[/crkey\/([\d\.]+)/i],[y,[v,n]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[y,v],[/(ubuntu) ([\w\.]+) like android/i],[[v,/(.+)/,"$1 Touch"],y],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[v,y],[/\(bb(10);/i],[y,[v,ni]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[y,[v,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile[;\w ]*|tablet|tv|[^\)]*(?:viera|lg(?:l25|-d300)|alcatel ?o.+|y300-f1)); rv:([\w\.]+)\).+gecko\//i],[y,[v,yi+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[y,[v,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[y,c,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[v,"webOS"]],[/watch(?: ?os[,\/ ]|\d,\d\/)([\d\.]+)/i],[y,[v,"watchOS"]],[/cros [\w]+(?:\)| ([\w\.]+)\b)/i],[y,[v,"Chrome OS"]],[/kepler ([\w\.]+); (aft|aeo)/i],[y,[v,"Vega OS"]],[/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[v,y],[/(sunos) ?([\d\.]*)/i],[[v,"Solaris"],y],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[v,y]]},Bi=(w={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}},z.call(w.init,[[h,[v,y,j,k]],[p,[C]],[u,[k,E,x]],[m,[v,y]],[f,[v,y]]]),z.call(w.isIgnore,[[h,[y,j]],[m,[y]],[f,[y]]]),z.call(w.isIgnoreRgx,[[h,/ ?browser$/i],[f,/ ?os$/i]]),z.call(w.toString,[[h,[v,y]],[p,[C]],[u,[x,E]],[m,[v,y]],[f,[v,y]]]),w);function Di(i,e){if(i=i||{},z.call(this,ri),e)z.call(this,[[$,Ti(i[r])],[W,Ti(i[Y])],[N,/\?1/.test(i[ii])],[E,Oi(i[ei])],[T,Oi(i[ti])],[J,Oi(i[oi])],[C,Oi(i[Z])],[S,Ti(i[Q])],[X,Oi(i[K])]]);else for(var t in i)this.hasOwnProperty(t)&&typeof i[t]!==l.UNDEFINED&&(this[t]=i[t])}function F(i,e,t,o){return z.call(this,[["itemType",i],["ua",e],["uaCH",o],["rgxMap",t],["data",A(this,i)]]),this}function B(i,e,t){if(typeof i===l.OBJECT?(e=Si(i,!0)?(typeof e===l.OBJECT&&(t=e),i):void(t=i),i=void 0):typeof i!==l.STRING||Si(e,!0)||(t=e,e=void 0),t)if(typeof t.append===l.FUNCTION){var o={};t.forEach(function(i,e){o[String(e).toLowerCase()]=i}),t=o}else{var r,a={};for(r in t)t.hasOwnProperty(r)&&(a[String(r).toLowerCase()]=t[r]);t=a}var s,n,w,b;return this instanceof B?(s=typeof i===l.STRING?i:t&&t[P]?t[P]:I&&I.userAgent?I.userAgent:d,n=new Di(t,!0),w=Fi,z.call(this,[["getBrowser",(b=function(i){return i==g?function(){return new F(i,s,w,n).set("ua",s).set(h,this.getBrowser()).set(p,this.getCPU()).set(u,this.getDevice()).set(m,this.getEngine()).set(f,this.getOS()).get()}:function(){return new F(i,s,w[i],n).parseUA().get()}})(h)],["getCPU",b(p)],["getDevice",b(u)],["getEngine",b(m)],["getOS",b(f)],["getResult",b(g)],["getUA",function(){return s}],["setUA",function(i){return q(i)&&(s=_i(i,V)),this}],["useExtension",function(i){return i&&(w=((i,e)=>{var t,o={},r=e;if(!Si(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(w,i)),this}]]).setUA(s).useExtension(e),this):new B(i,e,t).getResult()}F.prototype.get=function(i){return i?this.data.hasOwnProperty(i)?this.data[i]:void 0:this.data},F.prototype.set=function(i,e){return this.data[i]=e,this},F.prototype.setCH=function(i){return this.uaCH=i,this},F.prototype.detectFeature=function(){if(I&&I.userAgent==this.ua)switch(this.itemType){case h:I.brave&&typeof I.brave.isBrave==l.FUNCTION&&this.set(v,"Brave");break;case u:!this.get(k)&&_&&_[N]&&this.set(k,N),"Macintosh"==this.get(E)&&I&&typeof I.standalone!==l.UNDEFINED&&I.maxTouchPoints&&2<I.maxTouchPoints&&this.set(E,"iPad").set(k,t);break;case f:!this.get(v)&&_&&_[T]&&this.set(v,_[T]);break;case g:var e=this.data,i=function(i){return e[i].getItem().detectFeature().get()};this.set(h,i(h)).set(p,i(p)).set(u,i(u)).set(m,i(m)).set(f,i(f))}return this},F.prototype.parseUA=function(){switch(this.itemType!=g&&M.call(this.data,this.ua,this.rgxMap),this.itemType){case h:this.set(j,H(this.get(y)));break;case f:var i;"iOS"==this.get(v)&&this.get(y)&&/^1[89][^\d]/.exec(this.get(y))&&(i=/\) Version\/((\d+)[\d\.]*)/.exec(this.ua))&&26<=parseInt(i[2],10)&&this.set(y,i[1])}return this},F.prototype.parseCH=function(){var i,e=this.uaCH,t=this.rgxMap;switch(this.itemType){case h:case m:var o,r=e[W]||e[$];if(r)for(var a=0;a<r.length;a++){var s=r[a].brand||r[a],n=r[a].version;this.itemType==h&&!/not.a.brand/i.test(s)&&(!o||/Chrom/.test(o)&&s!=ki||o==xi&&/WebView2/.test(s))&&(s=c(s,zi),(o=this.get(v))&&!/Chrom/.test(o)&&/Chrom/.test(s)||this.set(v,s).set(y,n).set(j,H(n)),o=s),this.itemType==m&&s==ki&&this.set(y,n)}break;case p:var w=e[C];w&&("64"==e[X]&&(w+="64"),M.call(this.data,w+";",t));break;case u:if(e[N]&&this.set(k,N),e[E]&&(this.set(E,e[E]),this.get(k)&&this.get(x)||(M.call(w={},"droid 9; "+e[E]+")",t),!this.get(k)&&w.type&&this.set(k,w.type),!this.get(x)&&w.vendor&&this.set(x,w.vendor))),e[S]){if("string"!=typeof e[S])for(var b=0;!i&&b<e[S].length;)i=c(e[S][b++],Ui);else i=c(e[S],Ui);this.set(k,i)}break;case f:var d,w=e[T];w&&(d=e[J],w==Ei&&(d=13<=parseInt(H(d),10)?"11":"10"),this.set(v,w).set(y,d)),this.get(v)==Ei&&"Xbox"==e[E]&&this.set(v,"Xbox").set(y,void 0);break;case g:var l=this.data,w=function(i){return l[i].getItem().setCH(e).parseCH().get()};this.set(h,w(h)).set(p,w(p)).set(u,w(u)).set(m,w(m)).set(f,w(f))}return this},B.VERSION="2.0.10",B.BROWSER=D([v,y,j,k]),B.CPU=D([C]),B.DEVICE=D([E,x,k,R,N,i,t,e,L]),B.ENGINE=B.OS=D([v,y]);export{B as UAParser};
src/main/ua-parser.js +54 lines · 2 flagged
--- +++ @@ -1,3 +1,3 @@ /////////////////////////////////////////////////////////////////////////////////-/* UAParser.js v2.0.9+/* UAParser.js v2.0.10    Copyright © 2012-2026 Faisal Salman <[email protected]>@@ -21,3 +21,3 @@ -    var LIBVERSION  = '2.0.9',+    var LIBVERSION  = '2.0.10',         UA_MAX_LENGTH = 500,@@ -172,3 +172,3 @@             var arr = [];-            var tokens = strip(/\\?\"/g, header).split(',');+            var tokens = normalizeHeaderValue(header).split(',');             for (var i = 0; i < tokens.length; i++) {@@ -189,2 +189,5 @@         },+        normalizeHeaderValue = function (str) {+            return isString(str) ? trim(strip(/\\?\"/g, str), UA_MAX_LENGTH) : undefined;+        },         setProps = function (arr) {@@ -204,5 +207,2 @@             return isString(str) ? str.replace(pattern, EMPTY) : str;-        },-        stripQuotes = function (str) {-            return strip(/\\?\"/g, str);          },@@ -280,2 +280,6 @@ +        strTest = function (str, map) {+            return map.test.test(str) ? map.ifTrue : map.ifFalse;+        },+         strMapper = function (str, map) {@@ -350,3 +354,3 @@             /webview.+edge\/([\w\.]+)/i                                         // Microsoft Edge-            ], [VERSION, [NAME, EDGE+' WebView']], [+            ], [VERSION, [NAME, EDGE+' WebView'], [TYPE, INAPP]], [             /edg(?:e|ios|a)?\/([\w\.]+)/i                                       @@ -390,3 +394,3 @@             ], [VERSION, [NAME, 'DuckDuckGo']], [-            /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i                 // UCBrowser+            /(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i           // UCBrowser             ], [VERSION, [NAME, 'UCBrowser']], [@@ -429,3 +433,5 @@             /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i-            ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [              // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser+            ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [              // Oculus/Sailfish/VivoBrowser/PicoBrowser+            / HBPC\/([\w\.]+)/                                                  // Huawei Browser+            ], [VERSION, [NAME, HUAWEI + SUFFIX_BROWSER]], [             /samsungbrowser\/([\w\.]+)/i                                        // Samsung Internet@@ -477,6 +483,6 @@             /wv\).+chrome\/([\w\.]+).+edgw\//i                                  // Edge WebView2-            ], [VERSION, [NAME, EDGE+' WebView2']], [--            / wv\).+(chrome)\/([\w\.]+)/i                                       // Chrome WebView-            ], [[NAME, CHROME+' WebView'], VERSION], [+            ], [VERSION, [NAME, EDGE+' WebView2'], [TYPE, INAPP]], [++            /; wv\).+(chrome)\/([\w\.]+)/i                                      // Chrome WebView+            ], [[NAME, CHROME+' WebView'], VERSION, [TYPE, INAPP]], [ @@ -614,3 +620,3 @@             /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,-            / ([\w ]+) miui\/v?\d/i+            /; ([\w ]+) miui\/v?\d/i             ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [@@ -769,2 +775,7 @@ +            // Blackview+            /blackview ([-\w ]+)( b|\))/i,+            /; (bv\d{4}[-\w ]*)( b|\))/i+            ], [MODEL, [VENDOR, 'Blackview'], [TYPE, MOBILE]], [+             // HMD@@ -772,2 +783,6 @@             ], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [++            // T-Mobile+            /((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i+            ], [MODEL, [TYPE, strTest, { 'test': /ta?b/i, 'ifTrue': TABLET, 'ifFalse': MOBILE }], [VENDOR, 'T-Mobile']], [ @@ -780,4 +795,4 @@                                                                                 // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan-                                                                                // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko-            /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,+                                                                                // BLU/Coolpad/CUBOT/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko+            /; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,             /(hp) ([\w ]+\w)/i,                                                 // HP iPAQ@@ -1189,8 +1204,8 @@                 [MOBILE, /\?1/.test(uach[CH_MOBILE])],-                [MODEL, stripQuotes(uach[CH_MODEL])],-                [PLATFORM, stripQuotes(uach[CH_PLATFORM])],-                [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],-                [ARCHITECTURE, stripQuotes(uach[CH_ARCH])],+                [MODEL, normalizeHeaderValue(uach[CH_MODEL])],+                [PLATFORM, normalizeHeaderValue(uach[CH_PLATFORM])],+                [PLATFORMVER, normalizeHeaderValue(uach[CH_PLATFORM_VER])],+                [ARCHITECTURE, normalizeHeaderValue(uach[CH_ARCH])],                 [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],-                [BITNESS, stripQuotes(uach[CH_BITNESS])]+                [BITNESS, normalizeHeaderValue(uach[CH_BITNESS])]             ]);@@ -1282,7 +1297,13 @@             case OS:-                if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') {-                    // Based on the assumption that iOS version is tightly coupled with Safari version-                    var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version-                    if (realVersion && parseInt(realVersion[1].substring(0,2), 10) >= 26) {-                        this.set(VERSION, realVersion[1]);  // Set as iOS version+                // Since iOS 26, Safari's UA reports the OS version as frozen at 18:+                // https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#update-to-ua-string+                if (this.get(NAME) == 'iOS' && this.get(VERSION)) {+                    // Only perform this if iOS version is 18/19+                    if (/^1[89][^\d]/.exec(this.get(VERSION))) {+                        // Based on the assumption that "iOS" version is tightly coupled with "Safari" version+                        var realVersion = /\) Version\/((\d+)[\d\.]*)/.exec(this.ua);+                        if (realVersion && parseInt(realVersion[2], 10) >= 26) {+                            // iOS version = Safari version+                            this.set(VERSION, realVersion[1]);+                        }                     }@@ -1442,5 +1463,3 @@             httpUACH = new UACHData(headers, true),-            regexMap = extensions ? -                        extend(defaultRegexes, extensions) : -                        defaultRegexes,+            regexMap = defaultRegexes, @@ -1479,5 +1498,10 @@                 return this;+            }],+            ['useExtension', function (exts) {+                if (exts) regexMap = extend(regexMap, exts);+                return this;             }]         ])-        .setUA(userAgent);+        .setUA(userAgent)+        .useExtension(extensions); 
src/main/ua-parser.mjs +54 lines · 2 flagged
--- +++ @@ -5,3 +5,3 @@ /////////////////////////////////////////////////////////////////////////////////-/* UAParser.js v2.0.9+/* UAParser.js v2.0.10    Copyright © 2012-2026 Faisal Salman <[email protected]>@@ -23,3 +23,3 @@ -    var LIBVERSION  = '2.0.9',+    var LIBVERSION  = '2.0.10',         UA_MAX_LENGTH = 500,@@ -174,3 +174,3 @@             var arr = [];-            var tokens = strip(/\\?\"/g, header).split(',');+            var tokens = normalizeHeaderValue(header).split(',');             for (var i = 0; i < tokens.length; i++) {@@ -191,2 +191,5 @@         },+        normalizeHeaderValue = function (str) {+            return isString(str) ? trim(strip(/\\?\"/g, str), UA_MAX_LENGTH) : undefined;+        },         setProps = function (arr) {@@ -206,5 +209,2 @@             return isString(str) ? str.replace(pattern, EMPTY) : str;-        },-        stripQuotes = function (str) {-            return strip(/\\?\"/g, str);          },@@ -282,2 +282,6 @@ +        strTest = function (str, map) {+            return map.test.test(str) ? map.ifTrue : map.ifFalse;+        },+         strMapper = function (str, map) {@@ -352,3 +356,3 @@             /webview.+edge\/([\w\.]+)/i                                         // Microsoft Edge-            ], [VERSION, [NAME, EDGE+' WebView']], [+            ], [VERSION, [NAME, EDGE+' WebView'], [TYPE, INAPP]], [             /edg(?:e|ios|a)?\/([\w\.]+)/i                                       @@ -392,3 +396,3 @@             ], [VERSION, [NAME, 'DuckDuckGo']], [-            /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i                 // UCBrowser+            /(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i           // UCBrowser             ], [VERSION, [NAME, 'UCBrowser']], [@@ -431,3 +435,5 @@             /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i-            ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [              // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser+            ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [              // Oculus/Sailfish/VivoBrowser/PicoBrowser+            / HBPC\/([\w\.]+)/                                                  // Huawei Browser+            ], [VERSION, [NAME, HUAWEI + SUFFIX_BROWSER]], [             /samsungbrowser\/([\w\.]+)/i                                        // Samsung Internet@@ -479,6 +485,6 @@             /wv\).+chrome\/([\w\.]+).+edgw\//i                                  // Edge WebView2-            ], [VERSION, [NAME, EDGE+' WebView2']], [--            / wv\).+(chrome)\/([\w\.]+)/i                                       // Chrome WebView-            ], [[NAME, CHROME+' WebView'], VERSION], [+            ], [VERSION, [NAME, EDGE+' WebView2'], [TYPE, INAPP]], [++            /; wv\).+(chrome)\/([\w\.]+)/i                                      // Chrome WebView+            ], [[NAME, CHROME+' WebView'], VERSION, [TYPE, INAPP]], [ @@ -616,3 +622,3 @@             /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,-            / ([\w ]+) miui\/v?\d/i+            /; ([\w ]+) miui\/v?\d/i             ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [@@ -771,2 +777,7 @@ +            // Blackview+            /blackview ([-\w ]+)( b|\))/i,+            /; (bv\d{4}[-\w ]*)( b|\))/i+            ], [MODEL, [VENDOR, 'Blackview'], [TYPE, MOBILE]], [+             // HMD@@ -774,2 +785,6 @@             ], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [++            // T-Mobile+            /((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i+            ], [MODEL, [TYPE, strTest, { 'test': /ta?b/i, 'ifTrue': TABLET, 'ifFalse': MOBILE }], [VENDOR, 'T-Mobile']], [ @@ -782,4 +797,4 @@                                                                                 // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan-                                                                                // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko-            /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,+                                                                                // BLU/Coolpad/CUBOT/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko+            /; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,             /(hp) ([\w ]+\w)/i,                                                 // HP iPAQ@@ -1191,8 +1206,8 @@                 [MOBILE, /\?1/.test(uach[CH_MOBILE])],-                [MODEL, stripQuotes(uach[CH_MODEL])],-                [PLATFORM, stripQuotes(uach[CH_PLATFORM])],-                [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],-                [ARCHITECTURE, stripQuotes(uach[CH_ARCH])],+                [MODEL, normalizeHeaderValue(uach[CH_MODEL])],+                [PLATFORM, normalizeHeaderValue(uach[CH_PLATFORM])],+                [PLATFORMVER, normalizeHeaderValue(uach[CH_PLATFORM_VER])],+                [ARCHITECTURE, normalizeHeaderValue(uach[CH_ARCH])],                 [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],-                [BITNESS, stripQuotes(uach[CH_BITNESS])]+                [BITNESS, normalizeHeaderValue(uach[CH_BITNESS])]             ]);@@ -1284,7 +1299,13 @@             case OS:-                if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') {-                    // Based on the assumption that iOS version is tightly coupled with Safari version-                    var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version-                    if (realVersion && parseInt(realVersion[1].substring(0,2), 10) >= 26) {-                        this.set(VERSION, realVersion[1]);  // Set as iOS version+                // Since iOS 26, Safari's UA reports the OS version as frozen at 18:+                // https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#update-to-ua-string+                if (this.get(NAME) == 'iOS' && this.get(VERSION)) {+                    // Only perform this if iOS version is 18/19+                    if (/^1[89][^\d]/.exec(this.get(VERSION))) {+                        // Based on the assumption that "iOS" version is tightly coupled with "Safari" version+                        var realVersion = /\) Version\/((\d+)[\d\.]*)/.exec(this.ua);+                        if (realVersion && parseInt(realVersion[2], 10) >= 26) {+                            // iOS version = Safari version+                            this.set(VERSION, realVersion[1]);+                        }                     }@@ -1444,5 +1465,3 @@             httpUACH = new UACHData(headers, true),-            regexMap = extensions ? -                        extend(defaultRegexes, extensions) : -                        defaultRegexes,+            regexMap = defaultRegexes, @@ -1481,5 +1500,10 @@                 return this;+            }],+            ['useExtension', function (exts) {+                if (exts) regexMap = extend(regexMap, exts);+                return this;             }]         ])-        .setUA(userAgent);+        .setUA(userAgent)+        .useExtension(extensions); 
package.json +19 lines
--- +++ @@ -3,3 +3,3 @@   "name": "ua-parser-js",-  "version": "2.0.9",+  "version": "2.0.10",   "author": "Faisal Salman <[email protected]> (http://faisalman.com)",@@ -25,4 +25,6 @@   "contributors": [+    "23tux <[email protected]>",     "Aamir Poonawalla <[email protected]>",     "Admas <[email protected]>",+    "Aidan Nulman <[email protected]>",     "Aiyush <[email protected]>",@@ -41,4 +43,7 @@     "Benjamin Urban <[email protected]>",+    "Benxamin <[email protected]>",     "boneyao <[email protected]>",+    "carel155 <[email protected]>",     "Carl C Von Lewin <[email protected]>",+    "Casey Grimes <[email protected]>",     "CESAR RAMOS <[email protected]>",@@ -77,2 +82,3 @@     "Germán M. Bravo <[email protected]>",+    "giantyo26 <[email protected]>",     "Grigory Dmitrenko <[email protected]>",@@ -81,2 +87,3 @@     "Harald Reingruber <[email protected]>",+    "Harlan Brawer <[email protected]>",     "Hendrik Helwich <[email protected]>",@@ -85,2 +92,3 @@     "Hyewon Kang <[email protected]>",+    "Hyper-Z11 <[email protected]>",     "Hyunbin <[email protected]>",@@ -114,2 +122,3 @@     "Lukas Eipert <[email protected]>",+    "Maksim Otto <[email protected]>",     "Malash <[email protected]>",@@ -157,2 +166,3 @@     "Sandro Sonntag <[email protected]>",+    "Sébastien Règne <[email protected]>",     "sgautrea <[email protected]>",@@ -167,2 +177,3 @@     "sUP <[email protected]>",+    "Suryaansh Chawla <[email protected]>",     "Sylvain Gizard <[email protected]>",@@ -172,3 +183,5 @@     "Ulrich Schmidt <[email protected]>",+    "undefined <[email protected]>",     "Vadim Kurachevsky <[email protected]>",+    "Valentina <[email protected]>",     "Varun Sharma <[email protected]>",@@ -229,2 +242,3 @@   "bin": "./script/cli.js",+  "sideEffects": false,   "scripts": {@@ -232,3 +246,2 @@     "build+test": "npm run build && npm run test",-    "fuzz": "jazzer ./test/fuzz/redos.js --sync",     "test": "./script/test-all.sh",@@ -236,2 +249,3 @@     "test:eslint": "eslint --no-config-lookup src",+    "test:fuzz": "jazzer ./test/fuzz/redos.js --sync",     "test:jshint": "jshint src/main",@@ -239,2 +253,3 @@     "test:mocha": "mocha --recursive test/unit",+    "test:nyc": "nyc --timeout=50000 --include=src/**/*.js npm run test",     "test:playwright": "npx playwright install && playwright test test/e2e --browser all"@@ -249,2 +264,3 @@     "@babel/traverse": "7.23.2",+    "@jazzer.js/core": "^4.0.0",     "@playwright/test": "^1.57.0",@@ -254,2 +270,3 @@     "mocha": "~8.2.0",+    "nyc": "^18.0.0",     "requirejs": "2.3.2",
src/bot-detection/bot-detection.d.ts +6 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for bot-detection submodule of UAParser.js v2.0.9+// Type definitions for bot-detection submodule of UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js@@ -4,4 +4,6 @@ -export function isAIAssistant(ua: string): boolean;-export function isAICrawler(ua: string): boolean;-export function isBot(ua: string): boolean;+import type { IResult } from "../main/ua-parser";++export function isAIAssistant(resultOrUA: IResult | string): boolean;+export function isAICrawler(resultOrUA: IResult | string): boolean;+export function isBot(resultOrUA: IResult | string): boolean;
src/bot-detection/bot-detection.js +2 lines
--- +++ @@ -1,3 +1,3 @@ //////////////////////////////////////////////////-/*  bot-detection submodule of UAParser.js v2.0.9+/*  bot-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -139,2 +139,3 @@     Crawler.META_EXTERNALAGENT,+    Crawler.META_WEBINDEXER, 
src/bot-detection/bot-detection.mjs +2 lines
--- +++ @@ -5,3 +5,3 @@ //////////////////////////////////////////////////-/*  bot-detection submodule of UAParser.js v2.0.9+/*  bot-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -143,2 +143,3 @@     Crawler.META_EXTERNALAGENT,+    Crawler.META_WEBINDEXER, 
src/browser-detection/browser-detection.d.ts +1 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for browser-detection submodule of UAParser.js v2.0.9+// Type definitions for browser-detection submodule of UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js
src/browser-detection/browser-detection.js +6 lines
--- +++ @@ -1,3 +1,3 @@ //////////////////////////////////////////////////////-/*  browser-detection submodule of UAParser.js v2.0.9+/*  browser-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -21,4 +21,7 @@ const isElectron = () => !!(-    process?.versions?.hasOwnProperty('electron') ||    // node.js-    / electron\//i.test(navigator?.userAgent));         // browser+    // in node.js environment+    (typeof process !== 'undefined' && process.versions?.hasOwnProperty('electron')) ||+    // in browser environment+    (typeof navigator !== 'undefined' && / electron\//i.test(navigator.userAgent))+); 
src/browser-detection/browser-detection.mjs +6 lines
--- +++ @@ -5,3 +5,3 @@ //////////////////////////////////////////////////////-/*  browser-detection submodule of UAParser.js v2.0.9+/*  browser-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -25,4 +25,7 @@ const isElectron = () => !!(-    process?.versions?.hasOwnProperty('electron') ||    // node.js-    / electron\//i.test(navigator?.userAgent));         // browser+    // in node.js environment+    (typeof process !== 'undefined' && process.versions?.hasOwnProperty('electron')) ||+    // in browser environment+    (typeof navigator !== 'undefined' && / electron\//i.test(navigator.userAgent))+); 
src/device-detection/device-detection.d.ts +1 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for device-detection submodule of UAParser.js v2.0.9+// Type definitions for device-detection submodule of UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js
src/device-detection/device-detection.js +1 lines
--- +++ @@ -1,3 +1,3 @@ /////////////////////////////////////////////////////-/*  device-detection submodule of UAParser.js v2.0.9+/*  device-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js
src/device-detection/device-detection.mjs +1 lines
--- +++ @@ -5,3 +5,3 @@ /////////////////////////////////////////////////////-/*  device-detection submodule of UAParser.js v2.0.9+/*  device-detection submodule of UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js
src/enums/ua-parser-enums.d.ts +29 lines
--- +++ @@ -5,3 +5,3 @@ ///////////////////////////////////////////////-/*  Enums for UAParser.js v2.0.9+/*  Enums for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -222,3 +222,2 @@     CONSOLE: 'console',-    DESKTOP: 'desktop',     EMBEDDED: 'embedded',@@ -228,3 +227,7 @@     WEARABLE: 'wearable',-    XR: 'xr'+    XR: 'xr',+    /**+     * @deprecated UAParser doesn't support `desktop` type, see https://docs.uaparser.dev/info/device/type+     */+    DESKTOP: 'desktop' }>;@@ -247,4 +250,7 @@     BLACKBERRY: 'BlackBerry',+    BLACKVIEW: 'Blackview',     BLU: 'BLU',     CAT: 'Cat',+    COOLPAD: 'Coolpad',+    CUBOT: 'CUBOT',     DELL: 'Dell',@@ -303,2 +309,3 @@     TESLA: 'Tesla',+    T_MOBILE: 'T-Mobile',     ULEFONE: 'Ulefone',@@ -475,2 +482,3 @@             AMAZON_CONTXBOT: 'contxbot',+            AMAZON_SEARCHBOT: 'Amzn-SearchBot',             ANTHROPIC_AI: 'anthropic-ai',@@ -479,4 +487,8 @@             ANTHROPIC_CLAUDE_WEB: 'Claude-Web',+            ARCHIVEORG_BOT: 'archive.org_bot',             ATLASSIAN_BOT: 'atlassian-bot',-            ARCHIVEORG_BOT: 'archive.org_bot',+            AUDISTO_CRAWLER: 'Audisto Crawler',+            AWARIO_BOT: 'AwarioBot',+            AWARIO_SMARTBOT: 'AwarioSmartBot',+            AWARIO_RSSBOT: 'AwarioRssBot',             BAIDU_ADS: 'Baidu-ADS',@@ -493,2 +505,3 @@             BRAVE_BOT: 'Bravebot',+            BRIGHTEDGE_CRAWLER: 'BrightEdge Crawler',             BYTEDANCE_BYTESPIDER: 'Bytespider',@@ -500,2 +513,3 @@             COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',+            COMSCORE_PROXIMIC: 'proximic',             COTOYOGI: 'Cotoyogi',@@ -533,2 +547,3 @@             GOOGLE_STOREBOT: 'Storebot-Google',+            HEADLINE: 'Headline',             HIVE_IMAGESIFTBOT: 'ImagesiftBot',@@ -536,2 +551,3 @@             HUAWEI_PETALBOT: 'PetalBot',+            HUBSPOT_CRAWLER: 'HubSpot Crawler',             HUGGINGFACE_BOT: 'HuggingFace-Bot',@@ -546,2 +562,3 @@             MARGINALIA: 'marginalia',+            META_EXTERNALADS: 'meta-externalads',             META_EXTERNALAGENT: 'meta-externalagent',@@ -550,2 +567,3 @@             META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',+            META_WEBINDEXER: 'meta-webindexer',             MAJESTIC_MJ12BOT: 'MJ12bot',@@ -589,2 +607,3 @@             XAI_BOT: 'xAI-Bot',+            YACY_BOT: 'yacybot',             YAHOO_JAPAN: 'Y!J-BRW',@@ -695,2 +714,3 @@             AMAZON_NOVA_ACT: 'NovaAct',+            AMAZON_USER: 'Amzn-User',             ANTHROPIC_CLAUDE_USER: 'Claude-User',@@ -704,4 +724,6 @@             DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',+            FEEDLY: 'Feedly',             FLIPBOARD_PROXY: 'FlipboardProxy',             GOOGLE_CHROME_LIGHTHOUSE: 'Lighthouse',+            GOOGLE_DOCS: 'GoogleDocs',             GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',@@ -735,2 +757,3 @@             UPTIMEROBOT: 'UptimeRobot',+            UPTIMEBOT: 'UptimeBot',             VERCEL_FAVICON_BOT: 'vercel-favicon-bot',@@ -740,2 +763,3 @@             VERCEL_TRACING: 'verceltracing',+            VIRUSTOTAL: 'virustotal',             X_TWITTERBOT: 'Twitterbot',@@ -794,2 +818,3 @@             OCAML_COHTTP: 'ocaml-cohttp',+            PHP_CRAWL: 'phpcrawl',             PHP_SOAP: 'PHP-SOAP',
src/enums/ua-parser-enums.js +29 lines
--- +++ @@ -1,3 +1,3 @@ ///////////////////////////////////////////////-/*  Enums for UAParser.js v2.0.9+/*  Enums for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -218,3 +218,2 @@     CONSOLE: 'console',-    DESKTOP: 'desktop',     EMBEDDED: 'embedded',@@ -224,3 +223,7 @@     WEARABLE: 'wearable',-    XR: 'xr'+    XR: 'xr',+    /**+     * @deprecated UAParser doesn't support `desktop` type, see https://docs.uaparser.dev/info/device/type+     */+    DESKTOP: 'desktop' });@@ -243,4 +246,7 @@     BLACKBERRY: 'BlackBerry',+    BLACKVIEW: 'Blackview',     BLU: 'BLU',     CAT: 'Cat',+    COOLPAD: 'Coolpad',+    CUBOT: 'CUBOT',     DELL: 'Dell',@@ -299,2 +305,3 @@     TESLA: 'Tesla',+    T_MOBILE: 'T-Mobile',     ULEFONE: 'Ulefone',@@ -471,2 +478,3 @@             AMAZON_CONTXBOT: 'contxbot',+            AMAZON_SEARCHBOT: 'Amzn-SearchBot',             ANTHROPIC_AI: 'anthropic-ai',@@ -475,4 +483,8 @@             ANTHROPIC_CLAUDE_WEB: 'Claude-Web',+            ARCHIVEORG_BOT: 'archive.org_bot',             ATLASSIAN_BOT: 'atlassian-bot',-            ARCHIVEORG_BOT: 'archive.org_bot',+            AUDISTO_CRAWLER: 'Audisto Crawler',+            AWARIO_BOT: 'AwarioBot',+            AWARIO_SMARTBOT: 'AwarioSmartBot',+            AWARIO_RSSBOT: 'AwarioRssBot',             BAIDU_ADS: 'Baidu-ADS',@@ -489,2 +501,3 @@             BRAVE_BOT: 'Bravebot',+            BRIGHTEDGE_CRAWLER: 'BrightEdge Crawler',             BYTEDANCE_BYTESPIDER: 'Bytespider',@@ -496,2 +509,3 @@             COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',+            COMSCORE_PROXIMIC: 'proximic',             COTOYOGI: 'Cotoyogi',@@ -529,2 +543,3 @@             GOOGLE_STOREBOT: 'Storebot-Google',+            HEADLINE: 'Headline',             HIVE_IMAGESIFTBOT: 'ImagesiftBot',@@ -532,2 +547,3 @@             HUAWEI_PETALBOT: 'PetalBot',+            HUBSPOT_CRAWLER: 'HubSpot Crawler',             HUGGINGFACE_BOT: 'HuggingFace-Bot',@@ -542,2 +558,3 @@             MARGINALIA: 'marginalia',+            META_EXTERNALADS: 'meta-externalads',             META_EXTERNALAGENT: 'meta-externalagent',@@ -546,2 +563,3 @@             META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',+            META_WEBINDEXER: 'meta-webindexer',             MAJESTIC_MJ12BOT: 'MJ12bot',@@ -585,2 +603,3 @@             XAI_BOT: 'xAI-Bot',+            YACY_BOT: 'yacybot',             YAHOO_JAPAN: 'Y!J-BRW',@@ -691,2 +710,3 @@             AMAZON_NOVA_ACT: 'NovaAct',+            AMAZON_USER: 'Amzn-User',             ANTHROPIC_CLAUDE_USER: 'Claude-User',@@ -700,4 +720,6 @@             DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',+            FEEDLY: 'Feedly',             FLIPBOARD_PROXY: 'FlipboardProxy',             GOOGLE_CHROME_LIGHTHOUSE: 'Lighthouse',+            GOOGLE_DOCS: 'GoogleDocs',             GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',@@ -731,2 +753,3 @@             UPTIMEROBOT: 'UptimeRobot',+            UPTIMEBOT: 'UptimeBot',             VERCEL_FAVICON_BOT: 'vercel-favicon-bot',@@ -736,2 +759,3 @@             VERCEL_TRACING: 'verceltracing',+            VIRUSTOTAL: 'virustotal',             X_TWITTERBOT: 'Twitterbot',@@ -790,2 +814,3 @@             OCAML_COHTTP: 'ocaml-cohttp',+            PHP_CRAWL: 'phpcrawl',             PHP_SOAP: 'PHP-SOAP',
src/enums/ua-parser-enums.mjs +29 lines
--- +++ @@ -5,3 +5,3 @@ ///////////////////////////////////////////////-/*  Enums for UAParser.js v2.0.9+/*  Enums for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -222,3 +222,2 @@     CONSOLE: 'console',-    DESKTOP: 'desktop',     EMBEDDED: 'embedded',@@ -228,3 +227,7 @@     WEARABLE: 'wearable',-    XR: 'xr'+    XR: 'xr',+    /**+     * @deprecated UAParser doesn't support `desktop` type, see https://docs.uaparser.dev/info/device/type+     */+    DESKTOP: 'desktop' });@@ -247,4 +250,7 @@     BLACKBERRY: 'BlackBerry',+    BLACKVIEW: 'Blackview',     BLU: 'BLU',     CAT: 'Cat',+    COOLPAD: 'Coolpad',+    CUBOT: 'CUBOT',     DELL: 'Dell',@@ -303,2 +309,3 @@     TESLA: 'Tesla',+    T_MOBILE: 'T-Mobile',     ULEFONE: 'Ulefone',@@ -475,2 +482,3 @@             AMAZON_CONTXBOT: 'contxbot',+            AMAZON_SEARCHBOT: 'Amzn-SearchBot',             ANTHROPIC_AI: 'anthropic-ai',@@ -479,4 +487,8 @@             ANTHROPIC_CLAUDE_WEB: 'Claude-Web',+            ARCHIVEORG_BOT: 'archive.org_bot',             ATLASSIAN_BOT: 'atlassian-bot',-            ARCHIVEORG_BOT: 'archive.org_bot',+            AUDISTO_CRAWLER: 'Audisto Crawler',+            AWARIO_BOT: 'AwarioBot',+            AWARIO_SMARTBOT: 'AwarioSmartBot',+            AWARIO_RSSBOT: 'AwarioRssBot',             BAIDU_ADS: 'Baidu-ADS',@@ -493,2 +505,3 @@             BRAVE_BOT: 'Bravebot',+            BRIGHTEDGE_CRAWLER: 'BrightEdge Crawler',             BYTEDANCE_BYTESPIDER: 'Bytespider',@@ -500,2 +513,3 @@             COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',+            COMSCORE_PROXIMIC: 'proximic',             COTOYOGI: 'Cotoyogi',@@ -533,2 +547,3 @@             GOOGLE_STOREBOT: 'Storebot-Google',+            HEADLINE: 'Headline',             HIVE_IMAGESIFTBOT: 'ImagesiftBot',@@ -536,2 +551,3 @@             HUAWEI_PETALBOT: 'PetalBot',+            HUBSPOT_CRAWLER: 'HubSpot Crawler',             HUGGINGFACE_BOT: 'HuggingFace-Bot',@@ -546,2 +562,3 @@             MARGINALIA: 'marginalia',+            META_EXTERNALADS: 'meta-externalads',             META_EXTERNALAGENT: 'meta-externalagent',@@ -550,2 +567,3 @@             META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',+            META_WEBINDEXER: 'meta-webindexer',             MAJESTIC_MJ12BOT: 'MJ12bot',@@ -589,2 +607,3 @@             XAI_BOT: 'xAI-Bot',+            YACY_BOT: 'yacybot',             YAHOO_JAPAN: 'Y!J-BRW',@@ -695,2 +714,3 @@             AMAZON_NOVA_ACT: 'NovaAct',+            AMAZON_USER: 'Amzn-User',             ANTHROPIC_CLAUDE_USER: 'Claude-User',@@ -704,4 +724,6 @@             DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',+            FEEDLY: 'Feedly',             FLIPBOARD_PROXY: 'FlipboardProxy',             GOOGLE_CHROME_LIGHTHOUSE: 'Lighthouse',+            GOOGLE_DOCS: 'GoogleDocs',             GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',@@ -735,2 +757,3 @@             UPTIMEROBOT: 'UptimeRobot',+            UPTIMEBOT: 'UptimeBot',             VERCEL_FAVICON_BOT: 'vercel-favicon-bot',@@ -740,2 +763,3 @@             VERCEL_TRACING: 'verceltracing',+            VIRUSTOTAL: 'virustotal',             X_TWITTERBOT: 'Twitterbot',@@ -794,2 +818,3 @@             OCAML_COHTTP: 'ocaml-cohttp',+            PHP_CRAWL: 'phpcrawl',             PHP_SOAP: 'PHP-SOAP',
src/extensions/ua-parser-extensions.d.ts +1 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for Helpers submodule of UAParser.js v2.0.9+// Type definitions for Helpers submodule of UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js
src/extensions/ua-parser-extensions.js +22 lines
--- +++ @@ -1,3 +1,3 @@ ///////////////////////////////////////////////-/*  Extensions for UAParser.js v2.0.9+/*  Extensions for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -57,2 +57,3 @@             // Amazonbot - https://developer.amazon.com/amazonbot+            // Awario - https://awario.com/bots.html             // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0@@ -81,3 +82,3 @@             // YepBot - https://yep.com/yepbot/-            /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,+            /((?:adidx|ahrefs|amazon|(?:amzn|oai)-search|awario(?:smart|rss)?|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i, @@ -98,4 +99,4 @@ -            // Daum-            /(daum(?:oa)?(?:-image)?)[ \/]([\w\.]+)/i,+            // Daum / HubSpot Crawler+            /(daum(?:oa)?(?:-image)?|hubspot crawler)[ \/]([\w\.]+)/i, @@ -103,3 +104,3 @@             // https://developers.facebook.com/docs/sharing/webmasters/web-crawlers-            /(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,+            /(facebook(?:externalhit|catalog)|meta-(?:externalagent|externalads|webindexer))\/([\w\.]+)/i, @@ -132,8 +133,14 @@ -            // aiHitBot / Algolia Crawler / BLEXBot / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot+            // aiHitBot / Algolia Crawler / Audisto Crawler / BLEXBot / BrightEdge Crawler / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot             // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/             // Freespoke - https://docs.freespoke.com/search/bot/-            /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i+            /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:audisto |brightedge |magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i         ],         [NAME, VERSION, [TYPE, CRAWLER]],++        [+            // Headline - https://headline.com/legal/crawler+            /(ev-crawler)\/([\w\.]+)/i+        ],+        [[NAME, 'Headline'], VERSION, [TYPE, CRAWLER]], @@ -158,3 +165,3 @@             // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider-            /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i+            /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0|yacy)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|proximic|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i         ], @@ -308,2 +315,3 @@             // DuckAssistBot - https://duckduckgo.com/duckassistbot/+            // Feedly - https://feedly.com/fetcher.html             // FlipboardProxy - https://about.flipboard.com/proxy-service/@@ -314,3 +322,3 @@             // Yandex Bots - https://yandex.com/bots-            /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,+            /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:amzn|chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptime(?:ro)?|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i, @@ -318,2 +326,5 @@             /(bluesky) cardyb\/([\w\.]+)/i,++            // Feedly+            /(feedly)(?:bot)?\/([\w\.]+)/i, @@ -332,3 +343,3 @@             // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots-            /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i+            /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:docs|imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|virustotal(?=cloud)|yandex(?:sitelinks|userproxy))/i         ], @@ -442,3 +453,3 @@         ], [NAME, VERSION, [TYPE, LIBRARY]], [-            /(node-fetch|undici)/i+            /(node-fetch|phpcrawl|undici)/i         ], [NAME, [TYPE, LIBRARY]]
src/extensions/ua-parser-extensions.mjs +22 lines
--- +++ @@ -5,3 +5,3 @@ ///////////////////////////////////////////////-/*  Extensions for UAParser.js v2.0.9+/*  Extensions for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -61,2 +61,3 @@             // Amazonbot - https://developer.amazon.com/amazonbot+            // Awario - https://awario.com/bots.html             // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0@@ -85,3 +86,3 @@             // YepBot - https://yep.com/yepbot/-            /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,+            /((?:adidx|ahrefs|amazon|(?:amzn|oai)-search|awario(?:smart|rss)?|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i, @@ -102,4 +103,4 @@ -            // Daum-            /(daum(?:oa)?(?:-image)?)[ \/]([\w\.]+)/i,+            // Daum / HubSpot Crawler+            /(daum(?:oa)?(?:-image)?|hubspot crawler)[ \/]([\w\.]+)/i, @@ -107,3 +108,3 @@             // https://developers.facebook.com/docs/sharing/webmasters/web-crawlers-            /(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,+            /(facebook(?:externalhit|catalog)|meta-(?:externalagent|externalads|webindexer))\/([\w\.]+)/i, @@ -136,8 +137,14 @@ -            // aiHitBot / Algolia Crawler / BLEXBot / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot+            // aiHitBot / Algolia Crawler / Audisto Crawler / BLEXBot / BrightEdge Crawler / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot             // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/             // Freespoke - https://docs.freespoke.com/search/bot/-            /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i+            /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:audisto |brightedge |magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i         ],         [NAME, VERSION, [TYPE, CRAWLER]],++        [+            // Headline - https://headline.com/legal/crawler+            /(ev-crawler)\/([\w\.]+)/i+        ],+        [[NAME, 'Headline'], VERSION, [TYPE, CRAWLER]], @@ -162,3 +169,3 @@             // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider-            /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i+            /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0|yacy)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|proximic|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i         ], @@ -312,2 +319,3 @@             // DuckAssistBot - https://duckduckgo.com/duckassistbot/+            // Feedly - https://feedly.com/fetcher.html             // FlipboardProxy - https://about.flipboard.com/proxy-service/@@ -318,3 +326,3 @@             // Yandex Bots - https://yandex.com/bots-            /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,+            /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:amzn|chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptime(?:ro)?|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i, @@ -322,2 +330,5 @@             /(bluesky) cardyb\/([\w\.]+)/i,++            // Feedly+            /(feedly)(?:bot)?\/([\w\.]+)/i, @@ -336,3 +347,3 @@             // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots-            /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i+            /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:docs|imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|virustotal(?=cloud)|yandex(?:sitelinks|userproxy))/i         ], @@ -446,3 +457,3 @@         ], [NAME, VERSION, [TYPE, LIBRARY]], [-            /(node-fetch|undici)/i+            /(node-fetch|phpcrawl|undici)/i         ], [NAME, [TYPE, LIBRARY]]
src/helpers/ua-parser-helpers.d.ts +1 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for Helpers submodule of UAParser.js v2.0.9+// Type definitions for Helpers submodule of UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js
src/helpers/ua-parser-helpers.js +2 lines
--- +++ @@ -1,3 +1,3 @@ ///////////////////////////////////////////////-/*  Helpers for UAParser.js v2.0.9+/*  Helpers for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -43,3 +43,3 @@  */-const isElectron = () => _isElectron;+const isElectron = _isElectron; 
src/helpers/ua-parser-helpers.mjs +2 lines
--- +++ @@ -5,3 +5,3 @@ ///////////////////////////////////////////////-/*  Helpers for UAParser.js v2.0.9+/*  Helpers for UAParser.js v2.0.10     https://github.com/faisalman/ua-parser-js@@ -47,3 +47,3 @@  */-const isElectron = () => _isElectron;+const isElectron = _isElectron; 
src/main/ua-parser.d.ts +11 lines
--- +++ @@ -1,2 +1,2 @@-// Type definitions for UAParser.js v2.0.9+// Type definitions for UAParser.js v2.0.10 // Project: https://github.com/faisalman/ua-parser-js@@ -7,2 +7,7 @@ declare namespace UAParser {++    type BrowserTypes = typeof BrowserType[keyof typeof BrowserType];+    type CPUArchs = typeof CPUArch[keyof typeof CPUArch];+    type DeviceTypes = typeof DeviceType[keyof typeof DeviceType];+    type EngineNames = typeof EngineName[keyof typeof EngineName];     @@ -19,3 +24,3 @@         major?: string;-        type?: typeof BrowserType[keyof typeof BrowserType];+        type?: BrowserTypes;     }@@ -23,3 +28,3 @@     interface ICPU extends IData<ICPU> {-        architecture?: typeof CPUArch[keyof typeof CPUArch];+        architecture?: CPUArchs;     }@@ -27,3 +32,3 @@     interface IDevice extends IData<IDevice> {-        type?: typeof DeviceType[keyof typeof DeviceType];+        type?: DeviceTypes;         vendor?: string;@@ -33,3 +38,3 @@     interface IEngine extends IData<IEngine> {-        name?: typeof EngineName[keyof typeof EngineName];+        name?: EngineNames;         version?: string;@@ -107,2 +112,3 @@         setUA(uastring: string): UAParser;+        useExtension(extensions: UAParserExt): UAParser;     }
webpack npm
5.109.2 24d ago incident on record
critical-tier DELETIONBURST ×33
latest 5.109.2 versions 883 maintainers 8 critical-tier (snapshotted)
5.106.2
5.107.0
5.107.1
5.107.2
5.108.0
5.108.1
5.108.2
5.108.3
5.108.4
5.109.0
5.109.1
5.109.2
DELETION
1.0.2 published then removed
high · registry-verified · 2014-02-27 · 12y ago
BURST
5 releases in 45m: 0.1.0, 0.1.1, 0.1.2, 0.1.3, 0.1.4
info · registry-verified · 2012-03-11 · 14y ago
BURST
2 releases in 16m: 0.2.1, 0.2.2
info · registry-verified · 2012-03-14 · 14y ago
BURST
2 releases in 9m: 0.2.6, 0.2.7
info · registry-verified · 2012-03-19 · 14y ago
BURST
2 releases in 3m: 0.3.3, 0.3.4
info · registry-verified · 2012-04-07 · 14y ago
BURST
2 releases in 10m: 0.3.6, 0.3.7
info · registry-verified · 2012-05-01 · 14y ago
BURST
2 releases in 9m: 0.3.10, 0.3.11
info · registry-verified · 2012-05-02 · 14y ago
BURST
2 releases in 46m: 0.3.16, 0.3.17
info · registry-verified · 2012-05-12 · 14y ago
BURST
3 releases in 19m: 0.3.18, 0.3.19, 0.3.20
info · registry-verified · 2012-05-13 · 14y ago
BURST
2 releases in 7m: 0.4.5, 0.4.6
info · registry-verified · 2012-05-20 · 14y ago
BURST
2 releases in 8m: 0.4.17, 0.4.18
info · registry-verified · 2012-07-11 · 14y ago
BURST
2 releases in 13m: 0.5.0, 0.5.1
info · registry-verified · 2012-08-06 · 14y ago
BURST
2 releases in 45m: 0.5.2, 0.5.3
info · registry-verified · 2012-08-07 · 14y ago
BURST
4 releases in 50m: 0.5.4, 0.5.5, 0.5.6, 0.5.7
info · registry-verified · 2012-08-07 · 14y ago
BURST
2 releases in 56m: 0.7.0, 0.7.1
info · registry-verified · 2012-10-08 · 13y ago
BURST
2 releases in 4m: 0.7.4, 0.7.5
info · registry-verified · 2012-10-21 · 13y ago
BURST
2 releases in 53m: 0.7.6, 0.7.7
info · registry-verified · 2012-10-25 · 13y ago
BURST
4 releases in 23m: 0.7.13, 0.7.14, 0.7.15, 0.7.16
info · registry-verified · 2012-11-05 · 13y ago
BURST
2 releases in 17m: 0.11.1, 0.11.2
info · registry-verified · 2013-11-03 · 12y ago
BURST
2 releases in 26m: 0.11.4, 0.11.5
info · registry-verified · 2013-11-06 · 12y ago
BURST
2 releases in 17m: 0.11.17, 0.11.18
info · registry-verified · 2013-12-31 · 12y ago
BURST
2 releases in 9m: 1.0.2, 1.0.3
info · registry-verified · 2014-02-27 · 12y ago
BURST
2 releases in 23m: 1.3.4, 1.3.5
info · registry-verified · 2014-08-25 · 12y ago
BURST
2 releases in 3m: 1.5.2, 1.5.3
info · registry-verified · 2015-01-21 · 11y ago
BURST
2 releases in 44m: 1.9.1, 1.9.2
info · registry-verified · 2015-05-10 · 11y ago
BURST
2 releases in 59m: 1.10.4, 1.10.5
info · registry-verified · 2015-07-23 · 11y ago
BURST
2 releases in 60m: 1.12.7, 1.12.8
info · registry-verified · 2015-11-20 · 10y ago
BURST
2 releases in 31m: 4.4.0, 4.4.1
info · registry-verified · 2018-03-29 · 8y ago
BURST
2 releases in 11m: 4.35.1, 4.35.2
info · registry-verified · 2019-07-01 · 7y ago
BURST
2 releases in 9m: 4.40.3, 4.41.0
info · registry-verified · 2019-09-24 · 6y ago
BURST
2 releases in 54m: 5.2.1, 5.3.0
info · registry-verified · 2020-10-27 · 5y ago
BURST
2 releases in 5m: 4.45.0, 5.12.0
info · registry-verified · 2021-01-08 · 5y ago
BURST
2 releases in 43m: 5.31.1, 5.31.2
info · registry-verified · 2021-04-09 · 5y ago
BURST
2 releases in 40m: 5.33.0, 5.33.1
info · registry-verified · 2021-04-14 · 5y ago
release diff 5.109.1 → 5.109.2
+0 added · -0 removed · ~28 modified
+2 more files not shown
lib/CleanPlugin.js +12 lines
--- +++ @@ -24,6 +24,13 @@ -/**- * Defines the clean plugin compilation hooks type used by this module.- * @typedef {object} CleanPluginCompilationHooks- * @property {SyncBailHook<[string], boolean | void>} keep when returning true the file/directory will be kept during cleaning, returning false will clean it and ignore the following plugins and config+const createCompilationHooks = () => ({+	/**+	 * When returning true the file/directory will be kept during cleaning, returning false will clean it and ignore the following plugins and config.+	 * @type {SyncBailHook<[string], boolean | void>}+	 * @since 5.20.0+	 */+	keep: new SyncBailHook(["ignore"])+});++/**+ * @typedef {ReturnType<typeof createCompilationHooks>} CleanPluginCompilationHooks  */@@ -486,8 +493,3 @@ -CleanPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CleanPluginCompilationHooks} */ ({-			keep: new SyncBailHook(["ignore"])-		})-);+CleanPlugin.getCompilationHooks = createHooksRegistry(createCompilationHooks); 
lib/Compilation.js +12 lines
--- +++ @@ -886,5 +886,11 @@ -			/** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */+			/**+			 * @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>}+			 * @since 5.32.0+			 */ 			executeModule: new SyncHook(["options", "context"]),-			/** @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */+			/**+			 * @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>}+			 * @since 5.33.0+			 */ 			prepareModuleExecution: new AsyncParallelHook(["options", "context"]),@@ -1092,3 +1098,6 @@ 			afterProcessAssets: afterProcessAssetsHook,-			/** @type {AsyncSeriesHook<[CompilationAssets]>} */+			/**+			 * @type {AsyncSeriesHook<[CompilationAssets]>}+			 * @since 5.8.0+			 */ 			processAdditionalAssets: new AsyncSeriesHook(["assets"]),
lib/Compiler.js +16 lines
--- +++ @@ -224,5 +224,11 @@ -			/** @type {AsyncSeriesHook<[]>} */+			/**+			 * @type {AsyncSeriesHook<[]>}+			 * @since 5.67.0+			 */ 			readRecords: new AsyncSeriesHook([]),-			/** @type {AsyncSeriesHook<[]>} */+			/**+			 * @type {AsyncSeriesHook<[]>}+			 * @since 5.67.0+			 */ 			emitRecords: new AsyncSeriesHook([]),@@ -237,3 +243,6 @@ 			watchClose: new SyncHook([]),-			/** @type {AsyncSeriesHook<[]>} */+			/**+			 * @type {AsyncSeriesHook<[]>}+			 * @since 5.17.0+			 */ 			shutdown: new AsyncSeriesHook([]),@@ -245,3 +254,6 @@ 			// TODO move them for webpack 5-			/** @type {SyncHook<[]>} */+			/**+			 * @type {SyncHook<[]>}+			 * @since 5.106.0+			 */ 			validate: new SyncHook([]),
lib/DefinePlugin.js +10 lines
--- +++ @@ -630,2 +630,10 @@ +const createCompilationHooks = () => ({+	/**+	 * @type {SyncWaterfallHook<[Record<string, CodeValue>]>}+	 * @since 5.104.0+	 */+	definitions: new SyncWaterfallHook(["definitions"])+});+ /**@@ -651,5 +659,3 @@ /**- * Defines the define plugin hooks type used by this module.- * @typedef {object} DefinePluginHooks- * @property {SyncWaterfallHook<[Record<string, CodeValue>]>} definitions+ * @typedef {ReturnType<typeof createCompilationHooks>} DefinePluginHooks  */@@ -1261,8 +1267,3 @@ -DefinePlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {DefinePluginHooks} */ ({-			definitions: new SyncWaterfallHook(["definitions"])-		})-);+DefinePlugin.getCompilationHooks = createHooksRegistry(createCompilationHooks); 
lib/ExternalModule.js +11 lines
--- +++ @@ -812,6 +812,12 @@ -/**- * Defines the external module hooks type used by this module.- * @typedef {object} ExternalModuleHooks- * @property {SyncBailHook<[Chunk, Compilation], boolean>} chunkCondition+const createCompilationHooks = () => ({+	/**+	 * @type {SyncBailHook<[Chunk, Compilation], boolean>}+	 * @since 5.106.0+	 */+	chunkCondition: new SyncBailHook(["chunk", "compilation"])+});++/**+ * @typedef {ReturnType<typeof createCompilationHooks>} ExternalModuleHooks  */@@ -1488,6 +1494,3 @@ ExternalModule.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {ExternalModuleHooks} */ ({-			chunkCondition: new SyncBailHook(["chunk", "compilation"])-		})+	createCompilationHooks );
lib/ModuleFilenameHelpers.js +14 lines
--- +++ @@ -171,2 +171,4 @@ 	let shortIdentifier;+	/** @type {ReturnStringCallback} */+	let resourceIdentifier; 	if (typeof module === "string") {@@ -176,2 +178,3 @@ 		identifier = shortIdentifier;+		resourceIdentifier = shortIdentifier; 		moduleId = () => "";@@ -183,2 +186,10 @@ 			module.readableIdentifier(requestShortener)+		);+		// `[resource]` and `[loaders]` must stay request paths: a subclass's+		// readable identifier may carry display-only decorations (e.g. CssModule's+		// `css ` prefix)+		resourceIdentifier = memoize(() =>+			module instanceof NormalModule+				? /** @type {string} */ (requestShortener.shorten(module.userRequest))+				: module.readableIdentifier(requestShortener) 		);@@ -198,5 +209,5 @@ 		/** @type {ReturnStringCallback} */-		(memoize(() => shortIdentifier().split("!").pop()));--	const loaders = getBefore(shortIdentifier, "!");+		(memoize(() => resourceIdentifier().split("!").pop()));++	const loaders = getBefore(resourceIdentifier, "!"); 	const allLoaders = getBefore(identifier, "!");
lib/NormalModule.js +74 lines
--- +++ @@ -54,3 +54,3 @@ 	contextify,-	makePathsRelative+	contextifySourceUrl } = require("./util/identifier");@@ -395,17 +395,2 @@  * @param {string} context absolute context path- * @param {string} source a source path- * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached- * @returns {string} new source path- */-const contextifySourceUrl = (context, source, associatedObjectForCache) => {-	if (source.startsWith("webpack://")) return source;-	return `webpack://${makePathsRelative(-		context,-		source,-		associatedObjectForCache-	)}`;-};--/**- * @param {string} context absolute context path  * @param {string | RawSourceMap} sourceMap a source map@@ -473,12 +458,75 @@ +const createCompilationHooks = () => {+	/** @type {HookMap<AsyncSeriesBailHook<[AnyLoaderContext], string | Buffer | null>>} */+	const readResource = new HookMap(+		() => new AsyncSeriesBailHook(["loaderContext"])+	);+	return {+		// TODO webpack 6 deprecate+		/**+		 * @deprecated Use the `readResource` hook instead.+		 * @type {DeprecatedReadResourceForScheme}+		 */+		readResourceForScheme: new HookMap((scheme) => {+			const hook = readResource.for(scheme);+			return createFakeHook(+				/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({+					tap: (options, fn) =>+						hook.tap(options, (loaderContext) =>+							fn(+								loaderContext.resource,+								/** @type {NormalModule} */ (loaderContext._module)+							)+						),+					tapAsync: (options, fn) =>+						hook.tapAsync(options, (loaderContext, callback) =>+							fn(+								loaderContext.resource,+								/** @type {NormalModule} */ (loaderContext._module),+								callback+							)+						),+					tapPromise: (options, fn) =>+						hook.tapPromise(options, (loaderContext) =>+							fn(+								loaderContext.resource,+								/** @type {NormalModule} */ (loaderContext._module)+							)+						)+				})+			);+		}),+		/**+		 * @since 5.58.0+		 */+		readResource,+		/** @type {SyncHook<[AnyLoaderContext, NormalModule]>} */+		loader: new SyncHook(["loaderContext", "module"]),+		/** @type {SyncHook<[LoaderItem[], NormalModule, AnyLoaderContext]>} */+		beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]),+		/**+		 * @type {SyncHook<[NormalModule]>}+		 * @since 5.59.0+		 */+		beforeParse: new SyncHook(["module"]),+		/**+		 * @type {SyncHook<[NormalModule]>}+		 * @since 5.59.0+		 */+		beforeSnapshot: new SyncHook(["module"]),+		/**+		 * @type {SyncWaterfallHook<[Result, NormalModule]>}+		 * @since 5.99.0+		 */+		processResult: new SyncWaterfallHook(["result", "module"]),+		/**+		 * @type {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>}+		 * @since 5.49.0+		 */+		needBuild: new AsyncSeriesBailHook(["module", "context"])+	};+};+ /**- * @typedef {object} NormalModuleCompilationHooks- * @property {SyncHook<[AnyLoaderContext, NormalModule]>} loader- * @property {SyncHook<[LoaderItem[], NormalModule, AnyLoaderContext]>} beforeLoaders- * @property {SyncHook<[NormalModule]>} beforeParse- * @property {SyncHook<[NormalModule]>} beforeSnapshot- * @property {DeprecatedReadResourceForScheme} readResourceForScheme- * @property {HookMap<AsyncSeriesBailHook<[AnyLoaderContext], string | Buffer | null>>} readResource- * @property {SyncWaterfallHook<[Result, NormalModule]>} processResult- * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild+ * @typedef {ReturnType<typeof createCompilationHooks>} NormalModuleCompilationHooks  */@@ -526,48 +574,3 @@ -const normalModuleHooksRegistry = createHooksRegistry(() => {-	// TODO webpack 6 deprecate-	/** @type {Partial<NormalModuleCompilationHooks>} */-	const hooks = {};-	hooks.readResourceForScheme = new HookMap((scheme) => {-		const hook =-			/** @type {NormalModuleCompilationHooks} */-			(hooks).readResource.for(scheme);-		return createFakeHook(-			/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({-				tap: (options, fn) =>-					hook.tap(options, (loaderContext) =>-						fn(-							loaderContext.resource,-							/** @type {NormalModule} */ (loaderContext._module)-						)-					),-				tapAsync: (options, fn) =>-					hook.tapAsync(options, (loaderContext, callback) =>-						fn(-							loaderContext.resource,-							/** @type {NormalModule} */ (loaderContext._module),-							callback-						)-					),-				tapPromise: (options, fn) =>-					hook.tapPromise(options, (loaderContext) =>-						fn(-							loaderContext.resource,-							/** @type {NormalModule} */ (loaderContext._module)-						)-					)-			})-		);-	});-	hooks.readResource = new HookMap(-		() => new AsyncSeriesBailHook(["loaderContext"])-	);-	hooks.loader = new SyncHook(["loaderContext", "module"]);-	hooks.beforeLoaders = new SyncHook(["loaders", "module", "loaderContext"]);-	hooks.beforeParse = new SyncHook(["module"]);-	hooks.beforeSnapshot = new SyncHook(["module"]);-	hooks.processResult = new SyncWaterfallHook(["result", "module"]);-	hooks.needBuild = new AsyncSeriesBailHook(["module", "context"]);-	return /** @type {NormalModuleCompilationHooks} */ (hooks);-});+const normalModuleHooksRegistry = createHooksRegistry(createCompilationHooks); 
lib/NormalModuleFactory.js +8 lines
--- +++ @@ -437,3 +437,6 @@ 			),-			/** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */+			/**+			 * @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>}+			 * @since 5.49.0+			 */ 			resolveInScheme: new HookMap(@@ -463,3 +466,6 @@ 			),-			/** @type {HookMap<SyncBailHook<[CreateData, ResolveData], Module | void>>} */+			/**+			 * @type {HookMap<SyncBailHook<[CreateData, ResolveData], Module | void>>}+			 * @since 5.81.0+			 */ 			createModuleClass: new HookMap(
lib/cache/PackFileCacheStrategy.js +259 lines
--- +++ @@ -9,2 +9,3 @@ const ProgressPlugin = require("../ProgressPlugin");+const { getReferencedFilenames } = require("../serialization/FileMiddleware"); const SerializerMiddleware = require("../serialization/SerializerMiddleware");@@ -36,2 +37,13 @@ /** @typedef {Map<string, PackItemInfo>} ItemInfo */+/** @typedef {{ firstSeen: number, size: number }} UnreferencedFile */+/** @typedef {Map<string, UnreferencedFile>} UnreferencedFiles */++// Unreferenced files are kept for this long to not race concurrent builds sharing the cache directory.+const CLEANUP_GRACE_PERIOD = 30 * 60 * 1000;+// Records when each unreferenced file was first seen. Aging by recorded time keeps+// orphans expiring across caches restored with refreshed modification times.+const UNREFERENCED_FILE = "unreferenced.json";+// A file written this recently may belong to a concurrent build that reused the name,+// in which case the recorded time describes the previous file and must not be trusted.+const CLEANUP_RECENT_WRITE_PERIOD = 60 * 1000; @@ -572,2 +584,37 @@ 	/**+	 * Drops every content whose items all expired. Unlike a partial collection this+	 * never unpacks, so it is not limited to a single content per store and lets a+	 * long unused cache shrink in one go instead of one pack per build.+	 */+	_gcExpiredContent() {+		const now = Date.now();+		let packCount = 0;+		let itemCount = 0;+		for (let loc = 0; loc < this.content.length; loc++) {+			const content = this.content[loc];+			if (!content) continue;+			let expired = true;+			for (const identifier of content.items) {+				const info = this.itemInfo.get(identifier);+				if (info !== undefined && now - info.lastAccess <= this.maxAge) {+					expired = false;+					break;+				}+			}+			if (!expired) continue;+			for (const identifier of content.items) this.itemInfo.delete(identifier);+			this.content[loc] = undefined;+			packCount++;+			itemCount += content.items.size;+		}+		if (packCount > 0) {+			this.logger.log(+				"Garbage Collected %d completely expired packs with %d items",+				packCount,+				itemCount+			);+		}+	}++	/** 	 * Find the content with the oldest item and run GC on that.@@ -583,7 +630,6 @@ 		}-		if (-			Date.now() - /** @type {PackItemInfo} */ (oldest).lastAccess >-			this.maxAge-		) {-			const loc = /** @type {PackItemInfo} */ (oldest).location;+		// collecting expired content may have left no items at all+		if (oldest === undefined) return;+		if (Date.now() - oldest.lastAccess > this.maxAge) {+			const loc = oldest.location; 			if (loc < 0) return;@@ -623,2 +669,3 @@ 		this._optimizeUnusedContent();+		this._gcExpiredContent(); 		this._gcOldestContent();@@ -1168,2 +1215,4 @@ 		this.compiler = compiler;+		/** @type {IntermediateFileSystem} */+		this.fs = fs; 		/** @type {string} */@@ -1184,2 +1233,6 @@ 		this.allowCollectingMemory = allowCollectingMemory;+		// referenced names per on-disk file, versioned by mtime since concurrent+		// processes may rewrite packs in place under the same name+		/** @type {Map<string, { mtimeMs: number, referenced: string[] }>} */+		this._referencedFilesCache = new Map(); 		/** @type {false | "gzip" | "brotli" | "zstd" | undefined} */@@ -1590,2 +1643,7 @@ 					);+					const cleanup = this.fs.unlink !== undefined;+					/** @type {Set<string> | undefined} */+					const writtenFiles = cleanup ? new Set() : undefined;+					/** @type {Set<string> | undefined} */+					const retainedFiles = cleanup ? new Set() : undefined; 					return this.fileSerializer@@ -1594,2 +1652,4 @@ 							extension: `${this._extension}`,+							writtenFiles,+							retainedFiles, 							logger: this.logger,@@ -1610,2 +1670,8 @@ 							);+							if (writtenFiles !== undefined) {+								return this._cleanupUnusedFiles(+									writtenFiles,+									/** @type {Set<string>} */ (retainedFiles)+								);+							} 						})@@ -1613,2 +1679,4 @@ 							this.logger.timeEnd("store pack");+							// files may be in an unknown state after a failed store+							this._referencedFilesCache.clear(); 							this.logger.warn(`Caching failed for pack: ${err}`);@@ -1624,2 +1692,188 @@ +	/**+	 * Reads when the currently unreferenced files were first seen. A missing or+	 * unreadable file just restarts the grace period for every orphan.+	 * @returns {Promise<UnreferencedFiles>} first seen time and size per file name+	 */+	_readUnreferencedFiles() {+		return new Promise((resolve) => {+			this.fs.readFile(+				`${this.cacheLocation}/${UNREFERENCED_FILE}`,+				(err, content) => {+					/** @type {UnreferencedFiles} */+					const result = new Map();+					if (err) return resolve(result);+					try {+						const data = JSON.parse(+							/** @type {Buffer} */ (content).toString("utf8")+						);+						for (const [file, entry] of Object.entries(data)) {+							const { firstSeen, size } = /** @type {UnreferencedFile} */ (+								entry+							);+							if (typeof firstSeen === "number" && typeof size === "number") {+								result.set(file, { firstSeen, size });+							}+						}+					} catch (_err) {+						result.clear();+					}+					resolve(result);+				}+			);+		});+	}++	/**+	 * Persists when the still unreferenced files were first seen. Failing to write+	 * only costs the orphans another grace period, so errors are ignored.+	 * @param {UnreferencedFiles} unreferenced first seen time and size per file name+	 * @param {boolean} hadEntries whether a previous state exists that must be replaced+	 * @returns {Promise<void>} promise+	 */+	_writeUnreferencedFiles(unreferenced, hadEntries) {+		if (unreferenced.size === 0 && !hadEntries) return Promise.resolve();+		/** @type {Record<string, UnreferencedFile>} */+		const data = {};+		for (const [file, entry] of unreferenced) data[file] = entry;+		return new Promise((resolve) => {+			this.fs.writeFile(+				`${this.cacheLocation}/${UNREFERENCED_FILE}`,+				JSON.stringify(data),+				() => resolve()+			);+		});+	}++	/**+	 * Deletes files from the cache directory that are no longer referenced by the+	 * stored pack. Retained files are walked on disk since nested lazy segments+	 * reference files not visible during serialization. Errors only log a warning.+	 * @param {Set<string>} writtenNames names (without extension) written by this store+	 * @param {Set<string>} retainedNames names (without extension) referenced but not rewritten+	 * @returns {Promise<void>} promise+	 */+	async _cleanupUnusedFiles(writtenNames, retainedNames) {+		this.logger.time("cleanup unused cache files");+		const fs = this.fs;+		const extension = this._extension;+		const cacheLocation = this.cacheLocation;+		const referencedFilesCache = this._referencedFilesCache;+		try {+			// rewritten files may reference different names now+			for (const name of writtenNames) referencedFilesCache.delete(name);+			/** @type {Set<string>} */+			const liveFiles = new Set([`index${extension}`, UNREFERENCED_FILE]);+			for (const name of writtenNames) liveFiles.add(`${name}${extension}`);+			/** @type {string[]} */+			const queue = [];+			/**+			 * Marks a file live and queues it for walking its references.+			 * @param {string} name file name without extension+			 */+			const enqueue = (name) => {+				const file = `${name}${extension}`;+				if (liveFiles.has(file)) return;+				liveFiles.add(file);+				queue.push(name);+			};+			for (const name of retainedNames) enqueue(name);+			while (queue.length > 0) {+				const name = /** @type {string} */ (queue.pop());+				const file = `${cacheLocation}/${name}${extension}`;+				// an unchanged mtime proves the memo entry still matches the disk+				const mtimeMs = await new Promise((resolve, reject) => {+					fs.stat(file, (err, stats) => {+						if (err) return reject(err);+						resolve(+							/** @type {number} */ (+								/** @type {import("../util/fs").IStats} */ (stats).mtimeMs+							)+						);+					});+				});+				const entry = referencedFilesCache.get(name);+				let referenced;+				if (entry !== undefined && entry.mtimeMs === mtimeMs) {+					referenced = entry.referenced;+				} else {+					referenced = await getReferencedFilenames(fs, file);+					referencedFilesCache.set(name, { mtimeMs, referenced });+				}+				for (const referencedName of referenced) enqueue(referencedName);+			}+			const files = await new Promise((resolve, reject) => {+				fs.readdir(cacheLocation, (err, files) => {+					if (err) return reject(err);+					resolve(/** @type {string[]} */ (files));+				});+			});+			const seenFiles = await this._readUnreferencedFiles();+			const now = Date.now();+			// every store rewrites the index backup, so a recorded time would age a file+			// that is in fact new; renaming carries the previous index mtime onto it+			const indexBackup = `index${extension}.old`;+			/** @type {UnreferencedFiles} */+			const stillUnreferenced = new Map();+			let deletedCount = 0;+			for (const file of files) {+				if (typeof file !== "string" || liveFiles.has(file)) continue;+				const path = `${cacheLocation}/${file}`;+				const stats = await new Promise((resolve) => {+					fs.stat(path, (err, stats) => {+						resolve(+							err+								? undefined+								: /** @type {import("../util/fs").IStats} */ (stats)
… 52 more lines (truncated)
lib/config/defaults.js +21 lines
--- +++ @@ -513,3 +513,9 @@ 		),-		{ targetProperties, environment: options.output.environment }+		{+			targetProperties,+			environment: options.output.environment,+			outputModule:+				/** @type {NonNullable<WebpackOptionsNormalized["output"]["module"]>} */+				(options.output.module)+		} 	);@@ -2253,5 +2259,9 @@  * @param {Environment} options.environment environment+ * @param {boolean} options.outputModule is output type is module  * @returns {void}  */-const applyLoaderDefaults = (loader, { targetProperties, environment }) => {+const applyLoaderDefaults = (+	loader,+	{ targetProperties, environment, outputModule }+) => { 	F(loader, "target", () => {@@ -2269,2 +2279,11 @@ 			if (targetProperties.web) return "web";+			// no single platform to report: the bundle runs on both (target+			// `"universal"` / `["web", "node"]`), so loaders get `"universal"`+			if (+				outputModule &&+				targetProperties.node === null &&+				targetProperties.web === null+			) {+				return "universal";+			} 		}
lib/container/ModuleFederationPlugin.js +15 lines
--- +++ @@ -20,7 +20,17 @@ +const createCompilationHooks = () => ({+	/**+	 * @type {SyncHook<Dependency>}+	 * @since 5.96.0+	 */+	addContainerEntryDependency: new SyncHook(["dependency"]),+	/**+	 * @type {SyncHook<Dependency>}+	 * @since 5.96.0+	 */+	addFederationRuntimeDependency: new SyncHook(["dependency"])+});+ /**- * Defines the compilation hooks type used by this module.- * @typedef {object} CompilationHooks- * @property {SyncHook<Dependency>} addContainerEntryDependency- * @property {SyncHook<Dependency>} addFederationRuntimeDependency+ * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks  */@@ -113,7 +123,3 @@ ModuleFederationPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CompilationHooks} */ ({-			addContainerEntryDependency: new SyncHook(["dependency"]),-			addFederationRuntimeDependency: new SyncHook(["dependency"])-		})+	createCompilationHooks );
lib/css/CssGenerator.js +8 lines
--- +++ @@ -35,2 +35,3 @@ const { encodeMappings } = require("../util/createMappings");+const { contextifySourceUrl } = require("../util/identifier"); const memoize = require("../util/memoize");@@ -551,4 +552,9 @@ 				const generatedJs = /** @type {string} */ (source.source());-				const sourceName = module.readableIdentifier(-					compilation.requestShortener+				// Context-relative identifier, like `NormalModule.createSource` — so+				// `SourceMapDevToolPlugin` can match the module and apply the+				// devtool filename template instead of leaking this raw name+				const sourceName = contextifySourceUrl(+					/** @type {string} */ (compilation.options.context),+					module.identifier(),+					compilation.compiler.root 				);
lib/css/CssLoadingRuntimeModule.js +25 lines
--- +++ @@ -22,8 +22,27 @@ +const createCompilationHooks = () => ({+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.66.0+	 */+	createStylesheet: new SyncWaterfallHook(["source", "chunk"]),+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.91.0+	 */+	linkPreload: new SyncWaterfallHook(["source", "chunk"]),+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.91.0+	 */+	linkPrefetch: new SyncWaterfallHook(["source", "chunk"]),+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.107.0+	 */+	linkInsert: new SyncWaterfallHook(["source", "chunk"])+});+ /**- * @typedef {object} CssLoadingRuntimeModulePluginHooks- * @property {SyncWaterfallHook<[string, Chunk]>} createStylesheet- * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload- * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch- * @property {SyncWaterfallHook<[string, Chunk]>} linkInsert+ * @typedef {ReturnType<typeof createCompilationHooks>} CssLoadingRuntimeModulePluginHooks  */@@ -579,9 +598,3 @@ CssLoadingRuntimeModule.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CssLoadingRuntimeModulePluginHooks} */ ({-			createStylesheet: new SyncWaterfallHook(["source", "chunk"]),-			linkPreload: new SyncWaterfallHook(["source", "chunk"]),-			linkPrefetch: new SyncWaterfallHook(["source", "chunk"]),-			linkInsert: new SyncWaterfallHook(["source", "chunk"])-		})+	createCompilationHooks );
lib/css/CssModulesPlugin.js +29 lines
--- +++ @@ -98,10 +98,2 @@ /**- * Defines the compilation hooks type used by this module.- * @typedef {object} CompilationHooks- * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage- * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash- * @property {SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined | void>} orderModules called for each CSS source type (CSS_IMPORT_TYPE, CSS_TYPE) with the chunk's modules pre-sorted by full module name; return an ordered `Module[]` to override the default import-order topological sort, or return `undefined` to keep the default- */--/**  * Defines the module factory cache entry type used by this module.@@ -221,2 +213,30 @@ const PLUGIN_NAME = "CssModulesPlugin";++const createCompilationHooks = () => ({+	/**+	 * @type {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>}+	 * @since 5.94.0+	 */+	renderModulePackage: new SyncWaterfallHook([+		"source",+		"module",+		"renderContext"+	]),+	/**+	 * @type {SyncHook<[Chunk, Hash, ChunkHashContext]>}+	 * @since 5.94.0+	 */+	chunkHash: new SyncHook(["chunk", "hash", "context"]),+	/**+	 * Called for each CSS source type (CSS_IMPORT_TYPE, CSS_TYPE) with the chunk's modules pre-sorted by full module name; return an ordered `Module[]` to override the default import-order topological sort, or return `undefined` to keep the default.+	 * @type {SyncBailHook<[Chunk, Module[], Compilation], Module[] | undefined | void>}+	 * @since 5.107.0+	 */+	orderModules: new SyncBailHook(["chunk", "modules", "compilation"])+});++/**+ * Defines the compilation hooks type used by this module.+ * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks+ */ @@ -1177,12 +1197,3 @@ CssModulesPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CompilationHooks} */ ({-			renderModulePackage: new SyncWaterfallHook([-				"source",-				"module",-				"renderContext"-			]),-			chunkHash: new SyncHook(["chunk", "hash", "context"]),-			orderModules: new SyncBailHook(["chunk", "modules", "compilation"])-		})+	createCompilationHooks );
lib/dependencies/CommonJsFullRequireDependency.js +33 lines
--- +++ @@ -11,2 +11,3 @@ const makeSerializable = require("../util/makeSerializable");+const memoize = require("../util/memoize"); const { propertyAccess } = require("../util/property");@@ -21,2 +22,3 @@ /** @typedef {import("../Dependency")} Dependency */+/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */@@ -28,4 +30,7 @@ /** @typedef {import("../util/chainedImports").IdRanges} IdRanges */-/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean]>} ObjectDeserializerContext */-/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean]>} ObjectSerializerContext */+/** @typedef {import("./HarmonyImportGuard").DependencyGuard} DependencyGuard */+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean, DependencyGuard[] | undefined]>} ObjectDeserializerContext */+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean, DependencyGuard[] | undefined]>} ObjectSerializerContext */++const getHarmonyImportGuard = memoize(() => require("./HarmonyImportGuard")); @@ -55,2 +60,16 @@ 		this.asiSafe = undefined;+		/** @type {DependencyGuard[] | undefined} */+		this.branchGuards = undefined;+	}++	/**+	 * Returns function to determine if the connection is active.+	 * @param {ModuleGraph} moduleGraph module graph+	 * @returns {null | false | GetConditionFn} function to determine if the connection is active+	 */+	getCondition(moduleGraph) {+		const guards = this.branchGuards;+		if (guards === undefined) return null;+		return (connection, runtime) =>+			!getHarmonyImportGuard().isDeadByGuards(guards, moduleGraph, runtime); 	}@@ -94,3 +113,4 @@ 			.write(this.call)-			.write(this.asiSafe);+			.write(this.asiSafe)+			.write(this.branchGuards); 		super.serialize(context);@@ -110,3 +130,5 @@ 		this.asiSafe = c3.read();-		super.deserialize(c3.rest);+		const c4 = c3.rest;+		this.branchGuards = c4.read();+		super.deserialize(c4.rest); 	}@@ -139,2 +161,9 @@ 		if (!dep.range) return;+		const connection = moduleGraph.getConnection(dep);+		// Dead branch: module is excluded and has no id; code is never executed.+		if (connection && !connection.isTargetActive(runtime)) {+			// Replaces the whole member chain, so no property access is left dangling+			source.replace(dep.range[0], dep.range[1] - 1, "null /* dead branch */");+			return;+		} 		const importedModule = moduleGraph.getModule(dep);
lib/dependencies/CommonJsImportsParserPlugin.js +2 lines
--- +++ @@ -644,2 +644,3 @@ 				parser.state.current.addDependency(dep);+				getHarmonyImportGuard().attachDependencyGuards(parser, dep); 				return true;@@ -682,2 +683,3 @@ 				parser.state.current.addDependency(dep);+				getHarmonyImportGuard().attachDependencyGuards(parser, dep); 				parser.walkExpressions(expr.arguments);
lib/dependencies/HarmonyImportGuard.js +2 lines
--- +++ @@ -16,2 +16,3 @@ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */+/** @typedef {import("./CommonJsFullRequireDependency")} CommonJsFullRequireDependency */ /** @typedef {import("./CommonJsRequireDependency")} CommonJsRequireDependency */@@ -31,3 +32,3 @@ /** @typedef {{ formula: GuardFormula, value: boolean }} DependencyGuard branch guard: the dependency is live only when the formula evaluates to `value` */-/** @typedef {HarmonyImportSpecifierDependency | CommonJsRequireDependency | ImportDependency} GuardableDependency */+/** @typedef {HarmonyImportSpecifierDependency | CommonJsRequireDependency | CommonJsFullRequireDependency | ImportDependency} GuardableDependency */ 
lib/esm/ModuleChunkLoadingRuntimeModule.js +15 lines
--- +++ @@ -27,7 +27,17 @@ +const createCompilationHooks = () => ({+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.41.0+	 */+	linkPreload: new SyncWaterfallHook(["source", "chunk"]),+	/**+	 * @type {SyncWaterfallHook<[string, Chunk]>}+	 * @since 5.41.0+	 */+	linkPrefetch: new SyncWaterfallHook(["source", "chunk"])+});+ /**- * Defines the jsonp compilation plugin hooks type used by this module.- * @typedef {object} JsonpCompilationPluginHooks- * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload- * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch+ * @typedef {ReturnType<typeof createCompilationHooks>} JsonpCompilationPluginHooks  */@@ -440,7 +450,3 @@ ModuleChunkLoadingRuntimeModule.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {JsonpCompilationPluginHooks} */ ({-			linkPreload: new SyncWaterfallHook(["source", "chunk"]),-			linkPrefetch: new SyncWaterfallHook(["source", "chunk"])-		})+	createCompilationHooks );
lib/html/HtmlModulesPlugin.js +30 lines
--- +++ @@ -74,8 +74,32 @@ /** @typedef {{ outputName: string, html: string }} HtmlTransformTagsContext */++const createCompilationHooks = () => ({+	/**+	 * Called with the list of extra tags to inject into each page (initially empty) plus the current HTML; push `HtmlTagDescriptor`s and return the list — webpack serializes and places them by `injectTo`. A structured alternative to the string-level `transformHtml` for adding tags; runs before CSP so injected inline tags are hashed.+	 * @type {AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], HtmlInjectTagsContext]>}+	 * @since 5.109.0+	 */+	injectTags: new AsyncSeriesWaterfallHook(["tags", "context"]),+	/**+	 * Called with the page's `<script>`/`<link>`/`<style>`/`<meta>` tags (webpack's own and any injected) as mutable descriptors; mutate `attrs` (add a `nonce`/`data-*`, switch `defer`↔`async`, …), set `remove: true`, or change `injectTo` to move a tag between `<head>` and `<body>`, and webpack rewrites the changed tags. Add new tags with `injectTags` instead.+	 * @type {AsyncSeriesHook<[HtmlMutableTag[], HtmlTransformTagsContext]>}+	 * @since 5.109.0+	 */+	transformTags: new AsyncSeriesHook(["tags", "context"]),+	/**+	 * Called with each emitted page's final HTML (all sentinels resolved) just before it is written; return the (possibly transformed) HTML — e.g. to minify, inject a CSP meta, or rewrite tags.+	 * @type {AsyncSeriesWaterfallHook<[string, HtmlTransformHtmlContext]>}+	 * @since 5.109.0+	 */+	transformHtml: new AsyncSeriesWaterfallHook(["html", "context"]),+	/**+	 * Called once each page's HTML asset has been finalized — a post-emit notification (nothing to return).+	 * @type {AsyncSeriesHook<[HtmlEmittedContext]>}+	 * @since 5.109.0+	 */+	htmlEmitted: new AsyncSeriesHook(["context"])+});+ /**- * @typedef {object} HtmlCompilationHooks- * @property {AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], HtmlInjectTagsContext]>} injectTags called with the list of extra tags to inject into each page (initially empty) plus the current HTML; push `HtmlTagDescriptor`s and return the list — webpack serializes and places them by `injectTo`. A structured alternative to the string-level `transformHtml` for adding tags; runs before CSP so injected inline tags are hashed- * @property {AsyncSeriesHook<[HtmlMutableTag[], HtmlTransformTagsContext]>} transformTags called with the page's `<script>`/`<link>`/`<style>`/`<meta>` tags (webpack's own and any injected) as mutable descriptors; mutate `attrs` (add a `nonce`/`data-*`, switch `defer`↔`async`, …), set `remove: true`, or change `injectTo` to move a tag between `<head>` and `<body>`, and webpack rewrites the changed tags. Add new tags with `injectTags` instead- * @property {AsyncSeriesWaterfallHook<[string, HtmlTransformHtmlContext]>} transformHtml called with each emitted page's final HTML (all sentinels resolved) just before it is written; return the (possibly transformed) HTML — e.g. to minify, inject a CSP meta, or rewrite tags- * @property {AsyncSeriesHook<[HtmlEmittedContext]>} htmlEmitted called once each page's HTML asset has been finalized — a post-emit notification (nothing to return)+ * @typedef {ReturnType<typeof createCompilationHooks>} HtmlCompilationHooks  */@@ -1101,9 +1125,3 @@ HtmlModulesPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {HtmlCompilationHooks} */ ({-			injectTags: new AsyncSeriesWaterfallHook(["tags", "context"]),-			transformTags: new AsyncSeriesHook(["tags", "context"]),-			transformHtml: new AsyncSeriesWaterfallHook(["html", "context"]),-			htmlEmitted: new AsyncSeriesHook(["context"])-		})+	createCompilationHooks );
lib/javascript/JavascriptModulesPlugin.js +83 lines
--- +++ @@ -332,19 +332,85 @@ +const createCompilationHooks = () => ({+	/**+	 * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}+	 */+	renderModuleContent: new SyncWaterfallHook([+		"source",+		"module",+		"moduleRenderContext"+	]),+	/**+	 * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}+	 */+	renderModuleContainer: new SyncWaterfallHook([+		"source",+		"module",+		"moduleRenderContext"+	]),+	/**+	 * @type {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>}+	 */+	renderModulePackage: new SyncWaterfallHook([+		"source",+		"module",+		"moduleRenderContext"+	]),+	/**+	 * @type {SyncWaterfallHook<[Source, RenderContext]>}+	 */+	render: new SyncWaterfallHook(["source", "renderContext"]),+	/**+	 * @type {SyncWaterfallHook<[Source, RenderContext]>}+	 * @since 5.41.0+	 */+	renderContent: new SyncWaterfallHook(["source", "renderContext"]),+	/**+	 * @type {SyncWaterfallHook<[Source, Module, StartupRenderContext]>}+	 * @since 5.22.0+	 */+	renderStartup: new SyncWaterfallHook([+		"source",+		"module",+		"startupRenderContext"+	]),+	/**+	 * @type {SyncWaterfallHook<[Source, RenderContext]>}+	 */+	renderChunk: new SyncWaterfallHook(["source", "renderContext"]),+	/**+	 * @type {SyncWaterfallHook<[Source, RenderContext]>}+	 */+	renderMain: new SyncWaterfallHook(["source", "renderContext"]),+	/**+	 * @type {SyncWaterfallHook<[string, RenderBootstrapContext]>}+	 */+	renderRequire: new SyncWaterfallHook(["code", "renderContext"]),+	/**+	 * @type {SyncBailHook<[Module, Partial<RenderBootstrapContext>], string | void>}+	 * @since 5.22.0+	 */+	inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),+	/**+	 * @type {SyncBailHook<[Module, RenderContext], string | void>}+	 * @since 5.22.0+	 */+	embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),+	/**+	 * @type {SyncBailHook<[RenderContext], string | void>}+	 * @since 5.26.1+	 */+	strictRuntimeBailout: new SyncBailHook(["renderContext"]),+	/**+	 * @type {SyncHook<[Chunk, Hash, ChunkHashContext]>}+	 */+	chunkHash: new SyncHook(["chunk", "hash", "context"]),+	/**+	 * @type {SyncBailHook<[Chunk, RenderContext], boolean | void>}+	 * @since 5.2.1+	 */+	useSourceMap: new SyncBailHook(["chunk", "renderContext"])+});+ /**- * Defines the compilation hooks type used by this module.- * @typedef {object} CompilationHooks- * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContent- * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContainer- * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModulePackage- * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk- * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain- * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent- * @property {SyncWaterfallHook<[Source, RenderContext]>} render- * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup- * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire- * @property {SyncBailHook<[Module, Partial<RenderBootstrapContext>], string | void>} inlineInRuntimeBailout- * @property {SyncBailHook<[Module, RenderContext], string | void>} embedInRuntimeBailout- * @property {SyncBailHook<[RenderContext], string | void>} strictRuntimeBailout- * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash- * @property {SyncBailHook<[Chunk, RenderContext], boolean | void>} useSourceMap+ * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks  */@@ -2290,35 +2356,3 @@ JavascriptModulesPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CompilationHooks} */ ({-			renderModuleContent: new SyncWaterfallHook([-				"source",-				"module",-				"moduleRenderContext"-			]),-			renderModuleContainer: new SyncWaterfallHook([-				"source",-				"module",-				"moduleRenderContext"-			]),-			renderModulePackage: new SyncWaterfallHook([-				"source",-				"module",-				"moduleRenderContext"-			]),-			render: new SyncWaterfallHook(["source", "renderContext"]),-			renderContent: new SyncWaterfallHook(["source", "renderContext"]),-			renderStartup: new SyncWaterfallHook([-				"source",-				"module",-				"startupRenderContext"-			]),-			renderChunk: new SyncWaterfallHook(["source", "renderContext"]),-			renderMain: new SyncWaterfallHook(["source", "renderContext"]),-			renderRequire: new SyncWaterfallHook(["code", "renderContext"]),-			inlineInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),-			embedInRuntimeBailout: new SyncBailHook(["module", "renderContext"]),-			strictRuntimeBailout: new SyncBailHook(["renderContext"]),-			chunkHash: new SyncHook(["chunk", "hash", "context"]),-			useSourceMap: new SyncBailHook(["chunk", "renderContext"])-		})+	createCompilationHooks );
lib/javascript/JavascriptParser.js +44 lines
--- +++ @@ -516,3 +516,6 @@ 			),-			/** @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | null | undefined>>} */+			/**+			 * @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | null | undefined>>}+			 * @since 5.73.0+			 */ 			evaluateNewExpression: new HookMap(@@ -520,3 +523,6 @@ 			),-			/** @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | null | undefined>>} */+			/**+			 * @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | null | undefined>>}+			 * @since 5.73.0+			 */ 			evaluateCallExpression: new HookMap(@@ -534,3 +540,6 @@ 			preStatement: new SyncBailHook(["statement"]),-			/** @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>} */+			/**+			 * @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}+			 * @since 5.109.0+			 */ 			preStatementByType: new HookMap(() => new SyncBailHook(["statement"])),@@ -539,3 +548,6 @@ 			blockPreStatement: new SyncBailHook(["declaration"]),-			/** @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>} */+			/**+			 * @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}+			 * @since 5.109.0+			 */ 			blockPreStatementByType: new HookMap(@@ -547,3 +559,6 @@ 			statementIf: new SyncBailHook(["statement"]),-			/** @type {SyncBailHook<[Expression], GuardCollection | void>} */+			/**+			 * @type {SyncBailHook<[Expression], GuardCollection | void>}+			 * @since 5.105.0+			 */ 			collectGuards: new SyncBailHook(["expression"]),@@ -556,3 +571,6 @@ 			classBodyElement: new SyncBailHook(["element", "classDefinition"]),-			/** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */+			/**+			 * @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>}+			 * @since 5.36.0+			 */ 			classBodyValue: new SyncBailHook([@@ -606,3 +624,6 @@ 			varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),-			/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */+			/**+			 * @type {HookMap<SyncBailHook<[Identifier], boolean | void>>}+			 * @since 5.100.0+			 */ 			varDeclarationUsing: new HookMap(() => new SyncBailHook(["declaration"])),@@ -612,3 +633,6 @@ 			pattern: new HookMap(() => new SyncBailHook(["pattern"])),-			/** @type {SyncBailHook<[Expression], boolean | void>} */+			/**+			 * @type {SyncBailHook<[Expression], boolean | void>}+			 * @since 5.101.3+			 */ 			collectDestructuringAssignmentProperties: new SyncBailHook([@@ -673,3 +697,6 @@ 			new: new HookMap(() => new SyncBailHook(["expression"])),-			/** @type {SyncBailHook<[BinaryExpression], boolean | void>} */+			/**+			 * @type {SyncBailHook<[BinaryExpression], boolean | void>}+			 * @since 5.71.0+			 */ 			binaryExpression: new SyncBailHook(["binaryExpression"]),@@ -697,3 +724,6 @@ 			program: new SyncBailHook(["ast", "comments"]),-			/** @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>} */+			/**+			 * @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>}+			 * @since 5.99.0+			 */ 			terminate: new SyncBailHook(["statement"]),@@ -701,3 +731,6 @@ 			finish: new SyncBailHook(["ast", "comments"]),-			/** @type {SyncBailHook<[Statement], boolean | void>} */+			/**+			 * @type {SyncBailHook<[Statement], boolean | void>}+			 * @since 5.99.9+			 */ 			unusedStatement: new SyncBailHook(["statement"])
lib/optimize/RealContentHashPlugin.js +11 lines
--- +++ @@ -168,6 +168,12 @@ -/**- * Defines the compilation hooks type used by this module.- * @typedef {object} CompilationHooks- * @property {SyncBailHook<[Buffer[], string], string | void>} updateHash+const createCompilationHooks = () => ({+	/**+	 * @type {SyncBailHook<[Buffer[], string], string | void>}+	 * @since 5.8.0+	 */+	updateHash: new SyncBailHook(["content", "oldHash"])+});++/**+ * @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks  */@@ -556,6 +562,3 @@ RealContentHashPlugin.getCompilationHooks = createHooksRegistry(-	() =>-		/** @type {CompilationHooks} */ ({-			updateHash: new SyncBailHook(["content", "oldHash"])-		})+	createCompilationHooks );
lib/serialization/FileMiddleware.js +301 lines
--- +++ @@ -9,2 +9,4 @@ const {+	// eslint-disable-next-line n/no-unsupported-features/node-builtins+	brotliDecompress, 	constants: zConstants,@@ -20,3 +22,6 @@ 	// eslint-disable-next-line n/no-unsupported-features/node-builtins-	createZstdDecompress+	createZstdDecompress,+	gunzip,+	// eslint-disable-next-line n/no-unsupported-features/node-builtins+	zstdDecompress } = require("zlib");@@ -53,2 +58,4 @@ const WRITE_LIMIT_CHUNK = 511 * 1024 * 1024;+// headers and pointer sections are tiny; anything above this is a corrupt file+const MAX_HEADER_OR_POINTER_SIZE = 256 * 1024 * 1024; @@ -113,2 +120,3 @@  * @param {HashFunction=} hashFunction hash function to use+ * @param {Set<string>=} retainedNames collects names of files that stay referenced without being rewritten  * @returns {Promise<SerializeResult>} resulting file pointer and promise@@ -120,3 +128,4 @@ 	writeFile,-	hashFunction = DEFAULTS.HASH_FUNCTION+	hashFunction = DEFAULTS.HASH_FUNCTION,+	retainedNames = undefined ) => {@@ -146,2 +155,6 @@ 				} else {+					if (retainedNames !== undefined) {+						// pointer buffer layout: u64 size + utf-8 file name+						retainedNames.add(serializedInfo.toString("utf8", 8));+					} 					processedData.push(serializedInfo);@@ -159,3 +172,4 @@ 							writeFile,-							hashFunction+							hashFunction,+							retainedNames 						).then((result) => {@@ -446,3 +460,10 @@ /** @typedef {true} SerializedType */-/** @typedef {{ filename: string, extension?: string }} Context */+/**+ * `writtenFiles`/`retainedFiles` collect file names (without extension) during+ * `serialize`: files written in this run and files that stay referenced by+ * lazy pointers without being rewritten. Retained files may reference further+ * files on disk not listed here (nested lazy segments); use+ * `getReferencedFilenames` to walk them.+ * @typedef {{ filename: string, extension?: string, writtenFiles?: Set<string>, retainedFiles?: Set<string> }} Context+ */ @@ -473,3 +494,3 @@ 	serialize(data, context) {-		const { filename, extension = "" } = context;+		const { filename, extension = "", writtenFiles, retainedFiles } = context; 		return new Promise((resolve, reject) => {@@ -583,3 +604,6 @@ 					);-					if (name) allWrittenFiles.add(file);+					if (name) {+						allWrittenFiles.add(file);+						if (writtenFiles !== undefined) writtenFiles.add(name);+					} 				};@@ -587,58 +611,63 @@ 				resolve(-					serialize(this, data, false, writeFile, this._hashFunction).then(-						async ({ backgroundJob }) => {-							await backgroundJob;--							// Rename the index file to disallow access during inconsistent file state-							await new Promise(-								/**-								 * Handles the callback logic for this hook.-								 * @param {(value?: undefined) => void} resolve resolve-								 */-								(resolve) => {-									this.fs.rename(filename, `${filename}.old`, (_err) => {-										resolve();-									});-								}-							);--							// update all written files-							await Promise.all(-								Array.from(-									allWrittenFiles,-									(file) =>-										new Promise(-											/**-											 * Handles the callback logic for this hook.-											 * @param {(value?: undefined) => void} resolve resolve-											 * @param {(reason?: Error | null) => void} reject reject-											 * @returns {void}-											 */-											(resolve, reject) => {-												this.fs.rename(`${file}_`, file, (err) => {-													if (err) return reject(err);-													resolve();-												});-											}-										)-								)-							);--							// As final step automatically update the index file to have a consistent pack again-							await new Promise(-								/**-								 * Handles the callback logic for this hook.-								 * @param {(value?: undefined) => void} resolve resolve-								 * @returns {void}-								 */-								(resolve) => {-									this.fs.rename(`${filename}_`, filename, (err) => {-										if (err) return reject(err);-										resolve();-									});-								}-							);-							return /** @type {true} */ (true);-						}-					)+					serialize(+						this,+						data,+						false,+						writeFile,+						this._hashFunction,+						retainedFiles+					).then(async ({ backgroundJob }) => {+						await backgroundJob;++						// Rename the index file to disallow access during inconsistent file state+						await new Promise(+							/**+							 * Handles the callback logic for this hook.+							 * @param {(value?: undefined) => void} resolve resolve+							 */+							(resolve) => {+								this.fs.rename(filename, `${filename}.old`, (_err) => {+									resolve();+								});+							}+						);++						// update all written files+						await Promise.all(+							Array.from(+								allWrittenFiles,+								(file) =>+									new Promise(+										/**+										 * Handles the callback logic for this hook.+										 * @param {(value?: undefined) => void} resolve resolve+										 * @param {(reason?: Error | null) => void} reject reject+										 * @returns {void}+										 */+										(resolve, reject) => {+											this.fs.rename(`${file}_`, file, (err) => {+												if (err) return reject(err);+												resolve();+											});+										}+									)+							)+						);++						// As final step automatically update the index file to have a consistent pack again+						await new Promise(+							/**+							 * Handles the callback logic for this hook.+							 * @param {(value?: undefined) => void} resolve resolve+							 * @returns {void}+							 */+							(resolve) => {+								this.fs.rename(`${filename}_`, filename, (err) => {+									if (err) return reject(err);+									resolve();+								});+							}+						);+						return /** @type {true} */ (true);+					}) 				);@@ -810,2 +839,211 @@ +/**+ * Extracts the file names referenced by lazy pointer sections from serialized content.+ * @param {Buffer} buf decompressed file content+ * @returns {string[]} referenced file names (without extension)+ */+const parsePointerNames = (buf) => {+	const version = buf.readUInt32LE(0);+	if (version !== VERSION) {+		throw new Error(`Invalid file version ${version}`);+	}+	const sectionCount = buf.readUInt32LE(4);+	let offset = 8 + sectionCount * 4;+	// a corrupt section table must abort the walk, never silently drop a name+	if (offset > buf.length) {+		throw new Error(`Invalid section count ${sectionCount}`);+	}+	/** @type {string[]} */+	const names = [];+	for (let i = 0; i < sectionCount; i++) {+		const length = buf.readInt32LE(8 + i * 4);+		if (length < 0) {+			// pointer section: u64 size + utf-8 file name+			const end = offset - length;+			if (end > buf.length) {+				throw new Error("Truncated pointer section");+			}+			names.push(buf.toString("utf8", offset + 8, end));+			offset = end;+		} else {+			offset += length;+		}+	}+	if (offset !== buf.length) {+		throw new Error("Section table does not match file size");+	}+	return names;+};++/**+ * Reads the pointer names of a compressed file by decompressing it fully+ * (compressed content cannot be read by byte range).+ * @param {IntermediateFileSystem} fs a file system+ * @param {string} file absolute path of the serialized file+ * @returns {Promise<string[]>} referenced file names (without extension)+ */+const getReferencedFilenamesCompressed = (fs, file) =>+	new Promise((resolve, reject) => {+		fs.readFile(file, (err, rawContent) => {+			if (err) return reject(err);+			/**+			 * Parses the decompressed content.+			 * @param {Error | null} err error+			 * @param {Buffer=} content decompressed content+			 * @returns {void}+			 */+			const onContent = (err, content) => {+				if (err) return reject(err);+				try {+					resolve(parsePointerNames(/** @type {Buffer} */ (content)));+				} catch (err_) {
… 153 more lines (truncated)
lib/util/identifier.js +21 lines
--- +++ @@ -534,2 +534,21 @@ +const makePathsRelative = makeCacheableWithContext(_makePathsRelative);++/**+ * Turns a source path into a `webpack://`-prefixed, context-relative source+ * URL, as used for the `sources` of module-level source maps.+ * @param {string} context absolute context path+ * @param {string} source a source path+ * @param {AssociatedObjectForCache=} associatedObjectForCache an object to which the cache will be attached+ * @returns {string} new source path+ */+const contextifySourceUrl = (context, source, associatedObjectForCache) => {+	if (source.startsWith("webpack://")) return source;+	return `webpack://${makePathsRelative(+		context,+		source,+		associatedObjectForCache+	)}`;+};+ const LINE_SEPARATOR_REGEXP = /[\u2028\u2029]/g;@@ -552,2 +571,3 @@ module.exports.contextify = contextify;+module.exports.contextifySourceUrl = contextifySourceUrl; module.exports.escapeHashInPathRequest = escapeHashInPathRequest;@@ -556,3 +576,3 @@ module.exports.makePathsAbsolute = makeCacheableWithContext(_makePathsAbsolute);-module.exports.makePathsRelative = makeCacheableWithContext(_makePathsRelative);+module.exports.makePathsRelative = makePathsRelative; module.exports.parseResource = makeCacheable(_parseResource);
package.json +3 lines
--- +++ @@ -2,3 +2,3 @@   "name": "webpack",-  "version": "5.109.1",+  "version": "5.109.2",   "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",@@ -107,3 +107,3 @@     "chrome-trace-event": "^1.0.2",-    "enhanced-resolve": "^5.24.2",+    "enhanced-resolve": "^5.24.4",     "es-module-lexer": "^2.1.0",@@ -202,3 +202,3 @@     "toml": "^4.1.1",-    "tooling": "webpack/tooling#v1.26.4",+    "tooling": "webpack/tooling#v1.27.0",     "ts-loader": "^9.6.0",
@babel/core npm
8.0.1 2mo ago nominal
critical-tier BURST ×2
latest 8.0.1 versions 229 maintainers 4 critical-tier (snapshotted)
7.27.4
7.27.7
7.28.0
7.28.3
7.28.4
7.28.5
7.28.6
7.29.0
7.29.6
7.29.7
8.0.0
8.0.1
BURST
2 releases in 33m: 7.22.18, 7.22.19
info · registry-verified · 2023-09-14 · 2y ago
BURST
2 releases in 22m: 7.29.6, 7.29.7
info · registry-verified · 2026-05-25 · 2mo ago
release diff 8.0.0 → 8.0.1
+0 added · -0 removed · ~3 modified
lib/index-shared.js +1 lines
--- +++ @@ -2918,3 +2918,3 @@ -const version = "8.0.0";+const version = "8.0.1"; const resolvePlugin = (name, dirname) => resolvers.resolvePlugin(name, dirname, false).filepath;
package.json +7 lines
--- +++ @@ -2,3 +2,3 @@   "name": "@babel/core",-  "version": "8.0.0",+  "version": "8.0.1",   "description": "Babel compiler core.",@@ -59,8 +59,8 @@     "@babel/helper-transform-fixture-test-runner": "^8.0.0",-    "@babel/plugin-syntax-flow": "^8.0.0",-    "@babel/plugin-syntax-jsx": "^8.0.0",-    "@babel/plugin-transform-flow-strip-types": "^8.0.0",-    "@babel/plugin-transform-modules-commonjs": "^8.0.0",-    "@babel/preset-env": "^8.0.0",-    "@babel/preset-typescript": "^8.0.0",+    "@babel/plugin-syntax-flow": "^8.0.1",+    "@babel/plugin-syntax-jsx": "^8.0.1",+    "@babel/plugin-transform-flow-strip-types": "^8.0.1",+    "@babel/plugin-transform-modules-commonjs": "^8.0.1",+    "@babel/preset-env": "^8.0.1",+    "@babel/preset-typescript": "^8.0.1",     "@cspotcode/source-map-support": "^0.8.1",
babel-loader npm
10.1.1 5mo ago nominal
critical-tier BURST ×6
latest 10.1.1 versions 84 maintainers 4 critical-tier (snapshotted)
9.1.0
8.3.0
9.1.1
9.1.2
9.1.3
8.4.0
9.2.0
8.4.1
9.2.1
10.0.0
10.1.0
10.1.1
BURST
2 releases in 59m: 5.2.1, 5.2.2
info · registry-verified · 2015-06-25 · 11y ago
BURST
2 releases in 8m: 5.4.1, 5.4.2
info · registry-verified · 2016-07-25 · 10y ago
BURST
2 releases in 26m: 9.1.0, 8.3.0
info · registry-verified · 2022-11-03 · 3y ago
BURST
2 releases in 5m: 9.1.1, 9.1.2
info · registry-verified · 2023-01-04 · 3y ago
BURST
2 releases in 1m: 8.4.0, 9.2.0
info · registry-verified · 2024-09-16 · 1y ago
BURST
2 releases in 3m: 8.4.1, 9.2.1
info · registry-verified · 2024-09-16 · 1y ago
release diff 10.1.0 → 10.1.1
+1 added · -0 removed · ~2 modified
lib/cache.js +1 lines
--- +++ @@ -10,3 +10,2 @@  */-const nodeModule = require("node:module"); const os = require("os");@@ -54,10 +53,2 @@ const gzip = promisify(zlib.gzip);-const findRootPackageJSON = () => {-  if (nodeModule.findPackageJSON) {-    return nodeModule.findPackageJSON("..", __filename);-  } else {-    // todo: remove this fallback when dropping support for Node.js < 22.14-    return findUpSync("package.json");-  }-}; @@ -272,3 +263,3 @@   }-  const rootPkgJSONPath = findRootPackageJSON();+  const rootPkgJSONPath = findUpSync("package.json");   if (rootPkgJSONPath) {
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "babel-loader",-  "version": "10.1.0",+  "version": "10.1.1",   "description": "babel module loader for webpack",
@babel/preset-env npm
8.0.2 2mo ago nominal
no findings
latest 8.0.2 versions 212 maintainers 4
7.28.0
7.28.3
7.28.5
7.28.6
7.29.0
7.29.2
7.29.3
7.29.5
7.29.7
8.0.0
8.0.1
8.0.2
CLEAN
no findings — nominal
release diff 8.0.1 → 8.0.2
+0 added · -0 removed · ~1 modified
package.json +4 lines
--- +++ @@ -2,3 +2,3 @@   "name": "@babel/preset-env",-  "version": "8.0.1",+  "version": "8.0.2",   "description": "A Babel preset for each environment.",@@ -67,3 +67,3 @@     "@babel/plugin-transform-property-literals": "^8.0.1",-    "@babel/plugin-transform-regenerator": "^8.0.1",+    "@babel/plugin-transform-regenerator": "^8.0.2",     "@babel/plugin-transform-regexp-modifiers": "^8.0.1",@@ -79,4 +79,4 @@     "@babel/plugin-transform-unicode-sets-regex": "^8.0.1",-    "@babel/preset-modules": "0.1.6-no-external-plugins",-    "babel-plugin-polyfill-corejs3": "^1.0.0-rc.2",+    "@babel/preset-modules": "^0.2.0",+    "babel-plugin-polyfill-corejs3": "^1.0.0",     "core-js-compat": "^3.48.0",
chai npm
6.2.2 8mo ago nominal
BURST ×7
latest 6.2.2 versions 110 maintainers 1
5.2.1
5.2.2
5.3.0
5.3.1
5.3.2
6.0.0
6.0.1
5.3.3
6.1.0
6.2.0
6.2.1
6.2.2
BURST
2 releases in 23m: 0.1.5, 0.1.6
info · registry-verified · 2012-01-02 · 14y ago
BURST
2 releases in 7m: 0.2.2, 0.2.3
info · registry-verified · 2012-02-02 · 14y ago
BURST
2 releases in 35m: 0.3.0, 0.3.1
info · registry-verified · 2012-02-07 · 14y ago
BURST
2 releases in 4m: 4.3.2, 4.3.3
info · registry-verified · 2021-03-03 · 5y ago
BURST
2 releases in 1m: 5.0.2, 5.0.3
info · registry-verified · 2024-01-25 · 2y ago
BURST
3 releases in 9m: 5.2.2, 5.3.0, 5.3.1
info · registry-verified · 2025-08-18 · 1y ago
BURST
2 releases in 29m: 6.0.1, 5.3.3
info · registry-verified · 2025-08-22 · 12mo ago
release diff 6.2.1 → 6.2.2
+0 added · -0 removed · ~2 modified
index.js +3 lines
--- +++ @@ -699,4 +699,4 @@ var symbolsSupported = typeof Symbol === "function" && typeof Symbol.for === "function";-var chaiInspect = symbolsSupported ? Symbol.for("chai/inspect") : "@@chai/inspect";-var nodeInspect = Symbol.for("nodejs.util.inspect.custom");+var chaiInspect = symbolsSupported ? /* @__PURE__ */ Symbol.for("chai/inspect") : "@@chai/inspect";+var nodeInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom"); var constructorMap = /* @__PURE__ */ new WeakMap();@@ -2960,3 +2960,3 @@   new Assertion(expected, flagMsg, ssfi, true).is.numeric;-  const abs = /* @__PURE__ */ __name((x) => x < 0n ? -x : x, "abs");+  const abs = /* @__PURE__ */ __name((x) => x < 0 ? -x : x, "abs");   const strip = /* @__PURE__ */ __name((number) => parseFloat(parseFloat(number).toPrecision(12)), "strip");@@ -4172,246 +4172 @@ };-/*!- * Chai - flag utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - test utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - expectTypes utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - getActual utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - message composition utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - transferFlags utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * chai- * http://chaijs.com- * Copyright(c) 2011-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - events utility- * Copyright(c) 2011-2016 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - isProxyEnabled helper- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - addProperty utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - addLengthGuard utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - getProperties utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - proxify utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - addMethod utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - overwriteProperty utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - overwriteMethod utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - addChainingMethod utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - overwriteChainableMethod utility- * Copyright(c) 2012-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - compareByInspect utility- * Copyright(c) 2011-2016 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - getOwnEnumerablePropertySymbols utility- * Copyright(c) 2011-2016 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - getOwnEnumerableProperties utility- * Copyright(c) 2011-2016 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * Chai - isNaN utility- * Copyright(c) 2012-2015 Sakthipriyan Vairamani <[email protected]>- * MIT Licensed- */-/*!- * chai- * Copyright(c) 2011 Jake Luer <[email protected]>- * MIT Licensed- */-/*!- * chai- * Copyright(c) 2011-2014 Jake Luer <[email protected]>- * MIT Licensed- */-/*! Bundled license information:--deep-eql/index.js:-  (*!-   * deep-eql-   * Copyright(c) 2013 Jake Luer <[email protected]>-   * MIT Licensed-   *)-  (*!-   * Check to see if the MemoizeMap has recorded a result of the two operands-   *-   * @param {Mixed} leftHandOperand-   * @param {Mixed} rightHandOperand-   * @param {MemoizeMap} memoizeMap-   * @returns {Boolean|null} result-  *)-  (*!-   * Set the result of the equality into the MemoizeMap-   *-   * @param {Mixed} leftHandOperand-   * @param {Mixed} rightHandOperand-   * @param {MemoizeMap} memoizeMap-   * @param {Boolean} result-  *)-  (*!-   * Primary Export-   *)-  (*!-   * The main logic of the `deepEqual` function.-   *-   * @param {Mixed} leftHandOperand-   * @param {Mixed} rightHandOperand-   * @param {Object} [options] (optional) Additional options-   * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality.-   * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of-      complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular-      references to blow the stack.-   * @return {Boolean} equal match-  *)-  (*!-   * Compare two Regular Expressions for equality.-   *-   * @param {RegExp} leftHandOperand-   * @param {RegExp} rightHandOperand-   * @return {Boolean} result-   *)-  (*!-   * Compare two Sets/Maps for equality. Faster than other equality functions.-   *-   * @param {Set} leftHandOperand-   * @param {Set} rightHandOperand-   * @param {Object} [options] (Optional)-   * @return {Boolean} result-   *)-  (*!-   * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers.-   *-   * @param {Iterable} leftHandOperand-   * @param {Iterable} rightHandOperand-   * @param {Object} [options] (Optional)-   * @return {Boolean} result-   *)-  (*!-   * Simple equality for generator objects such as those returned by generator functions.-   *-   * @param {Iterable} leftHandOperand-   * @param {Iterable} rightHandOperand-   * @param {Object} [options] (Optional)-   * @return {Boolean} result-   *)-  (*!-   * Determine if the given object has an @@iterator function.-   *-   * @param {Object} target-   * @return {Boolean} `true` if the object has an @@iterator function.-   *)-  (*!-   * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array.-   * This will consume the iterator - which could have side effects depending on the @@iterator implementation.-   *-   * @param {Object} target-   * @returns {Array} an array of entries from the @@iterator function-   *)-  (*!-   * Gets all entries from a Generator. This will consume the generator - which could have side effects.-   *-   * @param {Generator} target-   * @returns {Array} an array of entries from the Generator.-   *)-  (*!-   * Gets all own and inherited enumerable keys from a target.-   *-   * @param {Object} target-   * @returns {Array} an array of own and inherited enumerable keys from the target.-   *)-  (*!-   * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of-   * each key. If any value of the given key is not equal, the function will return false (early).-   *-   * @param {Mixed} leftHandOperand-   * @param {Mixed} rightHandOperand-   * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against-   * @param {Object} [options] (Optional)-   * @return {Boolean} result-   *)-  (*!-   * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual`-   * for each enumerable key in the object.-   *-   * @param {Mixed} leftHandOperand-   * @param {Mixed} rightHandOperand-   * @param {Object} [options] (Optional)-   * @return {Boolean} result
… 11 more lines (truncated)
package.json +2 lines
--- +++ @@ -24,3 +24,3 @@   ],-  "version": "6.2.1",+  "version": "6.2.2",   "repository": {@@ -34,3 +34,3 @@   "scripts": {-    "build": "esbuild --bundle --format=esm --target=es2021 --keep-names --outfile=index.js lib/chai.js",+    "build": "esbuild --bundle --format=esm --target=es2021 --keep-names --legal-comments=none --outfile=index.js lib/chai.js",     "prebuild": "npm run clean",
jest npm
30.4.2 3mo ago nominal
critical-tier BURST ×8
latest 30.4.2 versions 380 maintainers 5 critical-tier (snapshotted)
30.0.3
30.0.4
30.0.5
30.1.0
30.1.1
30.1.2
30.1.3
30.2.0
30.3.0
30.4.0
30.4.1
30.4.2
BURST
2 releases in 1m: 0.0.7, 0.0.61
info · registry-verified · 2012-03-05 · 14y ago
BURST
2 releases in 19m: 0.0.86, 0.0.87
info · registry-verified · 2012-04-30 · 14y ago
BURST
2 releases in 4m: 0.0.90, 0.0.91
info · registry-verified · 2012-05-06 · 14y ago
BURST
2 releases in 7m: 12.1.0, 12.1.1
info · registry-verified · 2016-05-20 · 10y ago
BURST
3 releases in 36m: 13.1.2, 13.1.3, 13.2.0
info · registry-verified · 2016-07-07 · 10y ago
BURST
2 releases in 13m: 13.2.1, 13.2.2
info · registry-verified · 2016-07-07 · 10y ago
BURST
2 releases in 7m: 20.0.2, 20.0.3
info · registry-verified · 2017-05-17 · 9y ago
BURST
2 releases in 28m: 29.1.0, 29.1.1
info · registry-verified · 2022-09-28 · 3y ago
release diff 30.4.1 → 30.4.2
+0 added · -0 removed · ~1 modified
package.json +4 lines
--- +++ @@ -3,3 +3,3 @@   "description": "Delightful JavaScript Testing.",-  "version": "30.4.1",+  "version": "30.4.2",   "main": "./build/index.js",@@ -17,6 +17,6 @@   "dependencies": {-    "@jest/core": "30.4.1",+    "@jest/core": "30.4.2",     "@jest/types": "30.4.1",     "import-local": "^3.2.0",-    "jest-cli": "30.4.1"+    "jest-cli": "30.4.2"   },@@ -70,3 +70,3 @@   },-  "gitHead": "b3b4a09ed3005369dacc7466d1d2122797283785"+  "gitHead": "746f2a0f57c56e3bba555280f0587d40f3db95c0" }
lodash npm
4.18.1 4mo ago nominal
BURST ×4
latest 4.18.1 versions 117 maintainers 1
4.17.13
4.17.14
4.17.15
4.17.16
4.17.17
4.17.18
4.17.19
4.17.20
4.17.21
4.17.23
4.18.0
4.18.1
BURST
6 releases in 30m: 0.9.0, 0.9.1, 0.9.2, 0.10.0, 1.0.0, 1.0.1
info · registry-verified · 2013-08-31 · 12y ago
BURST
6 releases in 2m: 1.1.0, 1.1.1, 1.2.0, 1.2.1, 1.3.0, 1.3.1
info · registry-verified · 2013-09-04 · 12y ago
BURST
2 releases in 49m: 4.8.0, 4.8.1
info · registry-verified · 2016-04-04 · 10y ago
BURST
2 releases in 23m: 4.17.9, 4.17.10
info · registry-verified · 2018-04-24 · 8y ago
release diff 4.18.0 → 4.18.1
+0 added · -0 removed · ~9 modified
_baseUnset.js +0 lines
--- +++ @@ -25,3 +25,2 @@   // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh-  // https://github.com/lodash/lodash/security/advisories/GHSA-w36w-cm3g-pc62   var index = -1,
core.js +2 lines
--- +++ @@ -3,3 +3,3 @@  * Lodash (Custom Build) <https://lodash.com/>- * Build: `lodash core -o ./core.js`+ * Build: `lodash core --repo lodash/lodash#4.18.1 -o ./core.js`  * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>@@ -15,3 +15,3 @@   /** Used as the semantic version number. */-  var VERSION = '4.18.0';+  var VERSION = '4.18.1'; 
fromPairs.js +2 lines
--- +++ @@ -1 +1,3 @@+var baseAssignValue = require('./_baseAssignValue');+ /**
lodash.js +1 lines
--- +++ @@ -14,3 +14,3 @@   /** Used as the semantic version number. */-  var VERSION = '4.18.0';+  var VERSION = '4.18.1'; @@ -4381,3 +4381,2 @@       // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh-      // https://github.com/lodash/lodash/security/advisories/GHSA-w36w-cm3g-pc62       var index = -1,
package.json +4 lines
--- +++ @@ -2,3 +2,3 @@   "name": "lodash",-  "version": "4.18.0",+  "version": "4.18.1",   "description": "Lodash modular utilities.",@@ -15,3 +15,5 @@   ],-  "scripts": { "test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\"" }+  "scripts": {+    "test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""+  } }
template.js +3 lines
--- +++ @@ -1,2 +1,4 @@-var attempt = require('./attempt'),+var arrayEach = require('./_arrayEach'),+    assignWith = require('./assignWith'),+    attempt = require('./attempt'),     baseValues = require('./_baseValues'),
prettier npm
3.9.6 1mo ago nominal
critical-tier BURST ×8
latest 3.9.6 versions 195 maintainers 11 critical-tier (snapshotted)
3.8.1
3.8.2
3.8.3
3.8.4
3.8.5
3.9.0
3.9.1
3.9.2
3.9.3
3.9.4
3.9.5
3.9.6
BURST
2 releases in 46m: 0.0.1, 0.0.2
info · registry-verified · 2017-01-10 · 9y ago
BURST
2 releases in 15m: 0.14.0, 0.14.1
info · registry-verified · 2017-01-30 · 9y ago
BURST
3 releases in 48m: 1.0.0, 1.0.1, 1.0.2
info · registry-verified · 2017-04-13 · 9y ago
BURST
2 releases in 58m: 1.2.0, 1.2.1
info · registry-verified · 2017-04-19 · 9y ago
BURST
2 releases in 50m: 1.4.3, 1.4.4
info · registry-verified · 2017-06-07 · 9y ago
BURST
2 releases in 19m: 1.10.0, 1.10.1
info · registry-verified · 2018-01-10 · 8y ago
BURST
2 releases in 9m: 1.13.1, 1.13.2
info · registry-verified · 2018-05-29 · 8y ago
BURST
2 releases in 9m: 3.9.2, 3.9.3
info · registry-verified · 2026-06-29 · 1mo ago
release diff 3.9.5 → 3.9.6
+0 added · -0 removed · ~21 modified
+19 more files not shown
plugins/acorn.js +10 lines · 2 flagged
--- +++ @@ -1,8 +1,8 @@-(function(n){function e(){var i=n();return i.default||i}if(typeof exports=="object"&&typeof module=="object")module.exports=e();else if(typeof define=="function"&&define.amd)define(e);else{var t=typeof globalThis<"u"?globalThis:typeof global<"u"?global:typeof self<"u"?self:this||{};t.prettierPlugins=t.prettierPlugins||{},t.prettierPlugins.acorn=e()}})(function(){"use strict";var Bi=Object.create;var me=Object.defineProperty;var Fi=Object.getOwnPropertyDescriptor;var ji=Object.getOwnPropertyNames;var Ui=Object.getPrototypeOf,Gi=Object.prototype.hasOwnProperty;var ct=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(i){throw t=0,i}},Be=(e,t)=>{for(var i in t)me(e,i,{get:t[i],enumerable:!0})},pt=(e,t,i,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ji(t))!Gi.call(e,s)&&s!==i&&me(e,s,{get:()=>t[s],enumerable:!(r=Fi(t,s))||r.enumerable});return e};var lt=(e,t,i)=>(i=e!=null?Bi(Ui(e)):{},pt(t||!e||!e.__esModule?me(i,"default",{value:e,enumerable:!0}):i,e)),Wi=e=>pt(me({},"__esModule",{value:!0}),e);var ii=ct((Ns,ti)=>{ti.exports={}});var et=ct((Ls,$e)=>{"use strict";var wr=ii(),Ir=/^[\da-fA-F]+$/,Pr=/^\d+$/,ri=new WeakMap;function si(e){e=e.Parser.acorn||e;let t=ri.get(e);if(!t){let i=e.tokTypes,r=e.TokContext,s=e.TokenType,n=new r("<tag",!1),o=new r("</tag",!1),c=new r("<tag>...</tag>",!0,!0),h={tc_oTag:n,tc_cTag:o,tc_expr:c},l={jsxName:new s("jsxName"),jsxText:new s("jsxText",{beforeExpr:!0}),jsxTagStart:new s("jsxTagStart",{startsExpr:!0}),jsxTagEnd:new s("jsxTagEnd")};l.jsxTagStart.updateContext=function(){this.context.push(c),this.context.push(n),this.exprAllowed=!1},l.jsxTagEnd.updateContext=function(m){let S=this.context.pop();S===n&&m===i.slash||S===o?(this.context.pop(),this.exprAllowed=this.curContext()===c):this.exprAllowed=!0},t={tokContexts:h,tokTypes:l},ri.set(e,t)}return t}function pe(e){if(!e)return e;if(e.type==="JSXIdentifier")return e.name;if(e.type==="JSXNamespacedName")return e.namespace.name+":"+e.name.name;if(e.type==="JSXMemberExpression")return pe(e.object)+"."+pe(e.property)}$e.exports=function(e){return e=e||{},function(t){return Nr({allowNamespaces:e.allowNamespaces!==!1,allowNamespacedObjects:!!e.allowNamespacedObjects},t)}};Object.defineProperty($e.exports,"tokTypes",{get:function(){return si(void 0).tokTypes},configurable:!0,enumerable:!0});function Nr(e,t){let i=t.acorn||void 0,r=si(i),s=i.tokTypes,n=r.tokTypes,o=i.tokContexts,c=r.tokContexts.tc_oTag,h=r.tokContexts.tc_cTag,l=r.tokContexts.tc_expr,m=i.isNewLine,S=i.isIdentifierStart,k=i.isIdentifierChar;return class extends t{static get acornJsx(){return r}jsx_readToken(){let p="",x=this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated JSX contents");let y=this.input.charCodeAt(this.pos);switch(y){case 60:case 123:return this.pos===this.start?y===60&&this.exprAllowed?(++this.pos,this.finishToken(n.jsxTagStart)):this.getTokenFromCode(y):(p+=this.input.slice(x,this.pos),this.finishToken(n.jsxText,p));case 38:p+=this.input.slice(x,this.pos),p+=this.jsx_readEntity(),x=this.pos;break;case 62:case 125:this.raise(this.pos,"Unexpected token `"+this.input[this.pos]+"`. Did you mean `"+(y===62?"&gt;":"&rbrace;")+'` or `{"'+this.input[this.pos]+'"}`?');default:m(y)?(p+=this.input.slice(x,this.pos),p+=this.jsx_readNewLine(!0),x=this.pos):++this.pos}}}jsx_readNewLine(p){let x=this.input.charCodeAt(this.pos),y;return++this.pos,x===13&&this.input.charCodeAt(this.pos)===10?(++this.pos,y=p?`+(function(n){function e(){var i=n();return i.default||i}if(typeof exports=="object"&&typeof module=="object")module.exports=e();else if(typeof define=="function"&&define.amd)define(e);else{var t=typeof globalThis<"u"?globalThis:typeof global<"u"?global:typeof self<"u"?self:this||{};t.prettierPlugins=t.prettierPlugins||{},t.prettierPlugins.acorn=e()}})(function(){"use strict";var Bi=Object.create;var me=Object.defineProperty;var Fi=Object.getOwnPropertyDescriptor;var ji=Object.getOwnPropertyNames;var Ui=Object.getPrototypeOf,Gi=Object.prototype.hasOwnProperty;var ct=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(i){throw t=0,i}},Be=(e,t)=>{for(var i in t)me(e,i,{get:t[i],enumerable:!0})},pt=(e,t,i,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ji(t))!Gi.call(e,s)&&s!==i&&me(e,s,{get:()=>t[s],enumerable:!(r=Fi(t,s))||r.enumerable});return e};var lt=(e,t,i)=>(i=e!=null?Bi(Ui(e)):{},pt(t||!e||!e.__esModule?me(i,"default",{value:e,enumerable:!0}):i,e)),Wi=e=>pt(me({},"__esModule",{value:!0}),e);var ii=ct((Ns,ti)=>{ti.exports={}});var et=ct((Ls,$e)=>{"use strict";var wr=ii(),Ir=/^[\da-fA-F]+$/,Pr=/^\d+$/,ri=new WeakMap;function si(e){e=e.Parser.acorn||e;let t=ri.get(e);if(!t){let i=e.tokTypes,r=e.TokContext,s=e.TokenType,n=new r("<tag",!1),o=new r("</tag",!1),h=new r("<tag>...</tag>",!0,!0),c={tc_oTag:n,tc_cTag:o,tc_expr:h},l={jsxName:new s("jsxName"),jsxText:new s("jsxText",{beforeExpr:!0}),jsxTagStart:new s("jsxTagStart",{startsExpr:!0}),jsxTagEnd:new s("jsxTagEnd")};l.jsxTagStart.updateContext=function(){this.context.push(h),this.context.push(n),this.exprAllowed=!1},l.jsxTagEnd.updateContext=function(m){let S=this.context.pop();S===n&&m===i.slash||S===o?(this.context.pop(),this.exprAllowed=this.curContext()===h):this.exprAllowed=!0},t={tokContexts:c,tokTypes:l},ri.set(e,t)}return t}function pe(e){if(!e)return e;if(e.type==="JSXIdentifier")return e.name;if(e.type==="JSXNamespacedName")return e.namespace.name+":"+e.name.name;if(e.type==="JSXMemberExpression")return pe(e.object)+"."+pe(e.property)}$e.exports=function(e){return e=e||{},function(t){return Nr({allowNamespaces:e.allowNamespaces!==!1,allowNamespacedObjects:!!e.allowNamespacedObjects},t)}};Object.defineProperty($e.exports,"tokTypes",{get:function(){return si(void 0).tokTypes},configurable:!0,enumerable:!0});function Nr(e,t){let i=t.acorn||void 0,r=si(i),s=i.tokTypes,n=r.tokTypes,o=i.tokContexts,h=r.tokContexts.tc_oTag,c=r.tokContexts.tc_cTag,l=r.tokContexts.tc_expr,m=i.isNewLine,S=i.isIdentifierStart,E=i.isIdentifierChar;return class extends t{static get acornJsx(){return r}jsx_readToken(){let p="",x=this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated JSX contents");let y=this.input.charCodeAt(this.pos);switch(y){case 60:case 123:return this.pos===this.start?y===60&&this.exprAllowed?(++this.pos,this.finishToken(n.jsxTagStart)):this.getTokenFromCode(y):(p+=this.input.slice(x,this.pos),this.finishToken(n.jsxText,p));case 38:p+=this.input.slice(x,this.pos),p+=this.jsx_readEntity(),x=this.pos;break;case 62:case 125:this.raise(this.pos,"Unexpected token `"+this.input[this.pos]+"`. Did you mean `"+(y===62?"&gt;":"&rbrace;")+'` or `{"'+this.input[this.pos]+'"}`?');default:m(y)?(p+=this.input.slice(x,this.pos),p+=this.jsx_readNewLine(!0),x=this.pos):++this.pos}}}jsx_readNewLine(p){let x=this.input.charCodeAt(this.pos),y;return++this.pos,x===13&&this.input.charCodeAt(this.pos)===10?(++this.pos,y=p?` `:`\r-`):y=String.fromCharCode(x),this.options.locations&&(++this.curLine,this.lineStart=this.pos),y}jsx_readString(p){let x="",y=++this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");let v=this.input.charCodeAt(this.pos);if(v===p)break;v===38?(x+=this.input.slice(y,this.pos),x+=this.jsx_readEntity(),y=this.pos):m(v)?(x+=this.input.slice(y,this.pos),x+=this.jsx_readNewLine(!1),y=this.pos):++this.pos}return x+=this.input.slice(y,this.pos++),this.finishToken(s.string,x)}jsx_readEntity(){let p="",x=0,y,v=this.input[this.pos];v!=="&"&&this.raise(this.pos,"Entity must start with an ampersand");let N=++this.pos;for(;this.pos<this.input.length&&x++<10;){if(v=this.input[this.pos++],v===";"){p[0]==="#"?p[1]==="x"?(p=p.substr(2),Ir.test(p)&&(y=String.fromCharCode(parseInt(p,16)))):(p=p.substr(1),Pr.test(p)&&(y=String.fromCharCode(parseInt(p,10)))):y=wr[p];break}p+=v}return y||(this.pos=N,"&")}jsx_readWord(){let p,x=this.pos;do p=this.input.charCodeAt(++this.pos);while(k(p)||p===45);return this.finishToken(n.jsxName,this.input.slice(x,this.pos))}jsx_parseIdentifier(){let p=this.startNode();return this.type===n.jsxName?p.name=this.value:this.type.keyword?p.name=this.type.keyword:this.unexpected(),this.next(),this.finishNode(p,"JSXIdentifier")}jsx_parseNamespacedName(){let p=this.start,x=this.startLoc,y=this.jsx_parseIdentifier();if(!e.allowNamespaces||!this.eat(s.colon))return y;var v=this.startNodeAt(p,x);return v.namespace=y,v.name=this.jsx_parseIdentifier(),this.finishNode(v,"JSXNamespacedName")}jsx_parseElementName(){if(this.type===n.jsxTagEnd)return"";let p=this.start,x=this.startLoc,y=this.jsx_parseNamespacedName();for(this.type===s.dot&&y.type==="JSXNamespacedName"&&!e.allowNamespacedObjects&&this.unexpected();this.eat(s.dot);){let v=this.startNodeAt(p,x);v.object=y,v.property=this.jsx_parseIdentifier(),y=this.finishNode(v,"JSXMemberExpression")}return y}jsx_parseAttributeValue(){switch(this.type){case s.braceL:let p=this.jsx_parseExpressionContainer();return p.expression.type==="JSXEmptyExpression"&&this.raise(p.start,"JSX attributes must only be assigned a non-empty expression"),p;case n.jsxTagStart:case s.string:return this.parseExprAtom();default:this.raise(this.start,"JSX value should be either an expression or a quoted JSX text")}}jsx_parseEmptyExpression(){let p=this.startNodeAt(this.lastTokEnd,this.lastTokEndLoc);return this.finishNodeAt(p,"JSXEmptyExpression",this.start,this.startLoc)}jsx_parseExpressionContainer(){let p=this.startNode();return this.next(),p.expression=this.type===s.braceR?this.jsx_parseEmptyExpression():this.parseExpression(),this.expect(s.braceR),this.finishNode(p,"JSXExpressionContainer")}jsx_parseAttribute(){let p=this.startNode();return this.eat(s.braceL)?(this.expect(s.ellipsis),p.argument=this.parseMaybeAssign(),this.expect(s.braceR),this.finishNode(p,"JSXSpreadAttribute")):(p.name=this.jsx_parseNamespacedName(),p.value=this.eat(s.eq)?this.jsx_parseAttributeValue():null,this.finishNode(p,"JSXAttribute"))}jsx_parseOpeningElementAt(p,x){let y=this.startNodeAt(p,x);y.attributes=[];let v=this.jsx_parseElementName();for(v&&(y.name=v);this.type!==s.slash&&this.type!==n.jsxTagEnd;)y.attributes.push(this.jsx_parseAttribute());return y.selfClosing=this.eat(s.slash),this.expect(n.jsxTagEnd),this.finishNode(y,v?"JSXOpeningElement":"JSXOpeningFragment")}jsx_parseClosingElementAt(p,x){let y=this.startNodeAt(p,x),v=this.jsx_parseElementName();return v&&(y.name=v),this.expect(n.jsxTagEnd),this.finishNode(y,v?"JSXClosingElement":"JSXClosingFragment")}jsx_parseElementAt(p,x){let y=this.startNodeAt(p,x),v=[],N=this.jsx_parseOpeningElementAt(p,x),de=null;if(!N.selfClosing){e:for(;;)switch(this.type){case n.jsxTagStart:if(p=this.start,x=this.startLoc,this.next(),this.eat(s.slash)){de=this.jsx_parseClosingElementAt(p,x);break e}v.push(this.jsx_parseElementAt(p,x));break;case n.jsxText:v.push(this.parseExprAtom());break;case s.braceL:v.push(this.jsx_parseExpressionContainer());break;default:this.unexpected()}pe(de.name)!==pe(N.name)&&this.raise(de.start,"Expected corresponding JSX closing tag for <"+pe(N.name)+">")}let Me=N.name?"Element":"Fragment";return y["opening"+Me]=N,y["closing"+Me]=de,y.children=v,this.type===s.relational&&this.value==="<"&&this.raise(this.start,"Adjacent JSX elements must be wrapped in an enclosing tag"),this.finishNode(y,"JSX"+Me)}jsx_parseText(){let p=this.parseLiteral(this.value);return p.type="JSXText",p}jsx_parseElement(){let p=this.start,x=this.startLoc;return this.next(),this.jsx_parseElementAt(p,x)}parseExprAtom(p){return this.type===n.jsxText?this.jsx_parseText():this.type===n.jsxTagStart?this.jsx_parseElement():super.parseExprAtom(p)}readToken(p){let x=this.curContext();if(x===l)return this.jsx_readToken();if(x===c||x===h){if(S(p))return this.jsx_readWord();if(p==62)return++this.pos,this.finishToken(n.jsxTagEnd);if((p===34||p===39)&&x==c)return this.jsx_readString(p)}return p===60&&this.exprAllowed&&this.input.charCodeAt(this.pos+1)!==33?(++this.pos,this.finishToken(n.jsxTagStart)):super.readToken(p)}updateContext(p){if(this.type==s.braceL){var x=this.curContext();x==c?this.context.push(o.b_expr):x==l?this.context.push(o.b_tmpl):super.updateContext(p),this.exprAllowed=!0}else if(this.type===s.slash&&p===n.jsxTagStart)this.context.length-=2,this.context.push(h),this.exprAllowed=!1;else return super.updateContext(p)}}}});var Is={};Be(Is,{parsers:()=>ws});var nt={};Be(nt,{acorn:()=>ys});var qi=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,7,9,32,4,318,1,78,5,71,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,3,0,158,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,68,8,2,0,3,0,2,3,2,4,2,0,15,1,83,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,7,19,58,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,199,7,137,9,54,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,55,9,266,3,10,1,2,0,49,6,4,4,14,10,5350,0,7,14,11465,27,2343,9,87,9,39,4,60,6,26,9,535,9,470,0,2,54,8,3,82,0,12,1,19628,1,4178,9,519,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,101,0,161,6,10,9,357,0,62,13,499,13,245,1,2,9,233,0,3,0,8,1,6,0,475,6,110,6,6,9,4759,9,787719,239],gt=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,4,51,13,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,7,25,39,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,39,27,10,22,251,41,7,1,17,5,57,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,20,1,64,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,31,9,2,0,3,0,2,37,2,0,26,0,2,0,45,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,200,32,32,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,24,43,261,18,16,0,2,12,2,33,125,0,80,921,103,110,18,195,2637,96,16,1071,18,5,26,3994,6,582,6842,29,1763,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,433,44,212,63,33,24,3,24,45,74,6,0,67,12,65,1,2,0,15,4,10,7381,42,31,98,114,8702,3,2,6,2,1,2,290,16,0,30,2,3,0,15,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,7,5,262,61,147,44,11,6,17,0,322,29,19,43,485,27,229,29,3,0,208,30,2,2,2,1,2,6,3,4,10,1,225,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4381,3,5773,3,7472,16,621,2467,541,1507,4938,6,8489],Hi="\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0897-\u089F\u08CA-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3C\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0CF3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECE\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u180F-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1ABF-\u1ADD\u1AE0-\u1AEB\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\u30FB\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F\uFF65",vt="\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC",Fe={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},je="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",Ki={5:je,"5module":je+" export import",6:je+" const class extends export import super"},bt=/^in(stanceof)?$/,Ji=new RegExp("["+vt+"]"),Xi=new RegExp("["+vt+Hi+"]");function Ge(e,t){for(var i=65536,r=0;r<t.length;r+=2){if(i+=t[r],i>e)return!1;if(i+=t[r+1],i>=e)return!0}return!1}function j(e,t){return e<65?e===36:e<91?!0:e<97?e===95:e<123?!0:e<=65535?e>=170&&Ji.test(String.fromCharCode(e)):t===!1?!1:Ge(e,gt)}function K(e,t){return e<48?e===36:e<58?!0:e<65?!1:e<91?!0:e<97?e===95:e<123?!0:e<=65535?e>=170&&Xi.test(String.fromCharCode(e)):t===!1?!1:Ge(e,gt)||Ge(e,qi)}var _=function(t,i){i===void 0&&(i={}),this.label=t,this.keyword=i.keyword,this.beforeExpr=!!i.beforeExpr,this.startsExpr=!!i.startsExpr,this.isLoop=!!i.isLoop,this.isAssign=!!i.isAssign,this.prefix=!!i.prefix,this.postfix=!!i.postfix,this.binop=i.binop||null,this.updateContext=null};function V(e,t){return new _(e,{beforeExpr:!0,binop:t})}var O={beforeExpr:!0},L={startsExpr:!0},Ke={};function C(e,t){return t===void 0&&(t={}),t.keyword=e,Ke[e]=new _(e,t)}var a={num:new _("num",L),regexp:new _("regexp",L),string:new _("string",L),name:new _("name",L),privateId:new _("privateId",L),eof:new _("eof"),bracketL:new _("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new _("]"),braceL:new _("{",{beforeExpr:!0,startsExpr:!0}),braceR:new _("}"),parenL:new _("(",{beforeExpr:!0,startsExpr:!0}),parenR:new _(")"),comma:new _(",",O),semi:new _(";",O),colon:new _(":",O),dot:new _("."),question:new _("?",O),questionDot:new _("?."),arrow:new _("=>",O),template:new _("template"),invalidTemplate:new _("invalidTemplate"),ellipsis:new _("...",O),backQuote:new _("`",L),dollarBraceL:new _("${",{beforeExpr:!0,startsExpr:!0}),eq:new _("=",{beforeExpr:!0,isAssign:!0}),assign:new _("_=",{beforeExpr:!0,isAssign:!0}),incDec:new _("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new _("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:V("||",1),logicalAND:V("&&",2),bitwiseOR:V("|",3),bitwiseXOR:V("^",4),bitwiseAND:V("&",5),equality:V("==/!=/===/!==",6),relational:V("</>/<=/>=",7),bitShift:V("<</>>/>>>",8),plusMin:new _("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:V("%",10),star:V("*",10),slash:V("/",10),starstar:new _("**",{beforeExpr:!0}),coalesce:V("??",1),_break:C("break"),_case:C("case",O),_catch:C("catch"),_continue:C("continue"),_debugger:C("debugger"),_default:C("default",O),_do:C("do",{isLoop:!0,beforeExpr:!0}),_else:C("else",O),_finally:C("finally"),_for:C("for",{isLoop:!0}),_function:C("function",L),_if:C("if"),_return:C("return",O),_switch:C("switch"),_throw:C("throw",O),_try:C("try"),_var:C("var"),_const:C("const"),_while:C("while",{isLoop:!0}),_with:C("with"),_new:C("new",{beforeExpr:!0,startsExpr:!0}),_this:C("this",L),_super:C("super",L),_class:C("class",L),_extends:C("extends",O),_export:C("export"),_import:C("import",L),_null:C("null",L),_true:C("true",L),_false:C("false",L),_in:C("in",{beforeExpr:!0,binop:7}),_instanceof:C("instanceof",{beforeExpr:!0,binop:7}),_typeof:C("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:C("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:C("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},R=/\r\n?|\n|\u2028|\u2029/,zi=new RegExp(R.source,"g");function ee(e){return e===10||e===13||e===8232||e===8233}function St(e,t,i){i===void 0&&(i=e.length);for(var r=t;r<i;r++){var s=e.charCodeAt(r);if(ee(s))return r<i-1&&s===13&&e.charCodeAt(r+1)===10?r+2:r+1}return-1}var Ct=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/,A=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,_t=Object.prototype,Qi=_t.hasOwnProperty,Yi=_t.toString,te=Object.hasOwn||(function(e,t){return Qi.call(e,t)}),ft=Array.isArray||(function(e){return Yi.call(e)==="[object Array]"}),dt=Object.create(null);function H(e){return dt[e]||(dt[e]=new RegExp("^(?:"+e.replace(/ /g,"|")+")$"))}function G(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode((e>>10)+55296,(e&1023)+56320))}var Zi=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,ue=function(t,i){this.line=t,this.column=i};ue.prototype.offset=function(t){return new ue(this.line,this.column+t)};var Se=function(t,i,r){this.start=i,this.end=r,t.sourceFile!==null&&(this.source=t.sourceFile)};function Et(e,t){for(var i=1,r=0;;){var s=St(e,r,t);if(s<0)return new ue(i,t-r);++i,r=s}}var We={ecmaVersion:null,sourceType:"script",strict:!1,onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,checkPrivateFields:!0,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},mt=!1;function $i(e){var t={};for(var i in We)t[i]=e&&te(e,i)?e[i]:We[i];if(t.ecmaVersion==="latest"?t.ecmaVersion=1e8:t.ecmaVersion==null?(!mt&&typeof console=="object"&&console.warn&&(mt=!0,console.warn(`Since Acorn 8.0.0, options.ecmaVersion is required.-Defaulting to 2020, but this will stop working in the future.`)),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),t.allowReserved==null&&(t.allowReserved=t.ecmaVersion<5),(!e||e.allowHashBang==null)&&(t.allowHashBang=t.ecmaVersion>=14),ft(t.onToken)){var r=t.onToken;t.onToken=function(s){return r.push(s)}}if(ft(t.onComment)&&(t.onComment=er(t,t.onComment)),t.sourceType==="commonjs"&&t.allowAwaitOutsideFunction)throw new Error("Cannot use allowAwaitOutsideFunction with sourceType: commonjs");return t}function er(e,t){return function(i,r,s,n,o,c){var h={type:i?"Block":"Line",value:r,start:s,end:n};e.locations&&(h.loc=new Se(this,o,c)),e.ranges&&(h.range=[s,n]),t.push(h)}}var X=1,z=2,Je=4,kt=8,Xe=16,Tt=32,Ce=64,At=128,Q=256,he=512,wt=1024,_e=X|z|Q;function ze(e,t){return z|(e?Je:0)|(t?kt:0)}var ye=0,Qe=1,q=2,It=3,Pt=4,Nt=5,T=function(t,i,r){this.options=t=$i(t),this.sourceFile=t.sourceFile,this.keywords=H(Ki[t.ecmaVersion>=6?6:t.sourceType==="module"?"5module":5]);var s="";t.allowReserved!==!0&&(s=Fe[t.ecmaVersion>=6?6:t.ecmaVersion===5?5:3],t.sourceType==="module"&&(s+=" await")),this.reservedWords=H(s);var n=(s?s+" ":"")+Fe.strict;this.reservedWordsStrict=H(n),this.reservedWordsStrictBind=H(n+" "+Fe.strictBind),this.input=String(i),this.containsEsc=!1,r?(this.pos=r,this.lineStart=this.input.lastIndexOf(`-`,r-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(R).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=a.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule=t.sourceType==="module",this.strict=this.inModule||t.strict===!0||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),this.pos===0&&t.allowHashBang&&this.input.slice(0,2)==="#!"&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(this.options.sourceType==="commonjs"?z:X),this.regexpState=null,this.privateNameStack=[]},M={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowReturn:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},allowUsing:{configurable:!0},inClassStaticBlock:{configurable:!0}};T.prototype.parse=function(){var t=this,i=this.options.program||this.startNode();return this.nextToken(),this.catchStackOverflow(function(){return t.parseTopLevel(i)})};M.inFunction.get=function(){return(this.currentVarScope().flags&z)>0};M.inGenerator.get=function(){return(this.currentVarScope().flags&kt)>0};M.inAsync.get=function(){return(this.currentVarScope().flags&Je)>0};M.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e],i=t.flags;if(i&(Q|he))return!1;if(i&z)return(i&Je)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction};M.allowReturn.get=function(){return!!(this.inFunction||this.options.allowReturnOutsideFunction&&this.currentVarScope().flags&X)};M.allowSuper.get=function(){var e=this.currentThisScope(),t=e.flags;return(t&Ce)>0||this.options.allowSuperOutsideMethod};M.allowDirectSuper.get=function(){return(this.currentThisScope().flags&At)>0};M.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())};M.allowNewDotTarget.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e],i=t.flags;if(i&(Q|he)||i&z&&!(i&Xe))return!0}return!1};M.allowUsing.get=function(){var e=this.currentScope(),t=e.flags;return!(t&wt||!this.inModule&&t&X)};M.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&Q)>0};T.extend=function(){for(var t=[],i=arguments.length;i--;)t[i]=arguments[i];for(var r=this,s=0;s<t.length;s++)r=t[s](r);return r};T.parse=function(t,i){return new this(i,t).parse()};T.parseExpressionAt=function(t,i,r){var s=new this(r,t,i);return s.nextToken(),s.parseExpression()};T.tokenizer=function(t,i){return new this(i,t)};Object.defineProperties(T.prototype,M);var P=T.prototype,tr=/^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/;P.strictDirective=function(e){if(this.options.ecmaVersion<5)return!1;for(;;){A.lastIndex=e,e+=A.exec(this.input)[0].length;var t=tr.exec(this.input.slice(e));if(!t)return!1;if((t[1]||t[2])==="use strict"){A.lastIndex=e+t[0].length;var i=A.exec(this.input),r=i.index+i[0].length,s=this.input.charAt(r);return s===";"||s==="}"||R.test(i[0])&&!(/[(`.[+\-/*%<>=,?^&]/.test(s)||s==="!"&&this.input.charAt(r+1)==="=")}e+=t[0].length,A.lastIndex=e,e+=A.exec(this.input)[0].length,this.input[e]===";"&&e++}};P.eat=function(e){return this.type===e?(this.next(),!0):!1};P.isContextual=function(e){return this.type===a.name&&this.value===e&&!this.containsEsc};P.eatContextual=function(e){return this.isContextual(e)?(this.next(),!0):!1};P.catchStackOverflow=function(e){try{return e()}catch(t){if(t instanceof Error&&(/\bstack\b.*\b(exceeded|overflow)\b/i.test(t.message)||/\btoo much recursion\b/i.test(t.message)))this.raise(this.start,"Not enough stack space to parse input");else throw t}};P.expectContextual=function(e){this.eatContextual(e)||this.unexpected()};P.canInsertSemicolon=function(){return this.type===a.eof||this.type===a.braceR||R.test(this.input.slice(this.lastTokEnd,this.start))};P.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0};P.semicolon=function(){!this.eat(a.semi)&&!this.insertSemicolon()&&this.unexpected()};P.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0};P.expect=function(e){this.eat(e)||this.unexpected()};P.unexpected=function(e){this.raise(e??this.start,"Unexpected token")};var Ee=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};P.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var i=t?e.parenthesizedAssign:e.parenthesizedBind;i>-1&&this.raiseRecoverable(i,t?"Assigning to rvalue":"Parenthesized pattern")}};P.checkExpressionErrors=function(e,t){if(!e)return!1;var i=e.shorthandAssign,r=e.doubleProto;if(!t)return i>=0||r>=0;i>=0&&this.raise(i,"Shorthand property assignments are valid only in destructuring patterns"),r>=0&&this.raiseRecoverable(r,"Redefinition of __proto__ property")};P.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos<this.awaitPos)&&this.raise(this.yieldPos,"Yield expression cannot be a default value"),this.awaitPos&&this.raise(this.awaitPos,"Await expression cannot be a default value")};P.isSimpleAssignTarget=function(e){return e.type==="ParenthesizedExpression"?this.isSimpleAssignTarget(e.expression):e.type==="Identifier"||e.type==="MemberExpression"};var d=T.prototype;d.parseTopLevel=function(e){var t=Object.create(null);for(e.body||(e.body=[]);this.type!==a.eof;){var i=this.parseStatement(null,!0,t);e.body.push(i)}if(this.inModule)for(var r=0,s=Object.keys(this.undefinedExports);r<s.length;r+=1){var n=s[r];this.raiseRecoverable(this.undefinedExports[n].start,"Export '"+n+"' is not defined")}return this.adaptDirectivePrologue(e.body),this.next(),e.sourceType=this.options.sourceType==="commonjs"?"script":this.options.sourceType,this.finishNode(e,"Program")};var Ye={kind:"loop"},ir={kind:"switch"};d.isLet=function(e){if(this.options.ecmaVersion<6||!this.isContextual("let"))return!1;A.lastIndex=this.pos;var t=A.exec(this.input),i=this.pos+t[0].length,r=this.fullCharCodeAt(i);if(r===91||r===92)return!0;if(e)return!1;if(r===123)return!0;if(j(r)){var s=i;do i+=r<=65535?1:2;while(K(r=this.fullCharCodeAt(i)));if(r===92)return!0;var n=this.input.slice(s,i);if(!bt.test(n))return!0}return!1};d.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;A.lastIndex=this.pos;var e=A.exec(this.input),t=this.pos+e[0].length,i;return!R.test(this.input.slice(this.pos,t))&&this.input.slice(t,t+8)==="function"&&(t+8===this.input.length||!(K(i=this.fullCharCodeAt(t+8))||i===92))};d.isUsingKeyword=function(e,t){if(this.options.ecmaVersion<17||!this.isContextual(e?"await":"using"))return!1;A.lastIndex=this.pos;var i=A.exec(this.input),r=this.pos+i[0].length;if(R.test(this.input.slice(this.pos,r)))return!1;if(e){var s=r+5,n;if(this.input.slice(r,s)!=="using"||s===this.input.length||K(n=this.fullCharCodeAt(s))||n===92)return!1;A.lastIndex=s;var o=A.exec(this.input);if(r=s+o[0].length,o&&R.test(this.input.slice(s,r)))return!1}var c=this.fullCharCodeAt(r);if(!j(c)&&c!==92)return!1;var h=r;do r+=c<=65535?1:2;while(K(c=this.fullCharCodeAt(r)));if(c===92)return!0;var l=this.input.slice(h,r);if(bt.test(l))return!1;if(t&&!e&&l==="of"){A.lastIndex=r;var m=A.exec(this.input);if(r=r+m[0].length,this.input.charCodeAt(r)!==61||(c=this.input.charCodeAt(r+1))===61||c===62)return!1}return!0};d.isAwaitUsing=function(e){return this.isUsingKeyword(!0,e)};d.isUsing=function(e){return this.isUsingKeyword(!1,e)};d.parseStatement=function(e,t,i){var r=this.type,s=this.startNode(),n;switch(this.isLet(e)&&(r=a._var,n="let"),r){case a._break:case a._continue:return this.parseBreakContinueStatement(s,r.keyword);case a._debugger:return this.parseDebuggerStatement(s);case a._do:return this.parseDoStatement(s);case a._for:return this.parseForStatement(s);case a._function:return e&&(this.strict||e!=="if"&&e!=="label")&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(s,!1,!e);case a._class:return e&&this.unexpected(),this.parseClass(s,!0);case a._if:return this.parseIfStatement(s);case a._return:return this.parseReturnStatement(s);case a._switch:return this.parseSwitchStatement(s);case a._throw:return this.parseThrowStatement(s);case a._try:return this.parseTryStatement(s);case a._const:case a._var:return n=n||this.value,e&&n!=="var"&&this.unexpected(),this.parseVarStatement(s,n);case a._while:return this.parseWhileStatement(s);case a._with:return this.parseWithStatement(s);case a.braceL:return this.parseBlock(!0,s);case a.semi:return this.parseEmptyStatement(s);case a._export:case a._import:if(this.options.ecmaVersion>10&&r===a._import){A.lastIndex=this.pos;var o=A.exec(this.input),c=this.pos+o[0].length,h=this.input.charCodeAt(c);if(h===40||h===46)return this.parseExpressionStatement(s,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),r===a._import?this.parseImport(s):this.parseExport(s,i);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(s,!0,!e);var l=this.isAwaitUsing(!1)?"await using":this.isUsing(!1)?"using":null;if(l)return this.allowUsing||this.raise(this.start,"Using declaration cannot appear in the top level when source type is `script` or in the bare case statement"),e&&this.raise(this.start,"Using declaration is not allowed in single-statement positions"),l==="await using"&&(this.canAwait||this.raise(this.start,"Await using cannot appear outside of async function"),this.next()),this.next(),this.parseVar(s,!1,l),this.semicolon(),this.finishNode(s,"VariableDeclaration");var m=this.value,S=this.parseExpression();return r===a.name&&S.type==="Identifier"&&this.eat(a.colon)?this.parseLabeledStatement(s,m,S,e):this.parseExpressionStatement(s,S)}};d.parseBreakContinueStatement=function(e,t){var i=t==="break";this.next(),this.eat(a.semi)||this.insertSemicolon()?e.label=null:this.type!==a.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var r=0;r<this.labels.length;++r){var s=this.labels[r];if((e.label==null||s.name===e.label.name)&&(s.kind!=null&&(i||s.kind==="loop")||e.label&&i))break}return r===this.labels.length&&this.raise(e.start,"Unsyntactic "+t),this.finishNode(e,i?"BreakStatement":"ContinueStatement")};d.parseDebuggerStatement=function(e){return this.next(),this.semicolon(),this.finishNode(e,"DebuggerStatement")};d.parseDoStatement=function(e){return this.next(),this.labels.push(Ye),e.body=this.parseStatement("do"),this.labels.pop(),this.expect(a._while),e.test=this.parseParenExpression(),this.options.ecmaVersion>=6?this.eat(a.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")};d.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(Ye),this.enterScope(0),this.expect(a.parenL),this.type===a.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var i=this.isLet();if(this.type===a._var||this.type===a._const||i){var r=this.startNode(),s=i?"let":this.value;return this.next(),this.parseVar(r,!0,s),this.finishNode(r,"VariableDeclaration"),this.parseForAfterInit(e,r,t)}var n=this.isContextual("let"),o=!1,c=this.isUsing(!0)?"using":this.isAwaitUsing(!0)?"await using":null;if(c){var h=this.startNode();return this.next(),c==="await using"&&(this.canAwait||this.raise(this.start,"Await using cannot appear outside of async function"),this.next()),this.parseVar(h,!0,c),this.finishNode(h,"VariableDeclaration"),this.parseForAfterInit(e,h,t)}var l=this.containsEsc,m=new Ee,S=this.start,k=t>-1?this.parseExprSubscripts(m,"await"):this.parseExpression(!0,m);return this.type===a._in||(o=this.options.ecmaVersion>=6&&this.isContextual("of"))?(t>-1?(this.type===a._in&&this.unexpected(t),e.await=!0):o&&this.options.ecmaVersion>=8&&(k.start===S&&!l&&k.type==="Identifier"&&k.name==="async"?this.unexpected():this.options.ecmaVersion>=9&&(e.await=!1)),n&&o&&this.raise(k.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(k,!1,m),this.checkLValPattern(k),this.parseForIn(e,k)):(this.checkExpressionErrors(m,!0),t>-1&&this.unexpected(t),this.parseFor(e,k))};d.parseForAfterInit=function(e,t,i){return(this.type===a._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&t.declarations.length===1?(this.type===a._in?((t.kind==="using"||t.kind==="await using")&&!t.declarations[0].init&&this.raise(this.start,"Using declaration is not allowed in for-in loops"),this.options.ecmaVersion>=9&&i>-1&&this.unexpected(i)):this.options.ecmaVersion>=9&&(e.await=i>-1),this.parseForIn(e,t)):(i>-1&&this.unexpected(i),this.parseFor(e,t))};d.parseFunctionStatement=function(e,t,i){return this.next(),this.parseFunction(e,oe|(i?0:qe),!1,t)};d.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(a._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")};d.parseReturnStatement=function(e){return this.allowReturn||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(a.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")};d.parseSwitchStatement=function(e){this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(a.braceL),this.labels.push(ir),this.enterScope(wt);for(var t,i=!1;this.type!==a.braceR;)if(this.type===a._case||this.type===a._default){var r=this.type===a._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),r?t.test=this.parseExpression():(i&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),i=!0,t.test=null),this.expect(a.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")};d.parseThrowStatement=function(e){return this.next(),R.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var rr=[];d.parseCatchClauseParam=function(){var e=this.parseBindingAtom(),t=e.type==="Identifier";return this.enterScope(t?Tt:0),this.checkLValPattern(e,t?Pt:q),this.expect(a.parenR),e};d.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===a._catch){var t=this.startNode();this.next(),this.eat(a.parenL)?t.param=this.parseCatchClauseParam():(this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0)),t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(a._finally)?this.parseBlock():null,!e.handler&&!e.finalizer&&this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")};d.parseVarStatement=function(e,t,i){return this.next(),this.parseVar(e,!1,t,i),this.semicolon(),this.finishNode(e,"VariableDeclaration")};d.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(Ye),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")};d.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")};d.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")};d.parseLabeledStatement=function(e,t,i,r){for(var s=0,n=this.labels;s<n.length;s+=1){var o=n[s];o.name===t&&this.raise(i.start,"Label '"+t+"' is already declared")}for(var c=this.type.isLoop?"loop":this.type===a._switch?"switch":null,h=this.labels.length-1;h>=0;h--){var l=this.labels[h];if(l.statementStart===e.start)l.statementStart=this.start,l.kind=c;else break}return this.labels.push({name:t,kind:c,statementStart:this.start}),e.body=this.parseStatement(r?r.indexOf("label")===-1?r+"label":r:"label"),this.labels.pop(),e.label=i,this.finishNode(e,"LabeledStatement")};d.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")};d.parseBlock=function(e,t,i){for(e===void 0&&(e=!0),t===void 0&&(t=this.startNode()),t.body=[],this.expect(a.braceL),e&&this.enterScope(0);this.type!==a.braceR;){var r=this.parseStatement(null);t.body.push(r)}return i&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")};d.parseFor=function(e,t){return e.init=t,this.expect(a.semi),e.test=this.type===a.semi?null:this.parseExpression(),this.expect(a.semi),e.update=this.type===a.parenR?null:this.parseExpression(),this.expect(a.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")};d.parseForIn=function(e,t){var i=this.type===a._in;return this.next(),t.type==="VariableDeclaration"&&t.declarations[0].init!=null&&(!i||this.options.ecmaVersion<8||this.strict||t.kind!=="var"||t.declarations[0].id.type!=="Identifier")&&this.raise(t.start,(i?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=i?this.parseExpression():this.parseMaybeAssign(),this.expect(a.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,i?"ForInStatement":"ForOfStatement")};d.parseVar=function(e,t,i,r){for(e.declarations=[],e.kind=i;;){var s=this.startNode();if(this.parseVarId(s,i),this.eat(a.eq)?s.init=this.parseMaybeAssign(t):!r&&i==="const"&&!(this.type===a._in||this.options.ecmaVersion>=6&&this.isContextual("of"))?this.unexpected():!r&&(i==="using"||i==="await using")&&this.options.ecmaVersion>=17&&this.type!==a._in&&!this.isContextual("of")?this.raise(this.lastTokEnd,"Missing initializer in "+i+" declaration"):!r&&s.id.type!=="Identifier"&&!(t&&(this.type===a._in||this.isContextual("of")))?this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):s.init=null,e.declarations.push(this.finishNode(s,"VariableDeclarator")),!this.eat(a.comma))break}return e};d.parseVarId=function(e,t){e.id=t==="using"||t==="await using"?this.parseIdent():this.parseBindingAtom(),this.checkLValPattern(e.id,t==="var"?Qe:q,!1)};var oe=1,qe=2,Lt=4;d.parseFunction=function(e,t,i,r,s){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!r)&&(this.type===a.star&&t&qe&&this.unexpected(),e.generator=this.eat(a.star)),this.options.ecmaVersion>=8&&(e.async=!!r),t&oe&&(e.id=t&Lt&&this.type!==a.name?null:this.parseIdent(),e.id&&!(t&qe)&&this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?Qe:q:It));var n=this.yieldPos,o=this.awaitPos,c=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(ze(e.async,e.generator)),t&oe||(e.id=this.type===a.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,i,!1,s),this.yieldPos=n,this.awaitPos=o,this.awaitIdentPos=c,this.finishNode(e,t&oe?"FunctionDeclaration":"FunctionExpression")};d.parseFunctionParams=function(e){this.expect(a.parenL),e.params=this.parseBindingList(a.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()};d.parseClass=function(e,t){this.next();var i=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var r=this.enterClassBody(),s=this.startNode(),n=!1;for(s.body=[],this.expect(a.braceL);this.type!==a.braceR;){var o=this.parseClassElement(e.superClass!==null);o&&(s.body.push(o),o.type==="MethodDefinition"&&o.kind==="constructor"?(n&&this.raiseRecoverable(o.start,"Duplicate constructor in the same class"),n=!0):o.key&&o.key.type==="PrivateIdentifier"&&sr(r,o)&&this.raiseRecoverable(o.key.start,"Identifier '#"+o.key.name+"' has already been declared"))}return this.strict=i,this.next(),e.body=this.finishNode(s,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")};d.parseClassElement=function(e){if(this.eat(a.semi))return null;var t=this.options.ecmaVersion,i=this.startNode(),r="",s=!1,n=!1,o="method",c=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(a.braceL))return this.parseClassStaticBlock(i),i;this.isClassElementNameStart()||this.type===a.star?c=!0:r="static"}if(i.static=c,!r&&t>=8&&this.eatContextual("async")&&((this.isClassElementNameStart()||this.type===a.star)&&!this.canInsertSemicolon()?n=!0:r="async"),!r&&(t>=9||!n)&&this.eat(a.star)&&(s=!0),!r&&!n&&!s){var h=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?o=h:r=h)}if(r?(i.computed=!1,i.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),i.key.name=r,this.finishNode(i.key,"Identifier")):this.parseClassElementName(i),t<13||this.type===a.parenL||o!=="method"||s||n){var l=!i.static&&ge(i,"constructor"),m=l&&e;l&&o!=="method"&&this.raise(i.key.start,"Constructor can't have get/set modifier"),i.kind=l?"constructor":o,this.parseClassMethod(i,s,n,m)}else this.parseClassField(i);return i};d.isClassElementNameStart=function(){return this.type===a.name||this.type===a.privateId||this.type===a.num||this.type===a.string||this.type===a.bracketL||this.type.keyword};d.parseClassElementName=function(e){this.type===a.privateId?(this.value==="constructor"&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)};d.parseClassMethod=function(e,t,i,r){var s=e.key;e.kind==="constructor"?(t&&this.raise(s.start,"Constructor can't be a generator"),i&&this.raise(s.start,"Constructor can't be an async method")):e.static&&ge(e,"prototype")&&this.raise(s.start,"Classes may not have a static property named prototype");var n=e.value=this.parseMethod(t,i,r);return e.kind==="get"&&n.params.length!==0&&this.raiseRecoverable(n.start,"getter should have no params"),e.kind==="set"&&n.params.length!==1&&this.raiseRecoverable(n.start,"setter should have exactly one param"),e.kind==="set"&&n.params[0].type==="RestElement"&&this.raiseRecoverable(n.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")};d.parseClassField=function(e){return ge(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&ge(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(a.eq)?(this.enterScope(he|Ce),e.value=this.parseMaybeAssign(),this.exitScope()):e.value=null,this.semicolon(),this.finishNode(e,"PropertyDefinition")};d.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(Q|Ce);this.type!==a.braceR;){var i=this.parseStatement(null);e.body.push(i)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")};d.parseClassId=function(e,t){this.type===a.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,q,!1)):(t===!0&&this.unexpected(),e.id=null)};d.parseClassSuper=function(e){e.superClass=this.eat(a._extends)?this.parseExprSubscripts(null,!1):null};d.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared};d.exitClassBody=function(){var e=this.privateNameStack.pop(),t=e.declared,i=e.used;if(this.options.checkPrivateFields)for(var r=this.privateNameStack.length,s=r===0?null:this.privateNameStack[r-1],n=0;n<i.length;++n){var o=i[n];te(t,o.name)||(s?s.used.push(o):this.raiseRecoverable(o.start,"Private field '#"+o.name+"' must be declared in an enclosing class"))}};function sr(e,t){var i=t.key.name,r=e[i],s="true";return t.type==="MethodDefinition"&&(t.kind==="get"||t.kind==="set")&&(s=(t.static?"s":"i")+t.kind),r==="iget"&&s==="iset"||r==="iset"&&s==="iget"||r==="sget"&&s==="sset"||r==="sset"&&s==="sget"?(e[i]="true",!1):r?!0:(e[i]=s,!1)}function ge(e,t){var i=e.computed,r=e.key;return!i&&(r.type==="Identifier"&&r.name===t||r.type==="Literal"&&r.value===t)}d.parseExportAllDeclaration=function(e,t){return this.options.ecmaVersion>=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==a.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")};d.parseExport=function(e,t){if(this.next(),this.eat(a.star))return this.parseExportAllDeclaration(e,t);if(this.eat(a._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),e.declaration.type==="VariableDeclaration"?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null,this.options.ecmaVersion>=16&&(e.attributes=[]);else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==a.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause());else{for(var i=0,r=e.specifiers;i<r.length;i+=1){var s=r[i];this.checkUnreserved(s.local),this.checkLocalExport(s.local),s.local.type==="Literal"&&this.raise(s.local.start,"A string literal cannot be used as an exported binding without `from`.")}e.source=null,this.options.ecmaVersion>=16&&(e.attributes=[])}this.semicolon()}return this.finishNode(e,"ExportNamedDeclaration")};d.parseExportDeclaration=function(e){return this.parseStatement(null)};d.parseExportDefaultDeclaration=function(){var e;if(this.type===a._function||(e=this.isAsyncFunction())){var t=this.startNode();return this.next(),e&&this.next(),this.parseFunction(t,oe|Lt,!1,e)}else if(this.type===a._class){var i=this.startNode();return this.parseClass(i,"nullableID")}else{var r=this.parseMaybeAssign();return this.semicolon(),r}};d.checkExport=function(e,t,i){e&&(typeof t!="string"&&(t=t.type==="Identifier"?t.name:t.value),te(e,t)&&this.raiseRecoverable(i,"Duplicate export '"+t+"'"),e[t]=!0)};d.checkPatternExport=function(e,t){var i=t.type;if(i==="Identifier")this.checkExport(e,t,t.start);else if(i==="ObjectPattern")for(var r=0,s=t.properties;r<s.length;r+=1){var n=s[r];this.checkPatternExport(e,n)}else if(i==="ArrayPattern")for(var o=0,c=t.elements;o<c.length;o+=1){var h=c[o];h&&this.checkPatternExport(e,h)}else i==="Property"?this.checkPatternExport(e,t.value):i==="AssignmentPattern"?this.checkPatternExport(e,t.left):i==="RestElement"&&this.checkPatternExport(e,t.argument)};d.checkVariableExport=function(e,t){if(e)for(var i=0,r=t;i<r.length;i+=1){var s=r[i];this.checkPatternExport(e,s.id)}};d.shouldParseExportStatement=function(){return this.type.keyword==="var"||this.type.keyword==="const"||this.type.keyword==="class"||this.type.keyword==="function"||this.isLet()||this.isAsyncFunction()};d.parseExportSpecifier=function(e){var t=this.startNode();return t.local=this.parseModuleExportName(),t.exported=this.eatContextual("as")?this.parseModuleExportName():t.local,this.checkExport(e,t.exported,t.exported.start),this.finishNode(t,"ExportSpecifier")};d.parseExportSpecifiers=function(e){var t=[],i=!0;for(this.expect(a.braceL);!this.eat(a.braceR);){if(i)i=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;t.push(this.parseExportSpecifier(e))}return t};d.parseImport=function(e){return this.next(),this.type===a.string?(e.specifiers=rr,e.source=this.parseExprAtom()):(e.specifiers=this.parseImportSpecifiers(),this.expectContextual("from"),e.source=this.type===a.string?this.parseExprAtom():this.unexpected()),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ImportDeclaration")};d.parseImportSpecifier=function(){var e=this.startNode();return e.imported=this.parseModuleExportName(),this.eatContextual("as")?e.local=this.parseIdent():(this.checkUnreserved(e.imported),e.local=e.imported),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportSpecifier")};d.parseImportDefaultSpecifier=function(){var e=this.startNode();return e.local=this.parseIdent(),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportDefaultSpecifier")};d.parseImportNamespaceSpecifier=function(){var e=this.startNode();return this.next(),this.expectContextual("as"),e.local=this.parseIdent(),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportNamespaceSpecifier")};d.parseImportSpecifiers=function(){var e=[],t=!0;if(this.type===a.name&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(a.comma)))return e;if(this.type===a.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(a.braceL);!this.eat(a.braceR);){if(t)t=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;e.push(this.parseImportSpecifier())}return e};d.parseWithClause=function(){var e=[];if(!this.eat(a._with))return e;this.expect(a.braceL);for(var t={},i=!0;!this.eat(a.braceR);){if(i)i=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;var r=this.parseImportAttribute(),s=r.key.type==="Identifier"?r.key.name:r.key.value;te(t,s)&&this.raiseRecoverable(r.key.start,"Duplicate attribute key '"+s+"'"),t[s]=!0,e.push(r)}return e};d.parseImportAttribute=function(){var e=this.startNode();return e.key=this.type===a.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never"),this.expect(a.colon),this.type!==a.string&&this.unexpected(),e.value=this.parseExprAtom(),this.finishNode(e,"ImportAttribute")};d.parseModuleExportName=function(){if(this.options.ecmaVersion>=13&&this.type===a.string){var e=this.parseLiteral(this.value);return Zi.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)};d.adaptDirectivePrologue=function(e){for(var t=0;t<e.length&&this.isDirectiveCandidate(e[t]);++t)e[t].directive=e[t].expression.raw.slice(1,-1)};d.isDirectiveCandidate=function(e){return this.options.ecmaVersion>=5&&e.type==="ExpressionStatement"&&e.expression.type==="Literal"&&typeof e.expression.value=="string"&&(this.input[e.start]==='"'||this.input[e.start]==="'")};var B=T.prototype;B.toAssignable=function(e,t,i){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&e.name==="await"&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",i&&this.checkPatternErrors(i,!0);for(var r=0,s=e.properties;r<s.length;r+=1){var n=s[r];this.toAssignable(n,t),n.type==="RestElement"&&(n.argument.type==="ArrayPattern"||n.argument.type==="ObjectPattern")&&this.raise(n.argument.start,"Unexpected token")}break;case"Property":e.kind!=="init"&&this.raise(e.key.start,"Object pattern can't contain getter or setter"),this.toAssignable(e.value,t);break;case"ArrayExpression":e.type="ArrayPattern",i&&this.checkPatternErrors(i,!0),this.toAssignableList(e.elements,t);break;case"SpreadElement":e.type="RestElement",this.toAssignable(e.argument,t),e.argument.type==="AssignmentPattern"&&this.raise(e.argument.start,"Rest elements cannot have a default value");break;case"AssignmentExpression":e.operator!=="="&&this.raise(e.left.end,"Only '=' operator can be used for specifying default value."),e.type="AssignmentPattern",delete e.operator,this.toAssignable(e.left,t);break;case"ParenthesizedExpression":this.toAssignable(e.expression,t,i);break;case"ChainExpression":this.raiseRecoverable(e.start,"Optional chaining cannot appear in left-hand side");break;case"MemberExpression":if(!t)break;default:this.raise(e.start,"Assigning to rvalue")}else i&&this.checkPatternErrors(i,!0);return e};B.toAssignableList=function(e,t){for(var i=e.length,r=0;r<i;r++){var s=e[r];s&&this.toAssignable(s,t)}if(i){var n=e[i-1];this.options.ecmaVersion===6&&t&&n&&n.type==="RestElement"&&n.argument.type!=="Identifier"&&this.unexpected(n.argument.start)}return e};B.parseSpread=function(e){var t=this.startNode();return this.next(),t.argument=this.parseMaybeAssign(!1,e),this.finishNode(t,"SpreadElement")};B.parseRestBinding=function(){var e=this.startNode();return this.next(),this.options.ecmaVersion===6&&this.type!==a.name&&this.unexpected(),e.argument=this.parseBindingAtom(),this.finishNode(e,"RestElement")};B.parseBindingAtom=function(){if(this.options.ecmaVersion>=6)switch(this.type){case a.bracketL:var e=this.startNode();return this.next(),e.elements=this.parseBindingList(a.bracketR,!0,!0),this.finishNode(e,"ArrayPattern");case a.braceL:return this.parseObj(!0)}return this.parseIdent()};B.parseBindingList=function(e,t,i,r){for(var s=[],n=!0;!this.eat(e);)if(n?n=!1:this.expect(a.comma),t&&this.type===a.comma)s.push(null);else{if(i&&this.afterTrailingComma(e))break;if(this.type===a.ellipsis){var o=this.parseRestBinding();this.parseBindingListItem(o),s.push(o),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.expect(e);break}else s.push(this.parseAssignableListItem(r))}return s};B.parseAssignableListItem=function(e){var t=this.parseMaybeDefault(this.start,this.startLoc);return this.parseBindingListItem(t),t};B.parseBindingListItem=function(e){return e};B.parseMaybeDefault=function(e,t,i){if(i=i||this.parseBindingAtom(),this.options.ecmaVersion<6||!this.eat(a.eq))return i;var r=this.startNodeAt(e,t);return r.left=i,r.right=this.parseMaybeAssign(),this.finishNode(r,"AssignmentPattern")};B.checkLValSimple=function(e,t,i){t===void 0&&(t=ye);var r=t!==ye;switch(e.type){case"Identifier":this.strict&&this.reservedWordsStrictBind.test(e.name)&&this.raiseRecoverable(e.start,(r?"Binding ":"Assigning to ")+e.name+" in strict mode"),r&&(t===q&&e.name==="let"&&this.raiseRecoverable(e.start,"let is disallowed as a lexically bound name"),i&&(te(i,e.name)&&this.raiseRecoverable(e.start,"Argument name clash"),i[e.name]=!0),t!==Nt&&this.declareName(e.name,t,e.start));break;case"ChainExpression":this.raiseRecoverable(e.start,"Optional chaining cannot appear in left-hand side");break;case"MemberExpression":r&&this.raiseRecoverable(e.start,"Binding member expression");break;case"ParenthesizedExpression":return r&&this.raiseRecoverable(e.start,"Binding parenthesized expression"),this.checkLValSimple(e.expression,t,i);default:this.raise(e.start,(r?"Binding":"Assigning to")+" rvalue")}};B.checkLValPattern=function(e,t,i){switch(t===void 0&&(t=ye),e.type){case"ObjectPattern":for(var r=0,s=e.properties;r<s.length;r+=1){var n=s[r];this.checkLValInnerPattern(n,t,i)}break;case"ArrayPattern":for(var o=0,c=e.elements;o<c.length;o+=1){var h=c[o];h&&this.checkLValInnerPattern(h,t,i)}break;default:this.checkLValSimple(e,t,i)}};B.checkLValInnerPattern=function(e,t,i){switch(t===void 0&&(t=ye),e.type){case"Property":this.checkLValInnerPattern(e.value,t,i);break;case"AssignmentPattern":this.checkLValPattern(e.left,t,i);break;case"RestElement":this.checkLValPattern(e.argument,t,i);break;default:this.checkLValPattern(e,t,i)}};var F=function(t,i,r,s,n){this.token=t,this.isExpr=!!i,this.preserveSpace=!!r,this.override=s,this.generator=!!n},E={b_stat:new F("{",!1),b_expr:new F("{",!0),b_tmpl:new F("${",!1),p_stat:new F("(",!1),p_expr:new F("(",!0),q_tmpl:new F("`",!0,!0,function(e){return e.tryReadTemplateToken()}),f_stat:new F("function",!1),f_expr:new F("function",!0),f_expr_gen:new F("function",!0,!1,null,!0),f_gen:new F("function",!1,!1,null,!0)},ie=T.prototype;ie.initialContext=function(){return[E.b_stat]};ie.curContext=function(){return this.context[this.context.length-1]};ie.braceIsBlock=function(e){var t=this.curContext();return t===E.f_expr||t===E.f_stat?!0:e===a.colon&&(t===E.b_stat||t===E.b_expr)?!t.isExpr:e===a._return||e===a.name&&this.exprAllowed?R.test(this.input.slice(this.lastTokEnd,this.start)):e===a._else||e===a.semi||e===a.eof||e===a.parenR||e===a.arrow?!0:e===a.braceL?t===E.b_stat:e===a._var||e===a._const||e===a.name?!1:!this.exprAllowed};ie.inGeneratorContext=function(){for(var e=this.context.length-1;e>=1;e--){var t=this.context[e];if(t.token==="function")return t.generator}return!1};ie.updateContext=function(e){var t,i=this.type;i.keyword&&e===a.dot?this.exprAllowed=!1:(t=i.updateContext)?t.call(this,e):this.exprAllowed=i.beforeExpr};ie.overrideContext=function(e){this.curContext()!==e&&(this.context[this.context.length-1]=e)};a.parenR.updateContext=a.braceR.updateContext=function(){if(this.context.length===1){this.exprAllowed=!0;return}var e=this.context.pop();e===E.b_stat&&this.curContext().token==="function"&&(e=this.context.pop()),this.exprAllowed=!e.isExpr};a.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?E.b_stat:E.b_expr),this.exprAllowed=!0};a.dollarBraceL.updateContext=function(){this.context.push(E.b_tmpl),this.exprAllowed=!0};a.parenL.updateContext=function(e){var t=e===a._if||e===a._for||e===a._with||e===a._while;this.context.push(t?E.p_stat:E.p_expr),this.exprAllowed=!0};a.incDec.updateContext=function(){};a._function.updateContext=a._class.updateContext=function(e){e.beforeExpr&&e!==a._else&&!(e===a.semi&&this.curContext()!==E.p_stat)&&!(e===a._return&&R.test(this.input.slice(this.lastTokEnd,this.start)))&&!((e===a.colon||e===a.braceL)&&this.curContext()===E.b_stat)?this.context.push(E.f_expr):this.context.push(E.f_stat),this.exprAllowed=!1};a.colon.updateContext=function(){this.curContext().token==="function"&&this.context.pop(),this.exprAllowed=!0};a.backQuote.updateContext=function(){this.curContext()===E.q_tmpl?this.context.pop():this.context.push(E.q_tmpl),this.exprAllowed=!1};a.star.updateContext=function(e){if(e===a._function){var t=this.context.length-1;this.context[t]===E.f_expr?this.context[t]=E.f_expr_gen:this.context[t]=E.f_gen}this.exprAllowed=!0};a.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&e!==a.dot&&(this.value==="of"&&!this.exprAllowed||this.value==="yield"&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var g=T.prototype;g.checkPropClash=function(e,t,i){if(!(this.options.ecmaVersion>=9&&e.type==="SpreadElement")&&!(this.options.ecmaVersion>=6&&(e.computed||e.method||e.shorthand))){var r=e.key,s;switch(r.type){case"Identifier":s=r.name;break;case"Literal":s=String(r.value);break;default:return}var n=e.kind;if(this.options.ecmaVersion>=6){s==="__proto__"&&n==="init"&&(t.proto&&(i?i.doubleProto<0&&(i.doubleProto=r.start):this.raiseRecoverable(r.start,"Redefinition of __proto__ property")),t.proto=!0);return}s="$"+s;var o=t[s];if(o){var c;n==="init"?c=this.strict&&o.init||o.get||o.set:c=o.init||o[n],c&&this.raiseRecoverable(r.start,"Redefinition of property")}else o=t[s]={init:!1,get:!1,set:!1};o[n]=!0}};g.parseExpression=function(e,t){var i=this;return this.catchStackOverflow(function(){var r=i.start,s=i.startLoc,n=i.parseMaybeAssign(e,t);if(i.type===a.comma){var o=i.startNodeAt(r,s);for(o.expressions=[n];i.eat(a.comma);)o.expressions.push(i.parseMaybeAssign(e,t));return i.finishNode(o,"SequenceExpression")}return n})};g.parseMaybeAssign=function(e,t,i){if(this.isContextual("yield")){if(this.inGenerator)return this.parseYield(e);this.exprAllowed=!1}var r=!1,s=-1,n=-1,o=-1;t?(s=t.parenthesizedAssign,n=t.trailingComma,o=t.doubleProto,t.parenthesizedAssign=t.trailingComma=-1):(t=new Ee,r=!0);var c=this.start,h=this.startLoc;(this.type===a.parenL||this.type===a.name)&&(this.potentialArrowAt=this.start,this.potentialArrowInForAwait=e==="await");var l=this.parseMaybeConditional(e,t);if(i&&(l=i.call(this,l,c,h)),this.type.isAssign){var m=this.startNodeAt(c,h);return m.operator=this.value,this.type===a.eq&&(l=this.toAssignable(l,!1,t)),r||(t.parenthesizedAssign=t.trailingComma=t.doubleProto=-1),t.shorthandAssign>=l.start&&(t.shorthandAssign=-1),this.type===a.eq?this.checkLValPattern(l):this.checkLValSimple(l),m.left=l,this.next(),m.right=this.parseMaybeAssign(e),o>-1&&(t.doubleProto=o),this.finishNode(m,"AssignmentExpression")}else r&&this.checkExpressionErrors(t,!0);return s>-1&&(t.parenthesizedAssign=s),n>-1&&(t.trailingComma=n),l};g.parseMaybeConditional=function(e,t){var i=this.start,r=this.startLoc,s=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return s;if(!(s.type==="ArrowFunctionExpression"&&s.start===i)&&this.eat(a.question)){var n=this.startNodeAt(i,r);return n.test=s,n.consequent=this.parseMaybeAssign(),this.expect(a.colon),n.alternate=this.parseMaybeAssign(e),this.finishNode(n,"ConditionalExpression")}return s};g.parseExprOps=function(e,t){var i=this.start,r=this.startLoc,s=this.parseMaybeUnary(t,!1,!1,e);return this.checkExpressionErrors(t)||s.start===i&&s.type==="ArrowFunctionExpression"?s:this.parseExprOp(s,i,r,-1,e)};g.parseExprOp=function(e,t,i,r,s){var n=this.type.binop;if(n!=null&&(!s||this.type!==a._in)&&n>r){var o=this.type===a.logicalOR||this.type===a.logicalAND,c=this.type===a.coalesce;c&&(n=a.logicalAND.binop);var h=this.value;this.next();var l=this.start,m=this.startLoc,S=this.parseExprOp(this.parseMaybeUnary(null,!1,!1,s),l,m,n,s),k=this.buildBinary(t,i,e,S,h,o||c);return(o&&this.type===a.coalesce||c&&(this.type===a.logicalOR||this.type===a.logicalAND))&&this.raiseRecoverable(this.start,"Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"),this.parseExprOp(k,t,i,r,s)}return e};g.buildBinary=function(e,t,i,r,s,n){r.type==="PrivateIdentifier"&&this.raise(r.start,"Private identifier can only be left side of binary expression");var o=this.startNodeAt(e,t);return o.left=i,o.operator=s,o.right=r,this.finishNode(o,n?"LogicalExpression":"BinaryExpression")};g.parseMaybeUnary=function(e,t,i,r){var s=this.start,n=this.startLoc,o;if(this.isContextual("await")&&this.canAwait)o=this.parseAwait(r),t=!0;else if(this.type.prefix){var c=this.startNode(),h=this.type===a.incDec;c.operator=this.value,c.prefix=!0,this.next(),c.argument=this.parseMaybeUnary(null,!0,h,r),this.checkExpressionErrors(e,!0),h?this.checkLValSimple(c.argument):this.strict&&c.operator==="delete"&&Rt(c.argument)?this.raiseRecoverable(c.start,"Deleting local variable in strict mode"):c.operator==="delete"&&He(c.argument)?this.raiseRecoverable(c.start,"Private fields can not be deleted"):t=!0,o=this.finishNode(c,h?"UpdateExpression":"UnaryExpression")}else if(!t&&this.type===a.privateId)(r||this.privateNameStack.length===0)&&this.options.checkPrivateFields&&this.unexpected(),o=this.parsePrivateIdent(),this.type!==a._in&&this.unexpected();else{if(o=this.parseExprSubscripts(e,r),this.checkExpressionErrors(e))return o;for(;this.type.postfix&&!this.canInsertSemicolon();){var l=this.startNodeAt(s,n);l.operator=this.value,l.prefix=!1,l.argument=o,this.checkLValSimple(o),this.next(),o=this.finishNode(l,"UpdateExpression")}}if(!i&&this.eat(a.starstar))if(t)this.unexpected(this.lastTokStart);else return this.buildBinary(s,n,o,this.parseMaybeUnary(null,!1,!1,r),"**",!1);else return o};function Rt(e){return e.type==="Identifier"||e.type==="ParenthesizedExpression"&&Rt(e.expression)}function He(e){return e.type==="MemberExpression"&&e.property.type==="PrivateIdentifier"||e.type==="ChainExpression"&&He(e.expression)||e.type==="ParenthesizedExpression"&&He(e.expression)}g.parseExprSubscripts=function(e,t){var i=this.start,r=this.startLoc,s=this.parseExprAtom(e,t);if(s.type==="ArrowFunctionExpression"&&this.input.slice(this.lastTokStart,this.lastTokEnd)!==")")return s;var n=this.parseSubscripts(s,i,r,!1,t);return e&&n.type==="MemberExpression"&&(e.parenthesizedAssign>=n.start&&(e.parenthesizedAssign=-1),e.parenthesizedBind>=n.start&&(e.parenthesizedBind=-1),e.trailingComma>=n.start&&(e.trailingComma=-1)),n};g.parseSubscripts=function(e,t,i,r,s){for(var n=this.options.ecmaVersion>=8&&e.type==="Identifier"&&e.name==="async"&&this.lastTokEnd===e.end&&!this.canInsertSemicolon()&&e.end-e.start===5&&this.potentialArrowAt===e.start,o=!1;;){var c=this.parseSubscript(e,t,i,r,n,o,s);if(c.optional&&(o=!0),c===e||c.type==="ArrowFunctionExpression"){if(o){var h=this.startNodeAt(t,i);h.expression=c,c=this.finishNode(h,"ChainExpression")}return c}e=c}};g.shouldParseAsyncArrow=function(){return!this.canInsertSemicolon()&&this.eat(a.arrow)};g.parseSubscriptAsyncArrow=function(e,t,i,r){return this.parseArrowExpression(this.startNodeAt(e,t),i,!0,r)};g.parseSubscript=function(e,t,i,r,s,n,o){var c=this.options.ecmaVersion>=11,h=c&&this.eat(a.questionDot);r&&h&&this.raise(this.lastTokStart,"Optional chaining cannot appear in the callee of new expressions");var l=this.eat(a.bracketL);if(l||h&&this.type!==a.parenL&&this.type!==a.backQuote||this.eat(a.dot)){var m=this.startNodeAt(t,i);m.object=e,l?(m.property=this.parseExpression(),this.expect(a.bracketR)):this.type===a.privateId&&e.type!=="Super"?m.property=this.parsePrivateIdent():m.property=this.parseIdent(this.options.allowReserved!=="never"),m.computed=!!l,c&&(m.optional=h),e=this.finishNode(m,"MemberExpression")}else if(!r&&this.eat(a.parenL)){var S=new Ee,k=this.yieldPos,p=this.awaitPos,x=this.awaitIdentPos;this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0;var y=this.parseExprList(a.parenR,this.options.ecmaVersion>=8,!1,S);if(s&&!h&&this.shouldParseAsyncArrow())return this.checkPatternErrors(S,!1),this.checkYieldAwaitInDefaultParams(),this.awaitIdentPos>0&&this.raise(this.awaitIdentPos,"Cannot use 'await' as identifier inside an async function"),this.yieldPos=k,this.awaitPos=p,this.awaitIdentPos=x,this.parseSubscriptAsyncArrow(t,i,y,o);this.checkExpressionErrors(S,!0),this.yieldPos=k||this.yieldPos,this.awaitPos=p||this.awaitPos,this.awaitIdentPos=x||this.awaitIdentPos;var v=this.startNodeAt(t,i);v.callee=e,v.arguments=y,c&&(v.optional=h),e=this.finishNode(v,"CallExpression")}else if(this.type===a.backQuote){(h||n)&&this.raise(this.start,"Optional chaining cannot appear in the tag of tagged template expressions");var N=this.startNodeAt(t,i);N.tag=e,N.quasi=this.parseTemplate({isTagged:!0}),e=this.finishNode(N,"TaggedTemplateExpression")}return e};g.parseExprAtom=function(e,t,i){this.type===a.slash&&this.readRegexp();var r,s=this.potentialArrowAt===this.start;switch(this.type){case a._super:return this.allowSuper||this.raise(this.start,"'super' keyword outside a method"),r=this.startNode(),this.next(),this.type===a.parenL&&!this.allowDirectSuper&&this.raise(r.start,"super() call outside constructor of a subclass"),this.type!==a.dot&&this.type!==a.bracketL&&this.type!==a.parenL&&this.unexpected(),this.finishNode(r,"Super");case a._this:return r=this.startNode(),this.next(),this.finishNode(r,"ThisExpression");case a.name:var n=this.start,o=this.startLoc,c=this.containsEsc,h=this.parseIdent(!1);if(this.options.ecmaVersion>=8&&!c&&h.name==="async"&&!this.canInsertSemicolon()&&this.eat(a._function))return this.overrideContext(E.f_expr),this.parseFunction(this.startNodeAt(n,o),0,!1,!0,t);if(s&&!this.canInsertSemicolon()){if(this.eat(a.arrow))return this.parseArrowExpression(this.startNodeAt(n,o),[h],!1,t);if(this.options.ecmaVersion>=8&&h.name==="async"&&this.type===a.name&&!c&&(!this.potentialArrowInForAwait||this.value!=="of"||this.containsEsc))return h=this.parseIdent(!1),(this.canInsertSemicolon()||!this.eat(a.arrow))&&this.unexpected(),this.parseArrowExpression(this.startNodeAt(n,o),[h],!0,t)}return h;case a.regexp:var l=this.value;return r=this.parseLiteral(l.value),r.regex={pattern:l.pattern,flags:l.flags},r;case a.num:case a.string:return this.parseLiteral(this.value);case a._null:case a._true:case a._false:return r=this.startNode(),r.value=this.type===a._null?null:this.type===a._true,r.raw=this.type.keyword,this.next(),this.finishNode(r,"Literal");case a.parenL:var m=this.start,S=this.parseParenAndDistinguishExpression(s,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(S)&&(e.parenthesizedAssign=m),e.parenthesizedBind<0&&(e.parenthesizedBind=m)),S;case a.bracketL:return r=this.startNode(),this.next(),r.elements=this.parseExprList(a.bracketR,!0,!0,e),this.finishNode(r,"ArrayExpression");case a.braceL:return this.overrideContext(E.b_expr),this.parseObj(!1,e);case a._function:return r=this.startNode(),this.next(),this.parseFunction(r,0);case a._class:return this.parseClass(this.startNode(),!1);case a._new:return this.parseNew();case a.backQuote:return this.parseTemplate();case a._import:return this.options.ecmaVersion>=11?this.parseExprImport(i):this.unexpected();default:return this.parseExprAtomDefault()}};g.parseExprAtomDefault=function(){this.unexpected()};g.parseExprImport=function(e){var t=this.startNode();if(this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import"),this.next(),this.type===a.parenL&&!e)return this.parseDynamicImport(t);if(this.type===a.dot){var i=this.startNodeAt(t.start,t.loc&&t.loc.start);return i.name="import",t.meta=this.finishNode(i,"Identifier"),this.parseImportMeta(t)}else this.unexpected()};g.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),this.options.ecmaVersion>=16)this.eat(a.parenR)?e.options=null:(this.expect(a.comma),this.afterTrailingComma(a.parenR)?e.options=null:(e.options=this.parseMaybeAssign(),this.eat(a.parenR)||(this.expect(a.comma),this.afterTrailingComma(a.parenR)||this.unexpected())));else if(!this.eat(a.parenR)){var t=this.start;this.eat(a.comma)&&this.eat(a.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")};g.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),e.property.name!=="meta"&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),this.options.sourceType!=="module"&&!this.options.allowImportExportEverywhere&&this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")};g.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),t.raw.charCodeAt(t.raw.length-1)===110&&(t.bigint=t.value!=null?t.value.toString():t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")};g.parseParenExpression=function(){this.expect(a.parenL);var e=this.parseExpression();return this.expect(a.parenR),e};g.shouldParseArrow=function(e){return!this.canInsertSemicolon()};g.parseParenAndDistinguishExpression=function(e,t){var i=this.start,r=this.startLoc,s,n=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var o=this.start,c=this.startLoc,h=[],l=!0,m=!1,S=new Ee,k=this.yieldPos,p=this.awaitPos,x;for(this.yieldPos=0,this.awaitPos=0;this.type!==a.parenR;)if(l?l=!1:this.expect(a.comma),n&&this.afterTrailingComma(a.parenR,!0)){m=!0;break}else if(this.type===a.ellipsis){x=this.start,h.push(this.parseParenItem(this.parseRestBinding())),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}else h.push(this.parseMaybeAssign(!1,S,this.parseParenItem));var y=this.lastTokEnd,v=this.lastTokEndLoc;if(this.expect(a.parenR),e&&this.shouldParseArrow(h)&&this.eat(a.arrow))return this.checkPatternErrors(S,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=k,this.awaitPos=p,this.parseParenArrowList(i,r,h,t);(!h.length||m)&&this.unexpected(this.lastTokStart),x&&this.unexpected(x),this.checkExpressionErrors(S,!0),this.yieldPos=k||this.yieldPos,this.awaitPos=p||this.awaitPos,h.length>1?(s=this.startNodeAt(o,c),s.expressions=h,this.finishNodeAt(s,"SequenceExpression",y,v)):s=h[0]}else s=this.parseParenExpression();if(this.options.preserveParens){var N=this.startNodeAt(i,r);return N.expression=s,this.finishNode(N,"ParenthesizedExpression")}else return s};g.parseParenItem=function(e){return e};g.parseParenArrowList=function(e,t,i,r){return this.parseArrowExpression(this.startNodeAt(e,t),i,!1,r)};var ar=[];g.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode();if(this.next(),this.options.ecmaVersion>=6&&this.type===a.dot){var t=this.startNodeAt(e.start,e.loc&&e.loc.start);t.name="new",e.meta=this.finishNode(t,"Identifier"),this.next();var i=this.containsEsc;return e.property=this.parseIdent(!0),e.property.name!=="target"&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),i&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var r=this.start,s=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),r,s,!0,!1),e.callee.type==="Super"&&this.raiseRecoverable(r,"Invalid use of 'super'"),this.eat(a.parenL)?e.arguments=this.parseExprList(a.parenR,this.options.ecmaVersion>=8,!1):e.arguments=ar,this.finishNode(e,"NewExpression")};g.parseTemplateElement=function(e){var t=e.isTagged,i=this.startNode();return this.type===a.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),i.value={raw:this.value.replace(/\r\n?/g,`+`):y=String.fromCharCode(x),this.options.locations&&(++this.curLine,this.lineStart=this.pos),y}jsx_readString(p){let x="",y=++this.pos;for(;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");let v=this.input.charCodeAt(this.pos);if(v===p)break;v===38?(x+=this.input.slice(y,this.pos),x+=this.jsx_readEntity(),y=this.pos):m(v)?(x+=this.input.slice(y,this.pos),x+=this.jsx_readNewLine(!1),y=this.pos):++this.pos}return x+=this.input.slice(y,this.pos++),this.finishToken(s.string,x)}jsx_readEntity(){let p="",x=0,y,v=this.input[this.pos];v!=="&"&&this.raise(this.pos,"Entity must start with an ampersand");let N=++this.pos;for(;this.pos<this.input.length&&x++<10;){if(v=this.input[this.pos++],v===";"){p[0]==="#"?p[1]==="x"?(p=p.substr(2),Ir.test(p)&&(y=String.fromCharCode(parseInt(p,16)))):(p=p.substr(1),Pr.test(p)&&(y=String.fromCharCode(parseInt(p,10)))):y=wr[p];break}p+=v}return y||(this.pos=N,"&")}jsx_readWord(){let p,x=this.pos;do p=this.input.charCodeAt(++this.pos);while(E(p)||p===45);return this.finishToken(n.jsxName,this.input.slice(x,this.pos))}jsx_parseIdentifier(){let p=this.startNode();return this.type===n.jsxName?p.name=this.value:this.type.keyword?p.name=this.type.keyword:this.unexpected(),this.next(),this.finishNode(p,"JSXIdentifier")}jsx_parseNamespacedName(){let p=this.start,x=this.startLoc,y=this.jsx_parseIdentifier();if(!e.allowNamespaces||!this.eat(s.colon))return y;var v=this.startNodeAt(p,x);return v.namespace=y,v.name=this.jsx_parseIdentifier(),this.finishNode(v,"JSXNamespacedName")}jsx_parseElementName(){if(this.type===n.jsxTagEnd)return"";let p=this.start,x=this.startLoc,y=this.jsx_parseNamespacedName();for(this.type===s.dot&&y.type==="JSXNamespacedName"&&!e.allowNamespacedObjects&&this.unexpected();this.eat(s.dot);){let v=this.startNodeAt(p,x);v.object=y,v.property=this.jsx_parseIdentifier(),y=this.finishNode(v,"JSXMemberExpression")}return y}jsx_parseAttributeValue(){switch(this.type){case s.braceL:let p=this.jsx_parseExpressionContainer();return p.expression.type==="JSXEmptyExpression"&&this.raise(p.start,"JSX attributes must only be assigned a non-empty expression"),p;case n.jsxTagStart:case s.string:return this.parseExprAtom();default:this.raise(this.start,"JSX value should be either an expression or a quoted JSX text")}}jsx_parseEmptyExpression(){let p=this.startNodeAt(this.lastTokEnd,this.lastTokEndLoc);return this.finishNodeAt(p,"JSXEmptyExpression",this.start,this.startLoc)}jsx_parseExpressionContainer(){let p=this.startNode();return this.next(),p.expression=this.type===s.braceR?this.jsx_parseEmptyExpression():this.parseExpression(),this.expect(s.braceR),this.finishNode(p,"JSXExpressionContainer")}jsx_parseAttribute(){let p=this.startNode();return this.eat(s.braceL)?(this.expect(s.ellipsis),p.argument=this.parseMaybeAssign(),this.expect(s.braceR),this.finishNode(p,"JSXSpreadAttribute")):(p.name=this.jsx_parseNamespacedName(),p.value=this.eat(s.eq)?this.jsx_parseAttributeValue():null,this.finishNode(p,"JSXAttribute"))}jsx_parseOpeningElementAt(p,x){let y=this.startNodeAt(p,x);y.attributes=[];let v=this.jsx_parseElementName();for(v&&(y.name=v);this.type!==s.slash&&this.type!==n.jsxTagEnd;)y.attributes.push(this.jsx_parseAttribute());return y.selfClosing=this.eat(s.slash),this.expect(n.jsxTagEnd),this.finishNode(y,v?"JSXOpeningElement":"JSXOpeningFragment")}jsx_parseClosingElementAt(p,x){let y=this.startNodeAt(p,x),v=this.jsx_parseElementName();return v&&(y.name=v),this.expect(n.jsxTagEnd),this.finishNode(y,v?"JSXClosingElement":"JSXClosingFragment")}jsx_parseElementAt(p,x){let y=this.startNodeAt(p,x),v=[],N=this.jsx_parseOpeningElementAt(p,x),de=null;if(!N.selfClosing){e:for(;;)switch(this.type){case n.jsxTagStart:if(p=this.start,x=this.startLoc,this.next(),this.eat(s.slash)){de=this.jsx_parseClosingElementAt(p,x);break e}v.push(this.jsx_parseElementAt(p,x));break;case n.jsxText:v.push(this.parseExprAtom());break;case s.braceL:v.push(this.jsx_parseExpressionContainer());break;default:this.unexpected()}pe(de.name)!==pe(N.name)&&this.raise(de.start,"Expected corresponding JSX closing tag for <"+pe(N.name)+">")}let Me=N.name?"Element":"Fragment";return y["opening"+Me]=N,y["closing"+Me]=de,y.children=v,this.type===s.relational&&this.value==="<"&&this.raise(this.start,"Adjacent JSX elements must be wrapped in an enclosing tag"),this.finishNode(y,"JSX"+Me)}jsx_parseText(){let p=this.parseLiteral(this.value);return p.type="JSXText",p}jsx_parseElement(){let p=this.start,x=this.startLoc;return this.next(),this.jsx_parseElementAt(p,x)}parseExprAtom(p){return this.type===n.jsxText?this.jsx_parseText():this.type===n.jsxTagStart?this.jsx_parseElement():super.parseExprAtom(p)}readToken(p){let x=this.curContext();if(x===l)return this.jsx_readToken();if(x===h||x===c){if(S(p))return this.jsx_readWord();if(p==62)return++this.pos,this.finishToken(n.jsxTagEnd);if((p===34||p===39)&&x==h)return this.jsx_readString(p)}return p===60&&this.exprAllowed&&this.input.charCodeAt(this.pos+1)!==33?(++this.pos,this.finishToken(n.jsxTagStart)):super.readToken(p)}updateContext(p){if(this.type==s.braceL){var x=this.curContext();x==h?this.context.push(o.b_expr):x==l?this.context.push(o.b_tmpl):super.updateContext(p),this.exprAllowed=!0}else if(this.type===s.slash&&p===n.jsxTagStart)this.context.length-=2,this.context.push(c),this.exprAllowed=!1;else return super.updateContext(p)}}}});var Is={};Be(Is,{parsers:()=>ws});var nt={};Be(nt,{acorn:()=>ys});var qi=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,7,9,32,4,318,1,78,5,71,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,3,0,158,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,68,8,2,0,3,0,2,3,2,4,2,0,15,1,83,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,7,19,58,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,199,7,137,9,54,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,55,9,266,3,10,1,2,0,49,6,4,4,14,10,5350,0,7,14,11465,27,2343,9,87,9,39,4,60,6,26,9,535,9,470,0,2,54,8,3,82,0,12,1,19628,1,4178,9,519,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,101,0,161,6,10,9,357,0,62,13,499,13,245,1,2,9,233,0,3,0,8,1,6,0,475,6,110,6,6,9,4759,9,787719,239],gt=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,4,51,13,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,7,25,39,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,39,27,10,22,251,41,7,1,17,5,57,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,20,1,64,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,31,9,2,0,3,0,2,37,2,0,26,0,2,0,45,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,200,32,32,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,24,43,261,18,16,0,2,12,2,33,125,0,80,921,103,110,18,195,2637,96,16,1071,18,5,26,3994,6,582,6842,29,1763,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,433,44,212,63,33,24,3,24,45,74,6,0,67,12,65,1,2,0,15,4,10,7381,42,31,98,114,8702,3,2,6,2,1,2,290,16,0,30,2,3,0,15,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,7,5,262,61,147,44,11,6,17,0,322,29,19,43,485,27,229,29,3,0,208,30,2,2,2,1,2,6,3,4,10,1,225,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4381,3,5773,3,7472,16,621,2467,541,1507,4938,6,8489],Hi="\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0897-\u089F\u08CA-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3C\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0CF3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECE\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u180F-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1ABF-\u1ADD\u1AE0-\u1AEB\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\u30FB\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F\uFF65",vt="\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC",Fe={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},je="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",Ki={5:je,"5module":je+" export import",6:je+" const class extends export import super"},bt=/^in(stanceof)?$/,Ji=new RegExp("["+vt+"]"),Xi=new RegExp("["+vt+Hi+"]");function Ge(e,t){for(var i=65536,r=0;r<t.length;r+=2){if(i+=t[r],i>e)return!1;if(i+=t[r+1],i>=e)return!0}return!1}function j(e,t){return e<65?e===36:e<91?!0:e<97?e===95:e<123?!0:e<=65535?e>=170&&Ji.test(String.fromCharCode(e)):t===!1?!1:Ge(e,gt)}function K(e,t){return e<48?e===36:e<58?!0:e<65?!1:e<91?!0:e<97?e===95:e<123?!0:e<=65535?e>=170&&Xi.test(String.fromCharCode(e)):t===!1?!1:Ge(e,gt)||Ge(e,qi)}var _=function(t,i){i===void 0&&(i={}),this.label=t,this.keyword=i.keyword,this.beforeExpr=!!i.beforeExpr,this.startsExpr=!!i.startsExpr,this.isLoop=!!i.isLoop,this.isAssign=!!i.isAssign,this.prefix=!!i.prefix,this.postfix=!!i.postfix,this.binop=i.binop||null,this.updateContext=null};function V(e,t){return new _(e,{beforeExpr:!0,binop:t})}var O={beforeExpr:!0},L={startsExpr:!0},Ke={};function C(e,t){return t===void 0&&(t={}),t.keyword=e,Ke[e]=new _(e,t)}var a={num:new _("num",L),regexp:new _("regexp",L),string:new _("string",L),name:new _("name",L),privateId:new _("privateId",L),eof:new _("eof"),bracketL:new _("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new _("]"),braceL:new _("{",{beforeExpr:!0,startsExpr:!0}),braceR:new _("}"),parenL:new _("(",{beforeExpr:!0,startsExpr:!0}),parenR:new _(")"),comma:new _(",",O),semi:new _(";",O),colon:new _(":",O),dot:new _("."),question:new _("?",O),questionDot:new _("?."),arrow:new _("=>",O),template:new _("template"),invalidTemplate:new _("invalidTemplate"),ellipsis:new _("...",O),backQuote:new _("`",L),dollarBraceL:new _("${",{beforeExpr:!0,startsExpr:!0}),eq:new _("=",{beforeExpr:!0,isAssign:!0}),assign:new _("_=",{beforeExpr:!0,isAssign:!0}),incDec:new _("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new _("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:V("||",1),logicalAND:V("&&",2),bitwiseOR:V("|",3),bitwiseXOR:V("^",4),bitwiseAND:V("&",5),equality:V("==/!=/===/!==",6),relational:V("</>/<=/>=",7),bitShift:V("<</>>/>>>",8),plusMin:new _("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:V("%",10),star:V("*",10),slash:V("/",10),starstar:new _("**",{beforeExpr:!0}),coalesce:V("??",1),_break:C("break"),_case:C("case",O),_catch:C("catch"),_continue:C("continue"),_debugger:C("debugger"),_default:C("default",O),_do:C("do",{isLoop:!0,beforeExpr:!0}),_else:C("else",O),_finally:C("finally"),_for:C("for",{isLoop:!0}),_function:C("function",L),_if:C("if"),_return:C("return",O),_switch:C("switch"),_throw:C("throw",O),_try:C("try"),_var:C("var"),_const:C("const"),_while:C("while",{isLoop:!0}),_with:C("with"),_new:C("new",{beforeExpr:!0,startsExpr:!0}),_this:C("this",L),_super:C("super",L),_class:C("class",L),_extends:C("extends",O),_export:C("export"),_import:C("import",L),_null:C("null",L),_true:C("true",L),_false:C("false",L),_in:C("in",{beforeExpr:!0,binop:7}),_instanceof:C("instanceof",{beforeExpr:!0,binop:7}),_typeof:C("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:C("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:C("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},R=/\r\n?|\n|\u2028|\u2029/,zi=new RegExp(R.source,"g");function ee(e){return e===10||e===13||e===8232||e===8233}function St(e,t,i){i===void 0&&(i=e.length);for(var r=t;r<i;r++){var s=e.charCodeAt(r);if(ee(s))return r<i-1&&s===13&&e.charCodeAt(r+1)===10?r+2:r+1}return-1}var Ct=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/,T=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,_t=Object.prototype,Qi=_t.hasOwnProperty,Yi=_t.toString,te=Object.hasOwn||(function(e,t){return Qi.call(e,t)}),ft=Array.isArray||(function(e){return Yi.call(e)==="[object Array]"}),dt=Object.create(null);function H(e){return dt[e]||(dt[e]=new RegExp("^(?:"+e.replace(/ /g,"|")+")$"))}function G(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode((e>>10)+55296,(e&1023)+56320))}var Zi=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,ue=function(t,i){this.line=t,this.column=i};ue.prototype.offset=function(t){return new ue(this.line,this.column+t)};var Se=function(t,i,r){this.start=i,this.end=r,t.sourceFile!==null&&(this.source=t.sourceFile)};function Et(e,t){for(var i=1,r=0;;){var s=St(e,r,t);if(s<0)return new ue(i,t-r);++i,r=s}}var We={ecmaVersion:null,sourceType:"script",strict:!1,onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,checkPrivateFields:!0,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},mt=!1;function $i(e){var t={};for(var i in We)t[i]=e&&te(e,i)?e[i]:We[i];if(t.ecmaVersion==="latest"?t.ecmaVersion=1e8:t.ecmaVersion==null?(!mt&&typeof console=="object"&&console.warn&&(mt=!0,console.warn(`Since Acorn 8.0.0, options.ecmaVersion is required.+Defaulting to 2020, but this will stop working in the future.`)),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),t.allowReserved==null&&(t.allowReserved=t.ecmaVersion<5),(!e||e.allowHashBang==null)&&(t.allowHashBang=t.ecmaVersion>=14),ft(t.onToken)){var r=t.onToken;t.onToken=function(s){return r.push(s)}}if(ft(t.onComment)&&(t.onComment=er(t,t.onComment)),t.sourceType==="commonjs"&&t.allowAwaitOutsideFunction)throw new Error("Cannot use allowAwaitOutsideFunction with sourceType: commonjs");return t}function er(e,t){return function(i,r,s,n,o,h){var c={type:i?"Block":"Line",value:r,start:s,end:n};e.locations&&(c.loc=new Se(this,o,h)),e.ranges&&(c.range=[s,n]),t.push(c)}}var X=1,z=2,Je=4,kt=8,Xe=16,At=32,Ce=64,Tt=128,Q=256,he=512,wt=1024,_e=X|z|Q;function ze(e,t){return z|(e?Je:0)|(t?kt:0)}var ye=0,Qe=1,q=2,It=3,Pt=4,Nt=5,A=function(t,i,r){this.options=t=$i(t),this.sourceFile=t.sourceFile,this.keywords=H(Ki[t.ecmaVersion>=6?6:t.sourceType==="module"?"5module":5]);var s="";t.allowReserved!==!0&&(s=Fe[t.ecmaVersion>=6?6:t.ecmaVersion===5?5:3],t.sourceType==="module"&&(s+=" await")),this.reservedWords=H(s);var n=(s?s+" ":"")+Fe.strict;this.reservedWordsStrict=H(n),this.reservedWordsStrictBind=H(n+" "+Fe.strictBind),this.input=String(i),this.containsEsc=!1,r?(this.pos=r,this.lineStart=this.input.lastIndexOf(`+`,r-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(R).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=a.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule=t.sourceType==="module",this.strict=this.inModule||t.strict===!0||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),this.pos===0&&t.allowHashBang&&this.input.slice(0,2)==="#!"&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(this.options.sourceType==="commonjs"?z:X),this.regexpState=null,this.privateNameStack=[]},M={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowReturn:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},allowUsing:{configurable:!0},inClassStaticBlock:{configurable:!0}};A.prototype.parse=function(){var t=this,i=this.options.program||this.startNode();return this.nextToken(),this.catchStackOverflow(function(){return t.parseTopLevel(i)})};M.inFunction.get=function(){return(this.currentVarScope().flags&z)>0};M.inGenerator.get=function(){return(this.currentVarScope().flags&kt)>0};M.inAsync.get=function(){return(this.currentVarScope().flags&Je)>0};M.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e],i=t.flags;if(i&(Q|he))return!1;if(i&z)return(i&Je)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction};M.allowReturn.get=function(){return!!(this.inFunction||this.options.allowReturnOutsideFunction&&this.currentVarScope().flags&X)};M.allowSuper.get=function(){var e=this.currentThisScope(),t=e.flags;return(t&Ce)>0||this.options.allowSuperOutsideMethod};M.allowDirectSuper.get=function(){return(this.currentThisScope().flags&Tt)>0};M.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())};M.allowNewDotTarget.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e],i=t.flags;if(i&(Q|he)||i&z&&!(i&Xe))return!0}return!1};M.allowUsing.get=function(){var e=this.currentScope(),t=e.flags;return!(t&wt||!this.inModule&&t&X)};M.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&Q)>0};A.extend=function(){for(var t=[],i=arguments.length;i--;)t[i]=arguments[i];for(var r=this,s=0;s<t.length;s++)r=t[s](r);return r};A.parse=function(t,i){return new this(i,t).parse()};A.parseExpressionAt=function(t,i,r){var s=new this(r,t,i);return s.nextToken(),s.parseExpression()};A.tokenizer=function(t,i){return new this(i,t)};Object.defineProperties(A.prototype,M);var P=A.prototype,tr=/^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/;P.strictDirective=function(e){if(this.options.ecmaVersion<5)return!1;for(;;){T.lastIndex=e,e+=T.exec(this.input)[0].length;var t=tr.exec(this.input.slice(e));if(!t)return!1;if((t[1]||t[2])==="use strict"){T.lastIndex=e+t[0].length;var i=T.exec(this.input),r=i.index+i[0].length,s=this.input.charAt(r);return s===";"||s==="}"||R.test(i[0])&&!(/[(`.[+\-/*%<>=,?^&]/.test(s)||s==="!"&&this.input.charAt(r+1)==="=")}e+=t[0].length,T.lastIndex=e,e+=T.exec(this.input)[0].length,this.input[e]===";"&&e++}};P.eat=function(e){return this.type===e?(this.next(),!0):!1};P.isContextual=function(e){return this.type===a.name&&this.value===e&&!this.containsEsc};P.eatContextual=function(e){return this.isContextual(e)?(this.next(),!0):!1};P.catchStackOverflow=function(e){try{return e()}catch(t){if(t instanceof Error&&(/\bstack\b.*\b(exceeded|overflow)\b/i.test(t.message)||/\btoo much recursion\b/i.test(t.message)))this.raise(this.start,"Not enough stack space to parse input");else throw t}};P.expectContextual=function(e){this.eatContextual(e)||this.unexpected()};P.canInsertSemicolon=function(){return this.type===a.eof||this.type===a.braceR||R.test(this.input.slice(this.lastTokEnd,this.start))};P.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0};P.semicolon=function(){!this.eat(a.semi)&&!this.insertSemicolon()&&this.unexpected()};P.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0};P.expect=function(e){this.eat(e)||this.unexpected()};P.unexpected=function(e){this.raise(e??this.start,"Unexpected token")};var Ee=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};P.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var i=t?e.parenthesizedAssign:e.parenthesizedBind;i>-1&&this.raiseRecoverable(i,t?"Assigning to rvalue":"Parenthesized pattern")}};P.checkExpressionErrors=function(e,t){if(!e)return!1;var i=e.shorthandAssign,r=e.doubleProto;if(!t)return i>=0||r>=0;i>=0&&this.raise(i,"Shorthand property assignments are valid only in destructuring patterns"),r>=0&&this.raiseRecoverable(r,"Redefinition of __proto__ property")};P.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos<this.awaitPos)&&this.raise(this.yieldPos,"Yield expression cannot be a default value"),this.awaitPos&&this.raise(this.awaitPos,"Await expression cannot be a default value")};P.isSimpleAssignTarget=function(e){return e.type==="ParenthesizedExpression"?this.isSimpleAssignTarget(e.expression):e.type==="Identifier"||e.type==="MemberExpression"};var d=A.prototype;d.parseTopLevel=function(e){var t=Object.create(null);for(e.body||(e.body=[]);this.type!==a.eof;){var i=this.parseStatement(null,!0,t);e.body.push(i)}if(this.inModule)for(var r=0,s=Object.keys(this.undefinedExports);r<s.length;r+=1){var n=s[r];this.raiseRecoverable(this.undefinedExports[n].start,"Export '"+n+"' is not defined")}return this.adaptDirectivePrologue(e.body),this.next(),e.sourceType=this.options.sourceType==="commonjs"?"script":this.options.sourceType,this.finishNode(e,"Program")};var Ye={kind:"loop"},ir={kind:"switch"};d.isLet=function(e){if(this.options.ecmaVersion<6||!this.isContextual("let"))return!1;T.lastIndex=this.pos;var t=T.exec(this.input),i=this.pos+t[0].length,r=this.fullCharCodeAt(i);if(r===91||r===92)return!0;if(e)return!1;if(r===123)return!0;if(j(r)){var s=i;do i+=r<=65535?1:2;while(K(r=this.fullCharCodeAt(i)));if(r===92)return!0;var n=this.input.slice(s,i);if(!bt.test(n))return!0}return!1};d.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;T.lastIndex=this.pos;var e=T.exec(this.input),t=this.pos+e[0].length,i;return!R.test(this.input.slice(this.pos,t))&&this.input.slice(t,t+8)==="function"&&(t+8===this.input.length||!(K(i=this.fullCharCodeAt(t+8))||i===92))};d.isUsingKeyword=function(e,t){if(this.options.ecmaVersion<17||!this.isContextual(e?"await":"using"))return!1;T.lastIndex=this.pos;var i=T.exec(this.input),r=this.pos+i[0].length;if(R.test(this.input.slice(this.pos,r)))return!1;if(e){var s=r+5,n;if(this.input.slice(r,s)!=="using"||s===this.input.length||K(n=this.fullCharCodeAt(s))||n===92)return!1;T.lastIndex=s;var o=T.exec(this.input);if(r=s+o[0].length,o&&R.test(this.input.slice(s,r)))return!1}var h=this.fullCharCodeAt(r);if(!j(h)&&h!==92)return!1;var c=r;do r+=h<=65535?1:2;while(K(h=this.fullCharCodeAt(r)));if(h===92)return!0;var l=this.input.slice(c,r);if(bt.test(l))return!1;if(t&&!e&&l==="of"){T.lastIndex=r;var m=T.exec(this.input);if(r=r+m[0].length,this.input.charCodeAt(r)!==61||(h=this.input.charCodeAt(r+1))===61||h===62)return!1}return!0};d.isAwaitUsing=function(e){return this.isUsingKeyword(!0,e)};d.isUsing=function(e){return this.isUsingKeyword(!1,e)};d.parseStatement=function(e,t,i){var r=this.type,s=this.startNode(),n;switch(this.isLet(e)&&(r=a._var,n="let"),r){case a._break:case a._continue:return this.parseBreakContinueStatement(s,r.keyword);case a._debugger:return this.parseDebuggerStatement(s);case a._do:return this.parseDoStatement(s);case a._for:return this.parseForStatement(s);case a._function:return e&&(this.strict||e!=="if"&&e!=="label")&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(s,!1,!e);case a._class:return e&&this.unexpected(),this.parseClass(s,!0);case a._if:return this.parseIfStatement(s);case a._return:return this.parseReturnStatement(s);case a._switch:return this.parseSwitchStatement(s);case a._throw:return this.parseThrowStatement(s);case a._try:return this.parseTryStatement(s);case a._const:case a._var:return n=n||this.value,e&&n!=="var"&&this.unexpected(),this.parseVarStatement(s,n);case a._while:return this.parseWhileStatement(s);case a._with:return this.parseWithStatement(s);case a.braceL:return this.parseBlock(!0,s);case a.semi:return this.parseEmptyStatement(s);case a._export:case a._import:if(this.options.ecmaVersion>10&&r===a._import){T.lastIndex=this.pos;var o=T.exec(this.input),h=this.pos+o[0].length,c=this.input.charCodeAt(h);if(c===40||c===46)return this.parseExpressionStatement(s,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),r===a._import?this.parseImport(s):this.parseExport(s,i);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(s,!0,!e);var l=this.isAwaitUsing(!1)?"await using":this.isUsing(!1)?"using":null;if(l)return this.allowUsing||this.raise(this.start,"Using declaration cannot appear in the top level when source type is `script` or in the bare case statement"),e&&this.raise(this.start,"Using declaration is not allowed in single-statement positions"),l==="await using"&&(this.canAwait||this.raise(this.start,"Await using cannot appear outside of async function"),this.next()),this.next(),this.parseVar(s,!1,l),this.semicolon(),this.finishNode(s,"VariableDeclaration");var m=this.value,S=this.parseExpression();return r===a.name&&S.type==="Identifier"&&this.eat(a.colon)?this.parseLabeledStatement(s,m,S,e):this.parseExpressionStatement(s,S)}};d.parseBreakContinueStatement=function(e,t){var i=t==="break";this.next(),this.eat(a.semi)||this.insertSemicolon()?e.label=null:this.type!==a.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var r=0;r<this.labels.length;++r){var s=this.labels[r];if((e.label==null||s.name===e.label.name)&&(s.kind!=null&&(i||s.kind==="loop")||e.label&&i))break}return r===this.labels.length&&this.raise(e.start,"Unsyntactic "+t),this.finishNode(e,i?"BreakStatement":"ContinueStatement")};d.parseDebuggerStatement=function(e){return this.next(),this.semicolon(),this.finishNode(e,"DebuggerStatement")};d.parseDoStatement=function(e){return this.next(),this.labels.push(Ye),e.body=this.parseStatement("do"),this.labels.pop(),this.expect(a._while),e.test=this.parseParenExpression(),this.options.ecmaVersion>=6?this.eat(a.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")};d.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(Ye),this.enterScope(0),this.expect(a.parenL),this.type===a.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var i=this.isLet();if(this.type===a._var||this.type===a._const||i){var r=this.startNode(),s=i?"let":this.value;return this.next(),this.parseVar(r,!0,s),this.finishNode(r,"VariableDeclaration"),this.parseForAfterInit(e,r,t)}var n=this.isContextual("let"),o=!1,h=this.isUsing(!0)?"using":this.isAwaitUsing(!0)?"await using":null;if(h){var c=this.startNode();return this.next(),h==="await using"&&(this.canAwait||this.raise(this.start,"Await using cannot appear outside of async function"),this.next()),this.parseVar(c,!0,h),this.finishNode(c,"VariableDeclaration"),this.parseForAfterInit(e,c,t)}var l=this.containsEsc,m=new Ee,S=this.start,E=t>-1?this.parseExprSubscripts(m,"await"):this.parseExpression(!0,m);return this.type===a._in||(o=this.options.ecmaVersion>=6&&this.isContextual("of"))?(t>-1?(this.type===a._in&&this.unexpected(t),e.await=!0):o&&this.options.ecmaVersion>=8&&(E.start===S&&!l&&E.type==="Identifier"&&E.name==="async"?this.unexpected():this.options.ecmaVersion>=9&&(e.await=!1)),n&&o&&this.raise(E.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(E,!1,m),this.checkLValPattern(E),this.parseForIn(e,E)):(this.checkExpressionErrors(m,!0),t>-1&&this.unexpected(t),this.parseFor(e,E))};d.parseForAfterInit=function(e,t,i){return(this.type===a._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&t.declarations.length===1?(this.type===a._in?((t.kind==="using"||t.kind==="await using")&&!t.declarations[0].init&&this.raise(this.start,"Using declaration is not allowed in for-in loops"),this.options.ecmaVersion>=9&&i>-1&&this.unexpected(i)):this.options.ecmaVersion>=9&&(e.await=i>-1),this.parseForIn(e,t)):(i>-1&&this.unexpected(i),this.parseFor(e,t))};d.parseFunctionStatement=function(e,t,i){return this.next(),this.parseFunction(e,oe|(i?0:qe),!1,t)};d.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(a._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")};d.parseReturnStatement=function(e){return this.allowReturn||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(a.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")};d.parseSwitchStatement=function(e){this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(a.braceL),this.labels.push(ir),this.enterScope(wt);for(var t,i=!1;this.type!==a.braceR;)if(this.type===a._case||this.type===a._default){var r=this.type===a._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),r?t.test=this.parseExpression():(i&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),i=!0,t.test=null),this.expect(a.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")};d.parseThrowStatement=function(e){return this.next(),R.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var rr=[];d.parseCatchClauseParam=function(){var e=this.parseBindingAtom(),t=e.type==="Identifier";return this.enterScope(t?At:0),this.checkLValPattern(e,t?Pt:q),this.expect(a.parenR),e};d.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===a._catch){var t=this.startNode();this.next(),this.eat(a.parenL)?t.param=this.parseCatchClauseParam():(this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0)),t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(a._finally)?this.parseBlock():null,!e.handler&&!e.finalizer&&this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")};d.parseVarStatement=function(e,t,i){return this.next(),this.parseVar(e,!1,t,i),this.semicolon(),this.finishNode(e,"VariableDeclaration")};d.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(Ye),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")};d.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")};d.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")};d.parseLabeledStatement=function(e,t,i,r){for(var s=0,n=this.labels;s<n.length;s+=1){var o=n[s];o.name===t&&this.raise(i.start,"Label '"+t+"' is already declared")}for(var h=this.type.isLoop?"loop":this.type===a._switch?"switch":null,c=this.labels.length-1;c>=0;c--){var l=this.labels[c];if(l.statementStart===e.start)l.statementStart=this.start,l.kind=h;else break}return this.labels.push({name:t,kind:h,statementStart:this.start}),e.body=this.parseStatement(r?r.indexOf("label")===-1?r+"label":r:"label"),this.labels.pop(),e.label=i,this.finishNode(e,"LabeledStatement")};d.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")};d.parseBlock=function(e,t,i){for(e===void 0&&(e=!0),t===void 0&&(t=this.startNode()),t.body=[],this.expect(a.braceL),e&&this.enterScope(0);this.type!==a.braceR;){var r=this.parseStatement(null);t.body.push(r)}return i&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")};d.parseFor=function(e,t){return e.init=t,this.expect(a.semi),e.test=this.type===a.semi?null:this.parseExpression(),this.expect(a.semi),e.update=this.type===a.parenR?null:this.parseExpression(),this.expect(a.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")};d.parseForIn=function(e,t){var i=this.type===a._in;return this.next(),t.type==="VariableDeclaration"&&t.declarations[0].init!=null&&(!i||this.options.ecmaVersion<8||this.strict||t.kind!=="var"||t.declarations[0].id.type!=="Identifier")&&this.raise(t.start,(i?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=i?this.parseExpression():this.parseMaybeAssign(),this.expect(a.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,i?"ForInStatement":"ForOfStatement")};d.parseVar=function(e,t,i,r){for(e.declarations=[],e.kind=i;;){var s=this.startNode();if(this.parseVarId(s,i),this.eat(a.eq)?s.init=this.parseMaybeAssign(t):!r&&i==="const"&&!(this.type===a._in||this.options.ecmaVersion>=6&&this.isContextual("of"))?this.unexpected():!r&&(i==="using"||i==="await using")&&this.options.ecmaVersion>=17&&this.type!==a._in&&!this.isContextual("of")?this.raise(this.lastTokEnd,"Missing initializer in "+i+" declaration"):!r&&s.id.type!=="Identifier"&&!(t&&(this.type===a._in||this.isContextual("of")))?this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):s.init=null,e.declarations.push(this.finishNode(s,"VariableDeclarator")),!this.eat(a.comma))break}return e};d.parseVarId=function(e,t){e.id=t==="using"||t==="await using"?this.parseIdent():this.parseBindingAtom(),this.checkLValPattern(e.id,t==="var"?Qe:q,!1)};var oe=1,qe=2,Lt=4;d.parseFunction=function(e,t,i,r,s){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!r)&&(this.type===a.star&&t&qe&&this.unexpected(),e.generator=this.eat(a.star)),this.options.ecmaVersion>=8&&(e.async=!!r),t&oe&&(e.id=t&Lt&&this.type!==a.name?null:this.parseIdent(),e.id&&!(t&qe)&&this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?Qe:q:It));var n=this.yieldPos,o=this.awaitPos,h=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(ze(e.async,e.generator)),t&oe||(e.id=this.type===a.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,i,!1,s),this.yieldPos=n,this.awaitPos=o,this.awaitIdentPos=h,this.finishNode(e,t&oe?"FunctionDeclaration":"FunctionExpression")};d.parseFunctionParams=function(e){this.expect(a.parenL),e.params=this.parseBindingList(a.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()};d.parseClass=function(e,t){this.next();var i=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var r=this.enterClassBody(),s=this.startNode(),n=!1;for(s.body=[],this.expect(a.braceL);this.type!==a.braceR;){var o=this.parseClassElement(e.superClass!==null);o&&(s.body.push(o),o.type==="MethodDefinition"&&o.kind==="constructor"?(n&&this.raiseRecoverable(o.start,"Duplicate constructor in the same class"),n=!0):o.key&&o.key.type==="PrivateIdentifier"&&sr(r,o)&&this.raiseRecoverable(o.key.start,"Identifier '#"+o.key.name+"' has already been declared"))}return this.strict=i,this.next(),e.body=this.finishNode(s,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")};d.parseClassElement=function(e){if(this.eat(a.semi))return null;var t=this.options.ecmaVersion,i=this.startNode(),r="",s=!1,n=!1,o="method",h=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(a.braceL))return this.parseClassStaticBlock(i),i;this.isClassElementNameStart()||this.type===a.star?h=!0:r="static"}if(i.static=h,!r&&t>=8&&this.eatContextual("async")&&((this.isClassElementNameStart()||this.type===a.star)&&!this.canInsertSemicolon()?n=!0:r="async"),!r&&(t>=9||!n)&&this.eat(a.star)&&(s=!0),!r&&!n&&!s){var c=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?o=c:r=c)}if(r?(i.computed=!1,i.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),i.key.name=r,this.finishNode(i.key,"Identifier")):this.parseClassElementName(i),t<13||this.type===a.parenL||o!=="method"||s||n){var l=!i.static&&ge(i,"constructor"),m=l&&e;l&&o!=="method"&&this.raise(i.key.start,"Constructor can't have get/set modifier"),i.kind=l?"constructor":o,this.parseClassMethod(i,s,n,m)}else this.parseClassField(i);return i};d.isClassElementNameStart=function(){return this.type===a.name||this.type===a.privateId||this.type===a.num||this.type===a.string||this.type===a.bracketL||this.type.keyword};d.parseClassElementName=function(e){this.type===a.privateId?(this.value==="constructor"&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)};d.parseClassMethod=function(e,t,i,r){var s=e.key;e.kind==="constructor"?(t&&this.raise(s.start,"Constructor can't be a generator"),i&&this.raise(s.start,"Constructor can't be an async method")):e.static&&ge(e,"prototype")&&this.raise(s.start,"Classes may not have a static property named prototype");var n=e.value=this.parseMethod(t,i,r);return e.kind==="get"&&n.params.length!==0&&this.raiseRecoverable(n.start,"getter should have no params"),e.kind==="set"&&n.params.length!==1&&this.raiseRecoverable(n.start,"setter should have exactly one param"),e.kind==="set"&&n.params[0].type==="RestElement"&&this.raiseRecoverable(n.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")};d.parseClassField=function(e){return ge(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&ge(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(a.eq)?(this.enterScope(he|Ce),e.value=this.parseMaybeAssign(),this.exitScope()):e.value=null,this.semicolon(),this.finishNode(e,"PropertyDefinition")};d.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(Q|Ce);this.type!==a.braceR;){var i=this.parseStatement(null);e.body.push(i)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")};d.parseClassId=function(e,t){this.type===a.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,q,!1)):(t===!0&&this.unexpected(),e.id=null)};d.parseClassSuper=function(e){e.superClass=this.eat(a._extends)?this.parseExprSubscripts(null,!1):null};d.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared};d.exitClassBody=function(){var e=this.privateNameStack.pop(),t=e.declared,i=e.used;if(this.options.checkPrivateFields)for(var r=this.privateNameStack.length,s=r===0?null:this.privateNameStack[r-1],n=0;n<i.length;++n){var o=i[n];te(t,o.name)||(s?s.used.push(o):this.raiseRecoverable(o.start,"Private field '#"+o.name+"' must be declared in an enclosing class"))}};function sr(e,t){var i=t.key.name,r=e[i],s="true";return t.type==="MethodDefinition"&&(t.kind==="get"||t.kind==="set")&&(s=(t.static?"s":"i")+t.kind),r==="iget"&&s==="iset"||r==="iset"&&s==="iget"||r==="sget"&&s==="sset"||r==="sset"&&s==="sget"?(e[i]="true",!1):r?!0:(e[i]=s,!1)}function ge(e,t){var i=e.computed,r=e.key;return!i&&(r.type==="Identifier"&&r.name===t||r.type==="Literal"&&r.value===t)}d.parseExportAllDeclaration=function(e,t){return this.options.ecmaVersion>=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==a.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")};d.parseExport=function(e,t){if(this.next(),this.eat(a.star))return this.parseExportAllDeclaration(e,t);if(this.eat(a._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),e.declaration.type==="VariableDeclaration"?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null,this.options.ecmaVersion>=16&&(e.attributes=[]);else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==a.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause());else{for(var i=0,r=e.specifiers;i<r.length;i+=1){var s=r[i];this.checkUnreserved(s.local),this.checkLocalExport(s.local),s.local.type==="Literal"&&this.raise(s.local.start,"A string literal cannot be used as an exported binding without `from`.")}e.source=null,this.options.ecmaVersion>=16&&(e.attributes=[])}this.semicolon()}return this.finishNode(e,"ExportNamedDeclaration")};d.parseExportDeclaration=function(e){return this.parseStatement(null)};d.parseExportDefaultDeclaration=function(){var e;if(this.type===a._function||(e=this.isAsyncFunction())){var t=this.startNode();return this.next(),e&&this.next(),this.parseFunction(t,oe|Lt,!1,e)}else if(this.type===a._class){var i=this.startNode();return this.parseClass(i,"nullableID")}else{var r=this.parseMaybeAssign();return this.semicolon(),r}};d.checkExport=function(e,t,i){e&&(typeof t!="string"&&(t=t.type==="Identifier"?t.name:t.value),te(e,t)&&this.raiseRecoverable(i,"Duplicate export '"+t+"'"),e[t]=!0)};d.checkPatternExport=function(e,t){var i=t.type;if(i==="Identifier")this.checkExport(e,t,t.start);else if(i==="ObjectPattern")for(var r=0,s=t.properties;r<s.length;r+=1){var n=s[r];this.checkPatternExport(e,n)}else if(i==="ArrayPattern")for(var o=0,h=t.elements;o<h.length;o+=1){var c=h[o];c&&this.checkPatternExport(e,c)}else i==="Property"?this.checkPatternExport(e,t.value):i==="AssignmentPattern"?this.checkPatternExport(e,t.left):i==="RestElement"&&this.checkPatternExport(e,t.argument)};d.checkVariableExport=function(e,t){if(e)for(var i=0,r=t;i<r.length;i+=1){var s=r[i];this.checkPatternExport(e,s.id)}};d.shouldParseExportStatement=function(){return this.type.keyword==="var"||this.type.keyword==="const"||this.type.keyword==="class"||this.type.keyword==="function"||this.isLet()||this.isAsyncFunction()};d.parseExportSpecifier=function(e){var t=this.startNode();return t.local=this.parseModuleExportName(),t.exported=this.eatContextual("as")?this.parseModuleExportName():t.local,this.checkExport(e,t.exported,t.exported.start),this.finishNode(t,"ExportSpecifier")};d.parseExportSpecifiers=function(e){var t=[],i=!0;for(this.expect(a.braceL);!this.eat(a.braceR);){if(i)i=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;t.push(this.parseExportSpecifier(e))}return t};d.parseImport=function(e){return this.next(),this.type===a.string?(e.specifiers=rr,e.source=this.parseExprAtom()):(e.specifiers=this.parseImportSpecifiers(),this.expectContextual("from"),e.source=this.type===a.string?this.parseExprAtom():this.unexpected()),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ImportDeclaration")};d.parseImportSpecifier=function(){var e=this.startNode();return e.imported=this.parseModuleExportName(),this.eatContextual("as")?e.local=this.parseIdent():(this.checkUnreserved(e.imported),e.local=e.imported),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportSpecifier")};d.parseImportDefaultSpecifier=function(){var e=this.startNode();return e.local=this.parseIdent(),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportDefaultSpecifier")};d.parseImportNamespaceSpecifier=function(){var e=this.startNode();return this.next(),this.expectContextual("as"),e.local=this.parseIdent(),this.checkLValSimple(e.local,q),this.finishNode(e,"ImportNamespaceSpecifier")};d.parseImportSpecifiers=function(){var e=[],t=!0;if(this.type===a.name&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(a.comma)))return e;if(this.type===a.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(a.braceL);!this.eat(a.braceR);){if(t)t=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;e.push(this.parseImportSpecifier())}return e};d.parseWithClause=function(){var e=[];if(!this.eat(a._with))return e;this.expect(a.braceL);for(var t={},i=!0;!this.eat(a.braceR);){if(i)i=!1;else if(this.expect(a.comma),this.afterTrailingComma(a.braceR))break;var r=this.parseImportAttribute(),s=r.key.type==="Identifier"?r.key.name:r.key.value;te(t,s)&&this.raiseRecoverable(r.key.start,"Duplicate attribute key '"+s+"'"),t[s]=!0,e.push(r)}return e};d.parseImportAttribute=function(){var e=this.startNode();return e.key=this.type===a.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never"),this.expect(a.colon),this.type!==a.string&&this.unexpected(),e.value=this.parseExprAtom(),this.finishNode(e,"ImportAttribute")};d.parseModuleExportName=function(){if(this.options.ecmaVersion>=13&&this.type===a.string){var e=this.parseLiteral(this.value);return Zi.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)};d.adaptDirectivePrologue=function(e){for(var t=0;t<e.length&&this.isDirectiveCandidate(e[t]);++t)e[t].directive=e[t].expression.raw.slice(1,-1)};d.isDirectiveCandidate=function(e){return this.options.ecmaVersion>=5&&e.type==="ExpressionStatement"&&e.expression.type==="Literal"&&typeof e.expression.value=="string"&&(this.input[e.start]==='"'||this.input[e.start]==="'")};var B=A.prototype;B.toAssignable=function(e,t,i){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&e.name==="await"&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",i&&this.checkPatternErrors(i,!0);for(var r=0,s=e.properties;r<s.length;r+=1){var n=s[r];this.toAssignable(n,t),n.type==="RestElement"&&(n.argument.type==="ArrayPattern"||n.argument.type==="ObjectPattern")&&this.raise(n.argument.start,"Unexpected token")}break;case"Property":e.kind!=="init"&&this.raise(e.key.start,"Object pattern can't contain getter or setter"),this.toAssignable(e.value,t);break;case"ArrayExpression":e.type="ArrayPattern",i&&this.checkPatternErrors(i,!0),this.toAssignableList(e.elements,t);break;case"SpreadElement":e.type="RestElement",this.toAssignable(e.argument,t),e.argument.type==="AssignmentPattern"&&this.raise(e.argument.start,"Rest elements cannot have a default value");break;case"AssignmentExpression":e.operator!=="="&&this.raise(e.left.end,"Only '=' operator can be used for specifying default value."),e.type="AssignmentPattern",delete e.operator,this.toAssignable(e.left,t);break;case"ParenthesizedExpression":this.toAssignable(e.expression,t,i);break;case"ChainExpression":this.raiseRecoverable(e.start,"Optional chaining cannot appear in left-hand side");break;case"MemberExpression":if(!t)break;default:this.raise(e.start,"Assigning to rvalue")}else i&&this.checkPatternErrors(i,!0);return e};B.toAssignableList=function(e,t){for(var i=e.length,r=0;r<i;r++){var s=e[r];s&&this.toAssignable(s,t)}if(i){var n=e[i-1];this.options.ecmaVersion===6&&t&&n&&n.type==="RestElement"&&n.argument.type!=="Identifier"&&this.unexpected(n.argument.start)}return e};B.parseSpread=function(e){var t=this.startNode();return this.next(),t.argument=this.parseMaybeAssign(!1,e),this.finishNode(t,"SpreadElement")};B.parseRestBinding=function(){var e=this.startNode();return this.next(),this.options.ecmaVersion===6&&this.type!==a.name&&this.unexpected(),e.argument=this.parseBindingAtom(),this.finishNode(e,"RestElement")};B.parseBindingAtom=function(){if(this.options.ecmaVersion>=6)switch(this.type){case a.bracketL:var e=this.startNode();return this.next(),e.elements=this.parseBindingList(a.bracketR,!0,!0),this.finishNode(e,"ArrayPattern");case a.braceL:return this.parseObj(!0)}return this.parseIdent()};B.parseBindingList=function(e,t,i,r){for(var s=[],n=!0;!this.eat(e);)if(n?n=!1:this.expect(a.comma),t&&this.type===a.comma)s.push(null);else{if(i&&this.afterTrailingComma(e))break;if(this.type===a.ellipsis){var o=this.parseRestBinding();this.parseBindingListItem(o),s.push(o),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.expect(e);break}else s.push(this.parseAssignableListItem(r))}return s};B.parseAssignableListItem=function(e){var t=this.parseMaybeDefault(this.start,this.startLoc);return this.parseBindingListItem(t),t};B.parseBindingListItem=function(e){return e};B.parseMaybeDefault=function(e,t,i){if(i=i||this.parseBindingAtom(),this.options.ecmaVersion<6||!this.eat(a.eq))return i;var r=this.startNodeAt(e,t);return r.left=i,r.right=this.parseMaybeAssign(),this.finishNode(r,"AssignmentPattern")};B.checkLValSimple=function(e,t,i){t===void 0&&(t=ye);var r=t!==ye;switch(e.type){case"Identifier":this.strict&&this.reservedWordsStrictBind.test(e.name)&&this.raiseRecoverable(e.start,(r?"Binding ":"Assigning to ")+e.name+" in strict mode"),r&&(t===q&&e.name==="let"&&this.raiseRecoverable(e.start,"let is disallowed as a lexically bound name"),i&&(te(i,e.name)&&this.raiseRecoverable(e.start,"Argument name clash"),i[e.name]=!0),t!==Nt&&this.declareName(e.name,t,e.start));break;case"ChainExpression":this.raiseRecoverable(e.start,"Optional chaining cannot appear in left-hand side");break;case"MemberExpression":r&&this.raiseRecoverable(e.start,"Binding member expression");break;case"ParenthesizedExpression":return r&&this.raiseRecoverable(e.start,"Binding parenthesized expression"),this.checkLValSimple(e.expression,t,i);default:this.raise(e.start,(r?"Binding":"Assigning to")+" rvalue")}};B.checkLValPattern=function(e,t,i){switch(t===void 0&&(t=ye),e.type){case"ObjectPattern":for(var r=0,s=e.properties;r<s.length;r+=1){var n=s[r];this.checkLValInnerPattern(n,t,i)}break;case"ArrayPattern":for(var o=0,h=e.elements;o<h.length;o+=1){var c=h[o];c&&this.checkLValInnerPattern(c,t,i)}break;default:this.checkLValSimple(e,t,i)}};B.checkLValInnerPattern=function(e,t,i){switch(t===void 0&&(t=ye),e.type){case"Property":this.checkLValInnerPattern(e.value,t,i);break;case"AssignmentPattern":this.checkLValPattern(e.left,t,i);break;case"RestElement":this.checkLValPattern(e.argument,t,i);break;default:this.checkLValPattern(e,t,i)}};var F=function(t,i,r,s,n){this.token=t,this.isExpr=!!i,this.preserveSpace=!!r,this.override=s,this.generator=!!n},k={b_stat:new F("{",!1),b_expr:new F("{",!0),b_tmpl:new F("${",!1),p_stat:new F("(",!1),p_expr:new F("(",!0),q_tmpl:new F("`",!0,!0,function(e){return e.tryReadTemplateToken()}),f_stat:new F("function",!1),f_expr:new F("function",!0),f_expr_gen:new F("function",!0,!1,null,!0),f_gen:new F("function",!1,!1,null,!0)},ie=A.prototype;ie.initialContext=function(){return[k.b_stat]};ie.curContext=function(){return this.context[this.context.length-1]};ie.braceIsBlock=function(e){var t=this.curContext();return t===k.f_expr||t===k.f_stat?!0:e===a.colon&&(t===k.b_stat||t===k.b_expr)?!t.isExpr:e===a._return||e===a.name&&this.exprAllowed?R.test(this.input.slice(this.lastTokEnd,this.start)):e===a._else||e===a.semi||e===a.eof||e===a.parenR||e===a.arrow?!0:e===a.braceL?t===k.b_stat:e===a._var||e===a._const||e===a.name?!1:!this.exprAllowed};ie.inGeneratorContext=function(){for(var e=this.context.length-1;e>=1;e--){var t=this.context[e];if(t.token==="function")return t.generator}return!1};ie.updateContext=function(e){var t,i=this.type;i.keyword&&e===a.dot?this.exprAllowed=!1:(t=i.updateContext)?t.call(this,e):this.exprAllowed=i.beforeExpr};ie.overrideContext=function(e){this.curContext()!==e&&(this.context[this.context.length-1]=e)};a.parenR.updateContext=a.braceR.updateContext=function(){if(this.context.length===1){this.exprAllowed=!0;return}var e=this.context.pop();e===k.b_stat&&this.curContext().token==="function"&&(e=this.context.pop()),this.exprAllowed=!e.isExpr};a.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?k.b_stat:k.b_expr),this.exprAllowed=!0};a.dollarBraceL.updateContext=function(){this.context.push(k.b_tmpl),this.exprAllowed=!0};a.parenL.updateContext=function(e){var t=e===a._if||e===a._for||e===a._with||e===a._while;this.context.push(t?k.p_stat:k.p_expr),this.exprAllowed=!0};a.incDec.updateContext=function(){};a._function.updateContext=a._class.updateContext=function(e){e.beforeExpr&&e!==a._else&&!(e===a.semi&&this.curContext()!==k.p_stat)&&!(e===a._return&&R.test(this.input.slice(this.lastTokEnd,this.start)))&&!((e===a.colon||e===a.braceL)&&this.curContext()===k.b_stat)?this.context.push(k.f_expr):this.context.push(k.f_stat),this.exprAllowed=!1};a.colon.updateContext=function(){this.curContext().token==="function"&&this.context.pop(),this.exprAllowed=!0};a.backQuote.updateContext=function(){this.curContext()===k.q_tmpl?this.context.pop():this.context.push(k.q_tmpl),this.exprAllowed=!1};a.star.updateContext=function(e){if(e===a._function){var t=this.context.length-1;this.context[t]===k.f_expr?this.context[t]=k.f_expr_gen:this.context[t]=k.f_gen}this.exprAllowed=!0};a.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&e!==a.dot&&(this.value==="of"&&!this.exprAllowed||this.value==="yield"&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var g=A.prototype;g.checkPropClash=function(e,t,i){if(!(this.options.ecmaVersion>=9&&e.type==="SpreadElement")&&!(this.options.ecmaVersion>=6&&(e.computed||e.method||e.shorthand))){var r=e.key,s;switch(r.type){case"Identifier":s=r.name;break;case"Literal":s=String(r.value);break;default:return}var n=e.kind;if(this.options.ecmaVersion>=6){s==="__proto__"&&n==="init"&&(t.proto&&(i?i.doubleProto<0&&(i.doubleProto=r.start):this.raiseRecoverable(r.start,"Redefinition of __proto__ property")),t.proto=!0);return}s="$"+s;var o=t[s];if(o){var h;n==="init"?h=this.strict&&o.init||o.get||o.set:h=o.init||o[n],h&&this.raiseRecoverable(r.start,"Redefinition of property")}else o=t[s]={init:!1,get:!1,set:!1};o[n]=!0}};g.parseExpression=function(e,t){var i=this;return this.catchStackOverflow(function(){var r=i.start,s=i.startLoc,n=i.parseMaybeAssign(e,t);if(i.type===a.comma){var o=i.startNodeAt(r,s);for(o.expressions=[n];i.eat(a.comma);)o.expressions.push(i.parseMaybeAssign(e,t));return i.finishNode(o,"SequenceExpression")}return n})};g.parseMaybeAssign=function(e,t,i){if(this.isContextual("yield")){if(this.inGenerator)return this.parseYield(e);this.exprAllowed=!1}var r=!1,s=-1,n=-1,o=-1;t?(s=t.parenthesizedAssign,n=t.trailingComma,o=t.doubleProto,t.parenthesizedAssign=t.trailingComma=-1):(t=new Ee,r=!0);var h=this.start,c=this.startLoc;(this.type===a.parenL||this.type===a.name)&&(this.potentialArrowAt=this.start,this.potentialArrowInForAwait=e==="await");var l=this.parseMaybeConditional(e,t);if(i&&(l=i.call(this,l,h,c)),this.type.isAssign){var m=this.startNodeAt(h,c);return m.operator=this.value,this.type===a.eq&&(l=this.toAssignable(l,!1,t)),r||(t.parenthesizedAssign=t.trailingComma=t.doubleProto=-1),t.shorthandAssign>=l.start&&(t.shorthandAssign=-1),this.type===a.eq?this.checkLValPattern(l):this.checkLValSimple(l),m.left=l,this.next(),m.right=this.parseMaybeAssign(e),o>-1&&(t.doubleProto=o),this.finishNode(m,"AssignmentExpression")}else r&&this.checkExpressionErrors(t,!0);return s>-1&&(t.parenthesizedAssign=s),n>-1&&(t.trailingComma=n),l};g.parseMaybeConditional=function(e,t){var i=this.start,r=this.startLoc,s=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return s;if(!(s.type==="ArrowFunctionExpression"&&s.start===i)&&this.eat(a.question)){var n=this.startNodeAt(i,r);return n.test=s,n.consequent=this.parseMaybeAssign(),this.expect(a.colon),n.alternate=this.parseMaybeAssign(e),this.finishNode(n,"ConditionalExpression")}return s};g.parseExprOps=function(e,t){var i=this.start,r=this.startLoc,s=this.parseMaybeUnary(t,!1,!1,e);return this.checkExpressionErrors(t)||s.start===i&&s.type==="ArrowFunctionExpression"?s:this.parseExprOp(s,i,r,-1,e)};g.parseExprOp=function(e,t,i,r,s){var n=this.type.binop;if(n!=null&&(!s||this.type!==a._in)&&n>r){var o=this.type===a.logicalOR||this.type===a.logicalAND,h=this.type===a.coalesce;h&&(n=a.logicalAND.binop);var c=this.value;this.next();var l=this.start,m=this.startLoc,S=this.parseExprOp(this.parseMaybeUnary(null,!1,!1,s),l,m,n,s),E=this.buildBinary(t,i,e,S,c,o||h);return(o&&this.type===a.coalesce||h&&(this.type===a.logicalOR||this.type===a.logicalAND))&&this.raiseRecoverable(this.start,"Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"),this.parseExprOp(E,t,i,r,s)}return e};g.buildBinary=function(e,t,i,r,s,n){r.type==="PrivateIdentifier"&&this.raise(r.start,"Private identifier can only be left side of binary expression");var o=this.startNodeAt(e,t);return o.left=i,o.operator=s,o.right=r,this.finishNode(o,n?"LogicalExpression":"BinaryExpression")};g.parseMaybeUnary=function(e,t,i,r){var s=this.start,n=this.startLoc,o;if(this.isContextual("await")&&this.canAwait)o=this.parseAwait(r),t=!0;else if(this.type.prefix){var h=this.startNode(),c=this.type===a.incDec;h.operator=this.value,h.prefix=!0,this.next(),h.argument=this.parseMaybeUnary(null,!0,c,r),this.checkExpressionErrors(e,!0),c?this.checkLValSimple(h.argument):this.strict&&h.operator==="delete"&&Rt(h.argument)?this.raiseRecoverable(h.start,"Deleting local variable in strict mode"):h.operator==="delete"&&He(h.argument)?this.raiseRecoverable(h.start,"Private fields can not be deleted"):t=!0,o=this.finishNode(h,c?"UpdateExpression":"UnaryExpression")}else if(!t&&this.type===a.privateId)(r||this.privateNameStack.length===0)&&this.options.checkPrivateFields&&this.unexpected(),o=this.parsePrivateIdent(),this.type!==a._in&&this.unexpected();else{if(o=this.parseExprSubscripts(e,r),this.checkExpressionErrors(e))return o;for(;this.type.postfix&&!this.canInsertSemicolon();){var l=this.startNodeAt(s,n);l.operator=this.value,l.prefix=!1,l.argument=o,this.checkLValSimple(o),this.next(),o=this.finishNode(l,"UpdateExpression")}}if(!i&&this.eat(a.starstar))if(t)this.unexpected(this.lastTokStart);else return this.buildBinary(s,n,o,this.parseMaybeUnary(null,!1,!1,r),"**",!1);else return o};function Rt(e){return e.type==="Identifier"||e.type==="ParenthesizedExpression"&&Rt(e.expression)}function He(e){return e.type==="MemberExpression"&&e.property.type==="PrivateIdentifier"||e.type==="ChainExpression"&&He(e.expression)||e.type==="ParenthesizedExpression"&&He(e.expression)}g.parseExprSubscripts=function(e,t){var i=this.start,r=this.startLoc,s=this.parseExprAtom(e,t);if(s.type==="ArrowFunctionExpression"&&this.input.slice(this.lastTokStart,this.lastTokEnd)!==")")return s;var n=this.parseSubscripts(s,i,r,!1,t);return e&&n.type==="MemberExpression"&&(e.parenthesizedAssign>=n.start&&(e.parenthesizedAssign=-1),e.parenthesizedBind>=n.start&&(e.parenthesizedBind=-1),e.trailingComma>=n.start&&(e.trailingComma=-1)),n};g.parseSubscripts=function(e,t,i,r,s){for(var n=this.options.ecmaVersion>=8&&e.type==="Identifier"&&e.name==="async"&&this.lastTokEnd===e.end&&!this.canInsertSemicolon()&&e.end-e.start===5&&this.potentialArrowAt===e.start,o=!1;;){var h=this.parseSubscript(e,t,i,r,n,o,s);if(h.optional&&(o=!0),h===e||h.type==="ArrowFunctionExpression"){if(o){var c=this.startNodeAt(t,i);c.expression=h,h=this.finishNode(c,"ChainExpression")}return h}e=h}};g.shouldParseAsyncArrow=function(){return!this.canInsertSemicolon()&&this.eat(a.arrow)};g.parseSubscriptAsyncArrow=function(e,t,i,r){return this.parseArrowExpression(this.startNodeAt(e,t),i,!0,r)};g.parseSubscript=function(e,t,i,r,s,n,o){var h=this.options.ecmaVersion>=11,c=h&&this.eat(a.questionDot);r&&c&&this.raise(this.lastTokStart,"Optional chaining cannot appear in the callee of new expressions");var l=this.eat(a.bracketL);if(l||c&&this.type!==a.parenL&&this.type!==a.backQuote||this.eat(a.dot)){var m=this.startNodeAt(t,i);m.object=e,l?(m.property=this.parseExpression(),this.expect(a.bracketR)):this.type===a.privateId&&e.type!=="Super"?m.property=this.parsePrivateIdent():m.property=this.parseIdent(this.options.allowReserved!=="never"),m.computed=!!l,h&&(m.optional=c),e=this.finishNode(m,"MemberExpression")}else if(!r&&this.eat(a.parenL)){var S=new Ee,E=this.yieldPos,p=this.awaitPos,x=this.awaitIdentPos;this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0;var y=this.parseExprList(a.parenR,this.options.ecmaVersion>=8,!1,S);if(s&&!c&&this.shouldParseAsyncArrow())return this.checkPatternErrors(S,!1),this.checkYieldAwaitInDefaultParams(),this.awaitIdentPos>0&&this.raise(this.awaitIdentPos,"Cannot use 'await' as identifier inside an async function"),this.yieldPos=E,this.awaitPos=p,this.awaitIdentPos=x,this.parseSubscriptAsyncArrow(t,i,y,o);this.checkExpressionErrors(S,!0),this.yieldPos=E||this.yieldPos,this.awaitPos=p||this.awaitPos,this.awaitIdentPos=x||this.awaitIdentPos;var v=this.startNodeAt(t,i);v.callee=e,v.arguments=y,h&&(v.optional=c),e=this.finishNode(v,"CallExpression")}else if(this.type===a.backQuote){(c||n)&&this.raise(this.start,"Optional chaining cannot appear in the tag of tagged template expressions");var N=this.startNodeAt(t,i);N.tag=e,N.quasi=this.parseTemplate({isTagged:!0}),e=this.finishNode(N,"TaggedTemplateExpression")}return e};g.parseExprAtom=function(e,t,i){this.type===a.slash&&this.readRegexp();var r,s=this.potentialArrowAt===this.start;switch(this.type){case a._super:return this.allowSuper||this.raise(this.start,"'super' keyword outside a method"),r=this.startNode(),this.next(),this.type===a.parenL&&!this.allowDirectSuper&&this.raise(r.start,"super() call outside constructor of a subclass"),this.type!==a.dot&&this.type!==a.bracketL&&this.type!==a.parenL&&this.unexpected(),this.finishNode(r,"Super");case a._this:return r=this.startNode(),this.next(),this.finishNode(r,"ThisExpression");case a.name:var n=this.start,o=this.startLoc,h=this.containsEsc,c=this.parseIdent(!1);if(this.options.ecmaVersion>=8&&!h&&c.name==="async"&&!this.canInsertSemicolon()&&this.eat(a._function))return this.overrideContext(k.f_expr),this.parseFunction(this.startNodeAt(n,o),0,!1,!0,t);if(s&&!this.canInsertSemicolon()){if(this.eat(a.arrow))return this.parseArrowExpression(this.startNodeAt(n,o),[c],!1,t);if(this.options.ecmaVersion>=8&&c.name==="async"&&this.type===a.name&&!h&&(!this.potentialArrowInForAwait||this.value!=="of"||this.containsEsc))return c=this.parseIdent(!1),(this.canInsertSemicolon()||!this.eat(a.arrow))&&this.unexpected(),this.parseArrowExpression(this.startNodeAt(n,o),[c],!0,t)}return c;case a.regexp:var l=this.value;return r=this.parseLiteral(l.value),r.regex={pattern:l.pattern,flags:l.flags},r;case a.num:case a.string:return this.parseLiteral(this.value);case a._null:case a._true:case a._false:return r=this.startNode(),r.value=this.type===a._null?null:this.type===a._true,r.raw=this.type.keyword,this.next(),this.finishNode(r,"Literal");case a.parenL:var m=this.start,S=this.parseParenAndDistinguishExpression(s,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(S)&&(e.parenthesizedAssign=m),e.parenthesizedBind<0&&(e.parenthesizedBind=m)),S;case a.bracketL:return r=this.startNode(),this.next(),r.elements=this.parseExprList(a.bracketR,!0,!0,e),this.finishNode(r,"ArrayExpression");case a.braceL:return this.overrideContext(k.b_expr),this.parseObj(!1,e);case a._function:return r=this.startNode(),this.next(),this.parseFunction(r,0);case a._class:return this.parseClass(this.startNode(),!1);case a._new:return this.parseNew();case a.backQuote:return this.parseTemplate();case a._import:return this.options.ecmaVersion>=11?this.parseExprImport(i):this.unexpected();default:return this.parseExprAtomDefault()}};g.parseExprAtomDefault=function(){this.unexpected()};g.parseExprImport=function(e){var t=this.startNode();if(this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import"),this.next(),this.type===a.parenL&&!e)return this.parseDynamicImport(t);if(this.type===a.dot){var i=this.startNodeAt(t.start,t.loc&&t.loc.start);return i.name="import",t.meta=this.finishNode(i,"Identifier"),this.parseImportMeta(t)}else this.unexpected()};g.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),this.options.ecmaVersion>=16)this.eat(a.parenR)?e.options=null:(this.expect(a.comma),this.afterTrailingComma(a.parenR)?e.options=null:(e.options=this.parseMaybeAssign(),this.eat(a.parenR)||(this.expect(a.comma),this.afterTrailingComma(a.parenR)||this.unexpected())));else if(!this.eat(a.parenR)){var t=this.start;this.eat(a.comma)&&this.eat(a.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")};g.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),e.property.name!=="meta"&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),this.options.sourceType!=="module"&&!this.options.allowImportExportEverywhere&&this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")};g.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),t.raw.charCodeAt(t.raw.length-1)===110&&(t.bigint=t.value!=null?t.value.toString():t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")};g.parseParenExpression=function(){this.expect(a.parenL);var e=this.parseExpression();return this.expect(a.parenR),e};g.shouldParseArrow=function(e){return!this.canInsertSemicolon()};g.parseParenAndDistinguishExpression=function(e,t){var i=this.start,r=this.startLoc,s,n=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var o=this.start,h=this.startLoc,c=[],l=!0,m=!1,S=new Ee,E=this.yieldPos,p=this.awaitPos,x;for(this.yieldPos=0,this.awaitPos=0;this.type!==a.parenR;)if(l?l=!1:this.expect(a.comma),n&&this.afterTrailingComma(a.parenR,!0)){m=!0;break}else if(this.type===a.ellipsis){x=this.start,c.push(this.parseParenItem(this.parseRestBinding())),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}else c.push(this.parseMaybeAssign(!1,S,this.parseParenItem));var y=this.lastTokEnd,v=this.lastTokEndLoc;if(this.expect(a.parenR),e&&this.shouldParseArrow(c)&&this.eat(a.arrow))return this.checkPatternErrors(S,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=E,this.awaitPos=p,this.parseParenArrowList(i,r,c,t);(!c.length||m)&&this.unexpected(this.lastTokStart),x&&this.unexpected(x),this.checkExpressionErrors(S,!0),this.yieldPos=E||this.yieldPos,this.awaitPos=p||this.awaitPos,c.length>1?(s=this.startNodeAt(o,h),s.expressions=c,this.finishNodeAt(s,"SequenceExpression",y,v)):s=c[0]}else s=this.parseParenExpression();if(this.options.preserveParens){var N=this.startNodeAt(i,r);return N.expression=s,this.finishNode(N,"ParenthesizedExpression")}else return s};g.parseParenItem=function(e){return e};g.parseParenArrowList=function(e,t,i,r){return this.parseArrowExpression(this.startNodeAt(e,t),i,!1,r)};var ar=[];g.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode();if(this.next(),this.options.ecmaVersion>=6&&this.type===a.dot){var t=this.startNodeAt(e.start,e.loc&&e.loc.start);t.name="new",e.meta=this.finishNode(t,"Identifier"),this.next();var i=this.containsEsc;return e.property=this.parseIdent(!0),e.property.name!=="target"&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),i&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var r=this.start,s=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),r,s,!0,!1),e.callee.type==="Super"&&this.raiseRecoverable(r,"Invalid use of 'super'"),this.eat(a.parenL)?e.arguments=this.parseExprList(a.parenR,this.options.ecmaVersion>=8,!1):e.arguments=ar,this.finishNode(e,"NewExpression")};g.parseTemplateElement=function(e){var t=e.isTagged,i=this.startNode();return this.type===a.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),i.value={raw:this.value.replace(/\r\n?/g,` `),cooked:null}):i.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,`-`),cooked:this.value},this.next(),i.tail=this.type===a.backQuote,this.finishNode(i,"TemplateElement")};g.parseTemplate=function(e){e===void 0&&(e={});var t=e.isTagged;t===void 0&&(t=!1);var i=this.startNode();this.next(),i.expressions=[];var r=this.parseTemplateElement({isTagged:t});for(i.quasis=[r];!r.tail;)this.type===a.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(a.dollarBraceL),i.expressions.push(this.parseExpression()),this.expect(a.braceR),i.quasis.push(r=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(i,"TemplateLiteral")};g.isAsyncProp=function(e){return!e.computed&&e.key.type==="Identifier"&&e.key.name==="async"&&(this.type===a.name||this.type===a.num||this.type===a.string||this.type===a.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===a.star)&&!R.test(this.input.slice(this.lastTokEnd,this.start))};g.parseObj=function(e,t){var i=this.startNode(),r=!0,s={};for(i.properties=[],this.next();!this.eat(a.braceR);){if(r)r=!1;else if(this.expect(a.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(a.braceR))break;var n=this.parseProperty(e,t);e||this.checkPropClash(n,s,t),i.properties.push(n)}return this.finishNode(i,e?"ObjectPattern":"ObjectExpression")};g.parseProperty=function(e,t){var i=this.startNode(),r,s,n,o;if(this.options.ecmaVersion>=9&&this.eat(a.ellipsis))return e?(i.argument=this.parseIdent(!1),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.finishNode(i,"RestElement")):(i.argument=this.parseMaybeAssign(!1,t),this.type===a.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(i,"SpreadElement"));this.options.ecmaVersion>=6&&(i.method=!1,i.shorthand=!1,(e||t)&&(n=this.start,o=this.startLoc),e||(r=this.eat(a.star)));var c=this.containsEsc;return this.parsePropertyName(i),!e&&!c&&this.options.ecmaVersion>=8&&!r&&this.isAsyncProp(i)?(s=!0,r=this.options.ecmaVersion>=9&&this.eat(a.star),this.parsePropertyName(i)):s=!1,this.parsePropertyValue(i,e,r,s,n,o,t,c),this.finishNode(i,"Property")};g.parseGetterSetter=function(e){var t=e.key.name;this.parsePropertyName(e),e.value=this.parseMethod(!1),e.kind=t;var i=e.kind==="get"?0:1;if(e.value.params.length!==i){var r=e.value.start;e.kind==="get"?this.raiseRecoverable(r,"getter should have no params"):this.raiseRecoverable(r,"setter should have exactly one param")}else e.kind==="set"&&e.value.params[0].type==="RestElement"&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")};g.parsePropertyValue=function(e,t,i,r,s,n,o,c){(i||r)&&this.type===a.colon&&this.unexpected(),this.eat(a.colon)?(e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,o),e.kind="init"):this.options.ecmaVersion>=6&&this.type===a.parenL?(t&&this.unexpected(),e.method=!0,e.value=this.parseMethod(i,r),e.kind="init"):!t&&!c&&this.options.ecmaVersion>=5&&!e.computed&&e.key.type==="Identifier"&&(e.key.name==="get"||e.key.name==="set")&&this.type!==a.comma&&this.type!==a.braceR&&this.type!==a.eq?((i||r)&&this.unexpected(),this.parseGetterSetter(e)):this.options.ecmaVersion>=6&&!e.computed&&e.key.type==="Identifier"?((i||r)&&this.unexpected(),this.checkUnreserved(e.key),e.key.name==="await"&&!this.awaitIdentPos&&(this.awaitIdentPos=s),t?e.value=this.parseMaybeDefault(s,n,this.copyNode(e.key)):this.type===a.eq&&o?(o.shorthandAssign<0&&(o.shorthandAssign=this.start),e.value=this.parseMaybeDefault(s,n,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.kind="init",e.shorthand=!0):this.unexpected()};g.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(a.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(a.bracketR),e.key;e.computed=!1}return e.key=this.type===a.num||this.type===a.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never")};g.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)};g.parseMethod=function(e,t,i){var r=this.startNode(),s=this.yieldPos,n=this.awaitPos,o=this.awaitIdentPos;return this.initFunction(r),this.options.ecmaVersion>=6&&(r.generator=e),this.options.ecmaVersion>=8&&(r.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(ze(t,r.generator)|Ce|(i?At:0)),this.expect(a.parenL),r.params=this.parseBindingList(a.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(r,!1,!0,!1),this.yieldPos=s,this.awaitPos=n,this.awaitIdentPos=o,this.finishNode(r,"FunctionExpression")};g.parseArrowExpression=function(e,t,i,r){var s=this.yieldPos,n=this.awaitPos,o=this.awaitIdentPos;return this.enterScope(ze(i,!1)|Xe),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!i),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,r),this.yieldPos=s,this.awaitPos=n,this.awaitIdentPos=o,this.finishNode(e,"ArrowFunctionExpression")};g.parseFunctionBody=function(e,t,i,r){var s=t&&this.type!==a.braceL,n=this.strict,o=!1;if(s)e.body=this.parseMaybeAssign(r),e.expression=!0,this.checkParams(e,!1);else{var c=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);(!n||c)&&(o=this.strictDirective(this.end),o&&c&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list"));var h=this.labels;this.labels=[],o&&(this.strict=!0),this.checkParams(e,!n&&!o&&!t&&!i&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,Nt),e.body=this.parseBlock(!1,void 0,o&&!n),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=h}this.exitScope()};g.isSimpleParamList=function(e){for(var t=0,i=e;t<i.length;t+=1){var r=i[t];if(r.type!=="Identifier")return!1}return!0};g.checkParams=function(e,t){for(var i=Object.create(null),r=0,s=e.params;r<s.length;r+=1){var n=s[r];this.checkLValInnerPattern(n,Qe,t?null:i)}};g.parseExprList=function(e,t,i,r){for(var s=[],n=!0;!this.eat(e);){if(n)n=!1;else if(this.expect(a.comma),t&&this.afterTrailingComma(e))break;var o=void 0;i&&this.type===a.comma?o=null:this.type===a.ellipsis?(o=this.parseSpread(r),r&&this.type===a.comma&&r.trailingComma<0&&(r.trailingComma=this.start)):o=this.parseMaybeAssign(!1,r),s.push(o)}return s};g.checkUnreserved=function(e){var t=e.start,i=e.end,r=e.name;if(this.inGenerator&&r==="yield"&&this.raiseRecoverable(t,"Cannot use 'yield' as identifier inside a generator"),this.inAsync&&r==="await"&&this.raiseRecoverable(t,"Cannot use 'await' as identifier inside an async function"),!(this.currentThisScope().flags&_e)&&r==="arguments"&&this.raiseRecoverable(t,"Cannot use 'arguments' in class field initializer"),this.inClassStaticBlock&&(r==="arguments"||r==="await")&&this.raise(t,"Cannot use "+r+" in class static initialization block"),this.keywords.test(r)&&this.raise(t,"Unexpected keyword '"+r+"'"),!(this.options.ecmaVersion<6&&this.input.slice(t,i).indexOf("\\")!==-1)){var s=this.strict?this.reservedWordsStrict:this.reservedWords;s.test(r)&&(!this.inAsync&&r==="await"&&this.raiseRecoverable(t,"Cannot use keyword 'await' outside an async function"),this.raiseRecoverable(t,"The keyword '"+r+"' is reserved"))}};g.parseIdent=function(e){var t=this.parseIdentNode();return this.next(!!e),this.finishNode(t,"Identifier"),e||(this.checkUnreserved(t),t.name==="await"&&!this.awaitIdentPos&&(this.awaitIdentPos=t.start)),t};g.parseIdentNode=function(){var e=this.startNode();return this.type===a.name?e.name=this.value:this.type.keyword?(e.name=this.type.keyword,(e.name==="class"||e.name==="function")&&(this.lastTokEnd!==this.lastTokStart+1||this.input.charCodeAt(this.lastTokStart)!==46)&&this.context.pop(),this.type=a.name):this.unexpected(),e};g.parsePrivateIdent=function(){var e=this.startNode();return this.type===a.privateId?e.name=this.value:this.unexpected(),this.next(),this.finishNode(e,"PrivateIdentifier"),this.options.checkPrivateFields&&(this.privateNameStack.length===0?this.raise(e.start,"Private field '#"+e.name+"' must be declared in an enclosing class"):this.privateNameStack[this.privateNameStack.length-1].used.push(e)),e};g.parseYield=function(e){this.yieldPos||(this.yieldPos=this.start);var t=this.startNode();return this.next(),this.type===a.semi||this.canInsertSemicolon()||this.type!==a.star&&!this.type.startsExpr?(t.delegate=!1,t.argument=null):(t.delegate=this.eat(a.star),t.argument=this.parseMaybeAssign(e)),this.finishNode(t,"YieldExpression")};g.parseAwait=function(e){this.awaitPos||(this.awaitPos=this.start);var t=this.startNode();return this.next(),t.argument=this.parseMaybeUnary(null,!0,!1,e),this.finishNode(t,"AwaitExpression")};var ve=T.prototype;ve.raise=function(e,t){var i=Et(this.input,e);t+=" ("+i.line+":"+i.column+")",this.sourceFile&&(t+=" in "+this.sourceFile);var r=new SyntaxError(t);throw r.pos=e,r.loc=i,r.raisedAt=this.pos,r};ve.raiseRecoverable=ve.raise;ve.curPosition=function(){if(this.options.locations)return new ue(this.curLine,this.pos-this.lineStart)};var J=T.prototype,nr=function(t){this.flags=t,this.var=[],this.lexical=[],this.functions=[]};J.enterScope=function(e){this.scopeStack.push(new nr(e))};J.exitScope=function(){this.scopeStack.pop()};J.treatFunctionsAsVarInScope=function(e){return e.flags&z||!this.inModule&&e.flags&X};J.declareName=function(e,t,i){var r=!1;if(t===q){var s=this.currentScope();r=s.lexical.indexOf(e)>-1||s.functions.indexOf(e)>-1||s.var.indexOf(e)>-1,s.lexical.push(e),this.inModule&&s.flags&X&&delete this.undefinedExports[e]}else if(t===Pt){var n=this.currentScope();n.lexical.push(e)}else if(t===It){var o=this.currentScope();this.treatFunctionsAsVar?r=o.lexical.indexOf(e)>-1:r=o.lexical.indexOf(e)>-1||o.var.indexOf(e)>-1,o.functions.push(e)}else for(var c=this.scopeStack.length-1;c>=0;--c){var h=this.scopeStack[c];if(h.lexical.indexOf(e)>-1&&!(h.flags&Tt&&h.lexical[0]===e)||!this.treatFunctionsAsVarInScope(h)&&h.functions.indexOf(e)>-1){r=!0;break}if(h.var.push(e),this.inModule&&h.flags&X&&delete this.undefinedExports[e],h.flags&_e)break}r&&this.raiseRecoverable(i,"Identifier '"+e+"' has already been declared")};J.checkLocalExport=function(e){this.scopeStack[0].lexical.indexOf(e.name)===-1&&this.scopeStack[0].var.indexOf(e.name)===-1&&(this.undefinedExports[e.name]=e)};J.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]};J.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&(_e|he|Q))return t}};J.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&(_e|he|Q)&&!(t.flags&Xe))return t}};var ke=function(t,i,r){this.type="",this.start=i,this.end=0,t.options.locations&&(this.loc=new Se(t,r)),t.options.directSourceFile&&(this.sourceFile=t.options.directSourceFile),t.options.ranges&&(this.range=[i,0])},ce=T.prototype;ce.startNode=function(){return new ke(this,this.start,this.startLoc)};ce.startNodeAt=function(e,t){return new ke(this,e,t)};function Vt(e,t,i,r){return e.type=t,e.end=i,this.options.locations&&(e.loc.end=r),this.options.ranges&&(e.range[1]=i),e}ce.finishNode=function(e,t){return Vt.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)};ce.finishNodeAt=function(e,t,i,r){return Vt.call(this,e,t,i,r)};ce.copyNode=function(e){var t=new ke(this,e.start,this.startLoc);for(var i in e)t[i]=e[i];return t};var or="Berf Beria_Erfe Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sidetic Sidt Sunu Sunuwar Tai_Yo Tayo Todhri Todr Tolong_Siki Tols Tulu_Tigalari Tutg Unknown Zzzz",Ot="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",Dt=Ot+" Extended_Pictographic",Mt=Dt,Bt=Mt+" EBase EComp EMod EPres ExtPict",Ft=Bt,ur=Ft,hr={9:Ot,10:Dt,11:Mt,12:Bt,13:Ft,14:ur},cr="Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji",pr={9:"",10:"",11:"",12:"",13:"",14:cr},xt="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",jt="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Ut=jt+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",Gt=Ut+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",Wt=Gt+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",qt=Wt+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith",lr=qt+" "+or,fr={9:jt,10:Ut,11:Gt,12:Wt,13:qt,14:lr},Ht={};function dr(e){var t=Ht[e]={binary:H(hr[e]+" "+xt),binaryOfStrings:H(pr[e]),nonBinary:{General_Category:H(xt),Script:H(fr[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(xe=0,Ue=[9,10,11,12,13,14];xe<Ue.length;xe+=1)yt=Ue[xe],dr(yt);var yt,xe,Ue,f=T.prototype,be=function(t,i){this.parent=t,this.base=i||this};be.prototype.separatedFrom=function(t){for(var i=this;i;i=i.parent)for(var r=t;r;r=r.parent)if(i.base===r.base&&i!==r)return!0;return!1};be.prototype.sibling=function(){return new be(this.parent,this.base)};var U=function(t){this.parser=t,this.validFlags="gim"+(t.options.ecmaVersion>=6?"uy":"")+(t.options.ecmaVersion>=9?"s":"")+(t.options.ecmaVersion>=13?"d":"")+(t.options.ecmaVersion>=15?"v":""),this.unicodeProperties=Ht[t.options.ecmaVersion>=14?14:t.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchV=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=Object.create(null),this.backReferenceNames=[],this.branchID=null};U.prototype.reset=function(t,i,r){var s=r.indexOf("v")!==-1,n=r.indexOf("u")!==-1;this.start=t|0,this.source=i+"",this.flags=r,s&&this.parser.options.ecmaVersion>=15?(this.switchU=!0,this.switchV=!0,this.switchN=!0):(this.switchU=n&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=n&&this.parser.options.ecmaVersion>=9)};U.prototype.raise=function(t){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+t)};U.prototype.at=function(t,i){i===void 0&&(i=!1);var r=this.source,s=r.length;if(t>=s)return-1;var n=r.charCodeAt(t);if(!(i||this.switchU)||n<=55295||n>=57344||t+1>=s)return n;var o=r.charCodeAt(t+1);return o>=56320&&o<=57343?(n<<10)+o-56613888:n};U.prototype.nextIndex=function(t,i){i===void 0&&(i=!1);var r=this.source,s=r.length;if(t>=s)return s;var n=r.charCodeAt(t),o;return!(i||this.switchU)||n<=55295||n>=57344||t+1>=s||(o=r.charCodeAt(t+1))<56320||o>57343?t+1:t+2};U.prototype.current=function(t){return t===void 0&&(t=!1),this.at(this.pos,t)};U.prototype.lookahead=function(t){return t===void 0&&(t=!1),this.at(this.nextIndex(this.pos,t),t)};U.prototype.advance=function(t){t===void 0&&(t=!1),this.pos=this.nextIndex(this.pos,t)};U.prototype.eat=function(t,i){return i===void 0&&(i=!1),this.current(i)===t?(this.advance(i),!0):!1};U.prototype.eatChars=function(t,i){i===void 0&&(i=!1);for(var r=this.pos,s=0,n=t;s<n.length;s+=1){var o=n[s],c=this.at(r,i);if(c===-1||c!==o)return!1;r=this.nextIndex(r,i)}return this.pos=r,!0};f.validateRegExpFlags=function(e){for(var t=e.validFlags,i=e.flags,r=!1,s=!1,n=0;n<i.length;n++){var o=i.charAt(n);t.indexOf(o)===-1&&this.raise(e.start,"Invalid regular expression flag"),i.indexOf(o,n+1)>-1&&this.raise(e.start,"Duplicate regular expression flag"),o==="u"&&(r=!0),o==="v"&&(s=!0)}this.options.ecmaVersion>=15&&r&&s&&this.raise(e.start,"Invalid regular expression flag")};function mr(e){for(var t in e)return!0;return!1}f.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&mr(e.groupNames)&&(e.switchN=!0,this.regexp_pattern(e))};f.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames=Object.create(null),e.backReferenceNames.length=0,e.branchID=null,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,i=e.backReferenceNames;t<i.length;t+=1){var r=i[t];e.groupNames[r]||e.raise("Invalid named capture referenced")}};f.regexp_disjunction=function(e){var t=this.options.ecmaVersion>=16;for(t&&(e.branchID=new be(e.branchID,null)),this.regexp_alternative(e);e.eat(124);)t&&(e.branchID=e.branchID.sibling()),this.regexp_alternative(e);t&&(e.branchID=e.branchID.parent),this.regexp_eatQuantifier(e,!0)&&e.raise("Nothing to repeat"),e.eat(123)&&e.raise("Lone quantifier brackets")};f.regexp_alternative=function(e){for(;e.pos<e.source.length&&this.regexp_eatTerm(e););};f.regexp_eatTerm=function(e){return this.regexp_eatAssertion(e)?(e.lastAssertionIsQuantifiable&&this.regexp_eatQuantifier(e)&&e.switchU&&e.raise("Invalid quantifier"),!0):(e.switchU?this.regexp_eatAtom(e):this.regexp_eatExtendedAtom(e))?(this.regexp_eatQuantifier(e),!0):!1};f.regexp_eatAssertion=function(e){var t=e.pos;if(e.lastAssertionIsQuantifiable=!1,e.eat(94)||e.eat(36))return!0;if(e.eat(92)){if(e.eat(66)||e.eat(98))return!0;e.pos=t}if(e.eat(40)&&e.eat(63)){var i=!1;if(this.options.ecmaVersion>=9&&(i=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!i,!0}return e.pos=t,!1};f.regexp_eatQuantifier=function(e,t){return t===void 0&&(t=!1),this.regexp_eatQuantifierPrefix(e,t)?(e.eat(63),!0):!1};f.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)};f.regexp_eatBracedQuantifier=function(e,t){var i=e.pos;if(e.eat(123)){var r=0,s=-1;if(this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(s=e.lastIntValue),e.eat(125)))return s!==-1&&s<r&&!t&&e.raise("numbers out of order in {} quantifier"),!0;e.switchU&&!t&&e.raise("Incomplete quantifier"),e.pos=i}return!1};f.regexp_eatAtom=function(e){return this.regexp_eatPatternCharacters(e)||e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)};f.regexp_eatReverseSolidusAtomEscape=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatAtomEscape(e))return!0;e.pos=t}return!1};f.regexp_eatUncapturingGroup=function(e){var t=e.pos;if(e.eat(40)){if(e.eat(63)){if(this.options.ecmaVersion>=16){var i=this.regexp_eatModifiers(e),r=e.eat(45);if(i||r){for(var s=0;s<i.length;s++){var n=i.charAt(s);i.indexOf(n,s+1)>-1&&e.raise("Duplicate regular expression modifiers")}if(r){var o=this.regexp_eatModifiers(e);!i&&!o&&e.current()===58&&e.raise("Invalid regular expression modifiers");for(var c=0;c<o.length;c++){var h=o.charAt(c);(o.indexOf(h,c+1)>-1||i.indexOf(h)>-1)&&e.raise("Duplicate regular expression modifiers")}}}}if(e.eat(58)){if(this.regexp_disjunction(e),e.eat(41))return!0;e.raise("Unterminated group")}}e.pos=t}return!1};f.regexp_eatCapturingGroup=function(e){if(e.eat(40)){if(this.options.ecmaVersion>=9?this.regexp_groupSpecifier(e):e.current()===63&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1};f.regexp_eatModifiers=function(e){for(var t="",i=0;(i=e.current())!==-1&&xr(i);)t+=G(i),e.advance();return t};function xr(e){return e===105||e===109||e===115}f.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)};f.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1};f.regexp_eatSyntaxCharacter=function(e){var t=e.current();return Kt(t)?(e.lastIntValue=t,e.advance(),!0):!1};function Kt(e){return e===36||e>=40&&e<=43||e===46||e===63||e>=91&&e<=94||e>=123&&e<=125}f.regexp_eatPatternCharacters=function(e){for(var t=e.pos,i=0;(i=e.current())!==-1&&!Kt(i);)e.advance();return e.pos!==t};f.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return t!==-1&&t!==36&&!(t>=40&&t<=43)&&t!==46&&t!==63&&t!==91&&t!==94&&t!==124?(e.advance(),!0):!1};f.regexp_groupSpecifier=function(e){if(e.eat(63)){this.regexp_eatGroupName(e)||e.raise("Invalid group");var t=this.options.ecmaVersion>=16,i=e.groupNames[e.lastStringValue];if(i)if(t)for(var r=0,s=i;r<s.length;r+=1){var n=s[r];n.separatedFrom(e.branchID)||e.raise("Duplicate capture group name")}else e.raise("Duplicate capture group name");t?(i||(e.groupNames[e.lastStringValue]=[])).push(e.branchID):e.groupNames[e.lastStringValue]=!0}};f.regexp_eatGroupName=function(e){if(e.lastStringValue="",e.eat(60)){if(this.regexp_eatRegExpIdentifierName(e)&&e.eat(62))return!0;e.raise("Invalid capture group name")}return!1};f.regexp_eatRegExpIdentifierName=function(e){if(e.lastStringValue="",this.regexp_eatRegExpIdentifierStart(e)){for(e.lastStringValue+=G(e.lastIntValue);this.regexp_eatRegExpIdentifierPart(e);)e.lastStringValue+=G(e.lastIntValue);return!0}return!1};f.regexp_eatRegExpIdentifierStart=function(e){var t=e.pos,i=this.options.ecmaVersion>=11,r=e.current(i);return e.advance(i),r===92&&this.regexp_eatRegExpUnicodeEscapeSequence(e,i)&&(r=e.lastIntValue),yr(r)?(e.lastIntValue=r,!0):(e.pos=t,!1)};function yr(e){return j(e,!0)||e===36||e===95}f.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,i=this.options.ecmaVersion>=11,r=e.current(i);return e.advance(i),r===92&&this.regexp_eatRegExpUnicodeEscapeSequence(e,i)&&(r=e.lastIntValue),gr(r)?(e.lastIntValue=r,!0):(e.pos=t,!1)};function gr(e){return K(e,!0)||e===36||e===95||e===8204||e===8205}f.regexp_eatAtomEscape=function(e){return this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e)?!0:(e.switchU&&(e.current()===99&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)};f.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var i=e.lastIntValue;if(e.switchU)return i>e.maxBackReference&&(e.maxBackReference=i),!0;if(i<=e.numCapturingParens)return!0;e.pos=t}return!1};f.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1};f.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)};f.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1};f.regexp_eatZero=function(e){return e.current()===48&&!Te(e.lookahead())?(e.lastIntValue=0,e.advance(),!0):!1};f.regexp_eatControlEscape=function(e){var t=e.current();return t===116?(e.lastIntValue=9,e.advance(),!0):t===110?(e.lastIntValue=10,e.advance(),!0):t===118?(e.lastIntValue=11,e.advance(),!0):t===102?(e.lastIntValue=12,e.advance(),!0):t===114?(e.lastIntValue=13,e.advance(),!0):!1};f.regexp_eatControlLetter=function(e){var t=e.current();return Jt(t)?(e.lastIntValue=t%32,e.advance(),!0):!1};function Jt(e){return e>=65&&e<=90||e>=97&&e<=122}f.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){t===void 0&&(t=!1);var i=e.pos,r=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(r&&s>=55296&&s<=56319){var n=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var o=e.lastIntValue;if(o>=56320&&o<=57343)return e.lastIntValue=(s-55296)*1024+(o-56320)+65536,!0}e.pos=n,e.lastIntValue=s}return!0}if(r&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&vr(e.lastIntValue))return!0;r&&e.raise("Invalid unicode escape"),e.pos=i}return!1};function vr(e){return e>=0&&e<=1114111}f.regexp_eatIdentityEscape=function(e){if(e.switchU)return this.regexp_eatSyntaxCharacter(e)?!0:e.eat(47)?(e.lastIntValue=47,!0):!1;var t=e.current();return t!==99&&(!e.switchN||t!==107)?(e.lastIntValue=t,e.advance(),!0):!1};f.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do e.lastIntValue=10*e.lastIntValue+(t-48),e.advance();while((t=e.current())>=48&&t<=57);return!0}return!1};var Xt=0,W=1,D=2;f.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(br(t))return e.lastIntValue=-1,e.advance(),W;var i=!1;if(e.switchU&&this.options.ecmaVersion>=9&&((i=t===80)||t===112)){e.lastIntValue=-1,e.advance();var r;if(e.eat(123)&&(r=this.regexp_eatUnicodePropertyValueExpression(e))&&e.eat(125))return i&&r===D&&e.raise("Invalid property name"),r;e.raise("Invalid property name")}return Xt};function br(e){return e===100||e===68||e===115||e===83||e===119||e===87}f.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var i=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,i,r),W}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var s=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,s)}return Xt};f.regexp_validateUnicodePropertyNameAndValue=function(e,t,i){te(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(i)||e.raise("Invalid property value")};f.regexp_validateUnicodePropertyNameOrValue=function(e,t){if(e.unicodeProperties.binary.test(t))return W;if(e.switchV&&e.unicodeProperties.binaryOfStrings.test(t))return D;e.raise("Invalid property name")};f.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";zt(t=e.current());)e.lastStringValue+=G(t),e.advance();return e.lastStringValue!==""};function zt(e){return Jt(e)||e===95}f.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";Sr(t=e.current());)e.lastStringValue+=G(t),e.advance();return e.lastStringValue!==""};function Sr(e){return zt(e)||Te(e)}f.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)};f.regexp_eatCharacterClass=function(e){if(e.eat(91)){var t=e.eat(94),i=this.regexp_classContents(e);return e.eat(93)||e.raise("Unterminated character class"),t&&i===D&&e.raise("Negated character class may contain strings"),!0}return!1};f.regexp_classContents=function(e){return e.current()===93?W:e.switchV?this.regexp_classSetExpression(e):(this.regexp_nonEmptyClassRanges(e),W)};f.regexp_nonEmptyClassRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var i=e.lastIntValue;e.switchU&&(t===-1||i===-1)&&e.raise("Invalid character class"),t!==-1&&i!==-1&&t>i&&e.raise("Range out of order in character class")}}};f.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var i=e.current();(i===99||Zt(i))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var r=e.current();return r!==93?(e.lastIntValue=r,e.advance(),!0):!1};f.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)};f.regexp_classSetExpression=function(e){var t=W,i;if(!this.regexp_eatClassSetRange(e))if(i=this.regexp_eatClassSetOperand(e)){i===D&&(t=D);for(var r=e.pos;e.eatChars([38,38]);){if(e.current()!==38&&(i=this.regexp_eatClassSetOperand(e))){i!==D&&(t=W);continue}e.raise("Invalid character in character class")}if(r!==e.pos)return t;for(;e.eatChars([45,45]);)this.regexp_eatClassSetOperand(e)||e.raise("Invalid character in character class");if(r!==e.pos)return t}else e.raise("Invalid character in character class");for(;;)if(!this.regexp_eatClassSetRange(e)){if(i=this.regexp_eatClassSetOperand(e),!i)return t;i===D&&(t=D)}};f.regexp_eatClassSetRange=function(e){var t=e.pos;if(this.regexp_eatClassSetCharacter(e)){var i=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassSetCharacter(e)){var r=e.lastIntValue;return i!==-1&&r!==-1&&i>r&&e.raise("Range out of order in character class"),!0}e.pos=t}return!1};f.regexp_eatClassSetOperand=function(e){return this.regexp_eatClassSetCharacter(e)?W:this.regexp_eatClassStringDisjunction(e)||this.regexp_eatNestedClass(e)};f.regexp_eatNestedClass=function(e){var t=e.pos;if(e.eat(91)){var i=e.eat(94),r=this.regexp_classContents(e);if(e.eat(93))return i&&r===D&&e.raise("Negated character class may contain strings"),r;e.pos=t}if(e.eat(92)){var s=this.regexp_eatCharacterClassEscape(e);if(s)return s;e.pos=t}return null};f.regexp_eatClassStringDisjunction=function(e){var t=e.pos;if(e.eatChars([92,113])){if(e.eat(123)){var i=this.regexp_classStringDisjunctionContents(e);if(e.eat(125))return i}else e.raise("Invalid escape");e.pos=t}return null};f.regexp_classStringDisjunctionContents=function(e){for(var t=this.regexp_classString(e);e.eat(124);)this.regexp_classString(e)===D&&(t=D);return t};f.regexp_classString=function(e){for(var t=0;this.regexp_eatClassSetCharacter(e);)t++;return t===1?W:D};f.regexp_eatClassSetCharacter=function(e){var t=e.pos;if(e.eat(92))return this.regexp_eatCharacterEscape(e)||this.regexp_eatClassSetReservedPunctuator(e)?!0:e.eat(98)?(e.lastIntValue=8,!0):(e.pos=t,!1);var i=e.current();return i<0||i===e.lookahead()&&Cr(i)||_r(i)?!1:(e.advance(),e.lastIntValue=i,!0)};function Cr(e){return e===33||e>=35&&e<=38||e>=42&&e<=44||e===46||e>=58&&e<=64||e===94||e===96||e===126}function _r(e){return e===40||e===41||e===45||e===47||e>=91&&e<=93||e>=123&&e<=125}f.regexp_eatClassSetReservedPunctuator=function(e){var t=e.current();return Er(t)?(e.lastIntValue=t,e.advance(),!0):!1};function Er(e){return e===33||e===35||e===37||e===38||e===44||e===45||e>=58&&e<=62||e===64||e===96||e===126}f.regexp_eatClassControlLetter=function(e){var t=e.current();return Te(t)||t===95?(e.lastIntValue=t%32,e.advance(),!0):!1};f.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1};f.regexp_eatDecimalDigits=function(e){var t=e.pos,i=0;for(e.lastIntValue=0;Te(i=e.current());)e.lastIntValue=10*e.lastIntValue+(i-48),e.advance();return e.pos!==t};function Te(e){return e>=48&&e<=57}f.regexp_eatHexDigits=function(e){var t=e.pos,i=0;for(e.lastIntValue=0;Qt(i=e.current());)e.lastIntValue=16*e.lastIntValue+Yt(i),e.advance();return e.pos!==t};function Qt(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Yt(e){return e>=65&&e<=70?10+(e-65):e>=97&&e<=102?10+(e-97):e-48}f.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var i=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=t*64+i*8+e.lastIntValue:e.lastIntValue=t*8+i}else e.lastIntValue=t;return!0}return!1};f.regexp_eatOctalDigit=function(e){var t=e.current();return Zt(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)};function Zt(e){return e>=48&&e<=55}f.regexp_eatFixedHexDigits=function(e,t){var i=e.pos;e.lastIntValue=0;for(var r=0;r<t;++r){var s=e.current();if(!Qt(s))return e.pos=i,!1;e.lastIntValue=16*e.lastIntValue+Yt(s),e.advance()}return!0};var Ze=function(t){this.type=t.type,this.value=t.value,this.start=t.start,this.end=t.end,t.options.locations&&(this.loc=new Se(t,t.startLoc,t.endLoc)),t.options.ranges&&(this.range=[t.start,t.end])},b=T.prototype;b.next=function(e){!e&&this.type.keyword&&this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword "+this.type.keyword),this.options.onToken&&this.options.onToken(new Ze(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()};b.getToken=function(){return this.next(),new Ze(this)};typeof Symbol<"u"&&(b[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===a.eof,value:t}}}});b.nextToken=function(){var e=this.curContext();if((!e||!e.preserveSpace)&&this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length)return this.finishToken(a.eof);if(e.override)return e.override(this);this.readToken(this.fullCharCodeAtPos())};b.readToken=function(e){return j(e,this.options.ecmaVersion>=6)||e===92?this.readWord():this.getTokenFromCode(e)};b.fullCharCodeAt=function(e){var t=this.input.charCodeAt(e);if(t<=55295||t>=56320)return t;var i=this.input.charCodeAt(e+1);return i<=56319||i>=57344?t:(t<<10)+i-56613888};b.fullCharCodeAtPos=function(){return this.fullCharCodeAt(this.pos)};b.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,i=this.input.indexOf("*/",this.pos+=2);if(i===-1&&this.raise(this.pos-2,"Unterminated comment"),this.pos=i+2,this.options.locations)for(var r=void 0,s=t;(r=St(this.input,s,this.pos))>-1;)++this.curLine,s=this.lineStart=r;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,i),t,this.pos,e,this.curPosition())};b.skipLineComment=function(e){for(var t=this.pos,i=this.options.onComment&&this.curPosition(),r=this.input.charCodeAt(this.pos+=e);this.pos<this.input.length&&!ee(r);)r=this.input.charCodeAt(++this.pos);this.options.onComment&&this.options.onComment(!1,this.input.slice(t+e,this.pos),t,this.pos,i,this.curPosition())};b.skipSpace=function(){e:for(;this.pos<this.input.length;){var e=this.input.charCodeAt(this.pos);switch(e){case 32:case 160:++this.pos;break;case 13:this.input.charCodeAt(this.pos+1)===10&&++this.pos;case 10:case 8232:case 8233:++this.pos,this.options.locations&&(++this.curLine,this.lineStart=this.pos);break;case 47:switch(this.input.charCodeAt(this.pos+1)){case 42:this.skipBlockComment();break;case 47:this.skipLineComment(2);break;default:break e}break;default:if(e>8&&e<14||e>=5760&&Ct.test(String.fromCharCode(e)))++this.pos;else break e}}};b.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var i=this.type;this.type=e,this.value=t,this.updateContext(i)};b.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&e===46&&t===46?(this.pos+=3,this.finishToken(a.ellipsis)):(++this.pos,this.finishToken(a.dot))};b.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):e===61?this.finishOp(a.assign,2):this.finishOp(a.slash,1)};b.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),i=1,r=e===42?a.star:a.modulo;return this.options.ecmaVersion>=7&&e===42&&t===42&&(++i,r=a.starstar,t=this.input.charCodeAt(this.pos+2)),t===61?this.finishOp(a.assign,i+1):this.finishOp(r,i)};b.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);if(t===e){if(this.options.ecmaVersion>=12){var i=this.input.charCodeAt(this.pos+2);if(i===61)return this.finishOp(a.assign,3)}return this.finishOp(e===124?a.logicalOR:a.logicalAND,2)}return t===61?this.finishOp(a.assign,2):this.finishOp(e===124?a.bitwiseOR:a.bitwiseAND,1)};b.readToken_caret=function(){var e=this.input.charCodeAt(this.pos+1);return e===61?this.finishOp(a.assign,2):this.finishOp(a.bitwiseXOR,1)};b.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?t===45&&!this.inModule&&this.input.charCodeAt(this.pos+2)===62&&(this.lastTokEnd===0||R.test(this.input.slice(this.lastTokEnd,this.pos)))?(this.skipLineComment(3),this.skipSpace(),this.nextToken()):this.finishOp(a.incDec,2):t===61?this.finishOp(a.assign,2):this.finishOp(a.plusMin,1)};b.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),i=1;return t===e?(i=e===62&&this.input.charCodeAt(this.pos+2)===62?3:2,this.input.charCodeAt(this.pos+i)===61?this.finishOp(a.assign,i+1):this.finishOp(a.bitShift,i)):t===33&&e===60&&!this.inModule&&this.input.charCodeAt(this.pos+2)===45&&this.input.charCodeAt(this.pos+3)===45?(this.skipLineComment(4),this.skipSpace(),this.nextToken()):(t===61&&(i=2),this.finishOp(a.relational,i))};b.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return t===61?this.finishOp(a.equality,this.input.charCodeAt(this.pos+2)===61?3:2):e===61&&t===62&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(a.arrow)):this.finishOp(e===61?a.eq:a.prefix,1)};b.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(t===46){var i=this.input.charCodeAt(this.pos+2);if(i<48||i>57)return this.finishOp(a.questionDot,2)}if(t===63){if(e>=12){var r=this.input.charCodeAt(this.pos+2);if(r===61)return this.finishOp(a.assign,3)}return this.finishOp(a.coalesce,2)}}return this.finishOp(a.question,1)};b.readToken_numberSign=function(){var e=this.options.ecmaVersion,t=35;if(e>=13&&(++this.pos,t=this.fullCharCodeAtPos(),j(t,!0)||t===92))return this.finishToken(a.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+G(t)+"'")};b.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(a.parenL);case 41:return++this.pos,this.finishToken(a.parenR);case 59:return++this.pos,this.finishToken(a.semi);case 44:return++this.pos,this.finishToken(a.comma);case 91:return++this.pos,this.finishToken(a.bracketL);case 93:return++this.pos,this.finishToken(a.bracketR);case 123:return++this.pos,this.finishToken(a.braceL);case 125:return++this.pos,this.finishToken(a.braceR);case 58:return++this.pos,this.finishToken(a.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(a.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(t===120||t===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(t===111||t===79)return this.readRadixNumber(8);if(t===98||t===66)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(a.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+G(e)+"'")};b.finishOp=function(e,t){var i=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,i)};b.readRegexp=function(){for(var e,t,i=this.pos;;){this.pos>=this.input.length&&this.raise(i,"Unterminated regular expression");var r=this.input.charAt(this.pos);if(R.test(r)&&this.raise(i,"Unterminated regular expression"),e)e=!1;else{if(r==="[")t=!0;else if(r==="]"&&t)t=!1;else if(r==="/"&&!t)break;e=r==="\\"}++this.pos}var s=this.input.slice(i,this.pos);++this.pos;var n=this.pos,o=this.readWord1();this.containsEsc&&this.unexpected(n);var c=this.regexpState||(this.regexpState=new U(this));c.reset(i,s,o),this.validateRegExpFlags(c),this.validateRegExpPattern(c);var h=null;try{h=new RegExp(s,o)}catch{}return this.finishToken(a.regexp,{pattern:s,flags:o,value:h})};b.readInt=function(e,t,i){for(var r=this.options.ecmaVersion>=12&&t===void 0,s=i&&this.input.charCodeAt(this.pos)===48,n=this.pos,o=0,c=0,h=0,l=t??1/0;h<l;++h,++this.pos){var m=this.input.charCodeAt(this.pos),S=void 0;if(r&&m===95){s&&this.raiseRecoverable(this.pos,"Numeric separator is not allowed in legacy octal numeric literals"),c===95&&this.raiseRecoverable(this.pos,"Numeric separator must be exactly one underscore"),h===0&&this.raiseRecoverable(this.pos,"Numeric separator is not allowed at the first of digits"),c=m;continue}if(m>=97?S=m-97+10:m>=65?S=m-65+10:m>=48&&m<=57?S=m-48:S=1/0,S>=e)break;c=m,o=o*e+S}return r&&c===95&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===n||t!=null&&this.pos-n!==t?null:o};function kr(e,t){return t?parseInt(e,8):parseFloat(e.replace(/_/g,""))}function $t(e){return typeof BigInt!="function"?null:BigInt(e.replace(/_/g,""))}b.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var i=this.readInt(e);return i==null&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&this.input.charCodeAt(this.pos)===110?(i=$t(this.input.slice(t,this.pos)),++this.pos):j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(a.num,i)};b.readNumber=function(e){var t=this.pos;!e&&this.readInt(10,void 0,!0)===null&&this.raise(t,"Invalid number");var i=this.pos-t>=2&&this.input.charCodeAt(t)===48;i&&this.strict&&this.raise(t,"Invalid number");var r=this.input.charCodeAt(this.pos);if(!i&&!e&&this.options.ecmaVersion>=11&&r===110){var s=$t(this.input.slice(t,this.pos));return++this.pos,j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(a.num,s)}i&&/[89]/.test(this.input.slice(t,this.pos))&&(i=!1),r===46&&!i&&(++this.pos,this.readInt(10),r=this.input.charCodeAt(this.pos)),(r===69||r===101)&&!i&&(r=this.input.charCodeAt(++this.pos),(r===43||r===45)&&++this.pos,this.readInt(10)===null&&this.raise(t,"Invalid number")),j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var n=kr(this.input.slice(t,this.pos),i);return this.finishToken(a.num,n)};b.readCodePoint=function(){var e=this.input.charCodeAt(this.pos),t;if(e===123){this.options.ecmaVersion<6&&this.unexpected();var i=++this.pos;t=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,t>1114111&&this.invalidStringToken(i,"Code point out of bounds")}else t=this.readHexChar(4);return t};b.readString=function(e){for(var t="",i=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var r=this.input.charCodeAt(this.pos);if(r===e)break;r===92?(t+=this.input.slice(i,this.pos),t+=this.readEscapedChar(!1),i=this.pos):r===8232||r===8233?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(ee(r)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(i,this.pos++),this.finishToken(a.string,t)};var ei={};b.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e===ei)this.readInvalidTemplateToken();else throw e}this.inTemplateElement=!1};b.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw ei;this.raise(e,t)};b.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var i=this.input.charCodeAt(this.pos);if(i===96||i===36&&this.input.charCodeAt(this.pos+1)===123)return this.pos===this.start&&(this.type===a.template||this.type===a.invalidTemplate)?i===36?(this.pos+=2,this.finishToken(a.dollarBraceL)):(++this.pos,this.finishToken(a.backQuote)):(e+=this.input.slice(t,this.pos),this.finishToken(a.template,e));if(i===92)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(ee(i)){switch(e+=this.input.slice(t,this.pos),++this.pos,i){case 13:this.input.charCodeAt(this.pos)===10&&++this.pos;case 10:e+=`+`),cooked:this.value},this.next(),i.tail=this.type===a.backQuote,this.finishNode(i,"TemplateElement")};g.parseTemplate=function(e){e===void 0&&(e={});var t=e.isTagged;t===void 0&&(t=!1);var i=this.startNode();this.next(),i.expressions=[];var r=this.parseTemplateElement({isTagged:t});for(i.quasis=[r];!r.tail;)this.type===a.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(a.dollarBraceL),i.expressions.push(this.parseExpression()),this.expect(a.braceR),i.quasis.push(r=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(i,"TemplateLiteral")};g.isAsyncProp=function(e){return!e.computed&&e.key.type==="Identifier"&&e.key.name==="async"&&(this.type===a.name||this.type===a.num||this.type===a.string||this.type===a.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===a.star)&&!R.test(this.input.slice(this.lastTokEnd,this.start))};g.parseObj=function(e,t){var i=this.startNode(),r=!0,s={};for(i.properties=[],this.next();!this.eat(a.braceR);){if(r)r=!1;else if(this.expect(a.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(a.braceR))break;var n=this.parseProperty(e,t);e||this.checkPropClash(n,s,t),i.properties.push(n)}return this.finishNode(i,e?"ObjectPattern":"ObjectExpression")};g.parseProperty=function(e,t){var i=this.startNode(),r,s,n,o;if(this.options.ecmaVersion>=9&&this.eat(a.ellipsis))return e?(i.argument=this.parseIdent(!1),this.type===a.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.finishNode(i,"RestElement")):(i.argument=this.parseMaybeAssign(!1,t),this.type===a.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(i,"SpreadElement"));this.options.ecmaVersion>=6&&(i.method=!1,i.shorthand=!1,(e||t)&&(n=this.start,o=this.startLoc),e||(r=this.eat(a.star)));var h=this.containsEsc;return this.parsePropertyName(i),!e&&!h&&this.options.ecmaVersion>=8&&!r&&this.isAsyncProp(i)?(s=!0,r=this.options.ecmaVersion>=9&&this.eat(a.star),this.parsePropertyName(i)):s=!1,this.parsePropertyValue(i,e,r,s,n,o,t,h),this.finishNode(i,"Property")};g.parseGetterSetter=function(e){var t=e.key.name;this.parsePropertyName(e),e.value=this.parseMethod(!1),e.kind=t;var i=e.kind==="get"?0:1;if(e.value.params.length!==i){var r=e.value.start;e.kind==="get"?this.raiseRecoverable(r,"getter should have no params"):this.raiseRecoverable(r,"setter should have exactly one param")}else e.kind==="set"&&e.value.params[0].type==="RestElement"&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")};g.parsePropertyValue=function(e,t,i,r,s,n,o,h){(i||r)&&this.type===a.colon&&this.unexpected(),this.eat(a.colon)?(e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,o),e.kind="init"):this.options.ecmaVersion>=6&&this.type===a.parenL?(t&&this.unexpected(),e.method=!0,e.value=this.parseMethod(i,r),e.kind="init"):!t&&!h&&this.options.ecmaVersion>=5&&!e.computed&&e.key.type==="Identifier"&&(e.key.name==="get"||e.key.name==="set")&&this.type!==a.comma&&this.type!==a.braceR&&this.type!==a.eq?((i||r)&&this.unexpected(),this.parseGetterSetter(e)):this.options.ecmaVersion>=6&&!e.computed&&e.key.type==="Identifier"?((i||r)&&this.unexpected(),this.checkUnreserved(e.key),e.key.name==="await"&&!this.awaitIdentPos&&(this.awaitIdentPos=s),t?e.value=this.parseMaybeDefault(s,n,this.copyNode(e.key)):this.type===a.eq&&o?(o.shorthandAssign<0&&(o.shorthandAssign=this.start),e.value=this.parseMaybeDefault(s,n,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.kind="init",e.shorthand=!0):this.unexpected()};g.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(a.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(a.bracketR),e.key;e.computed=!1}return e.key=this.type===a.num||this.type===a.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never")};g.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)};g.parseMethod=function(e,t,i){var r=this.startNode(),s=this.yieldPos,n=this.awaitPos,o=this.awaitIdentPos;return this.initFunction(r),this.options.ecmaVersion>=6&&(r.generator=e),this.options.ecmaVersion>=8&&(r.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(ze(t,r.generator)|Ce|(i?Tt:0)),this.expect(a.parenL),r.params=this.parseBindingList(a.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(r,!1,!0,!1),this.yieldPos=s,this.awaitPos=n,this.awaitIdentPos=o,this.finishNode(r,"FunctionExpression")};g.parseArrowExpression=function(e,t,i,r){var s=this.yieldPos,n=this.awaitPos,o=this.awaitIdentPos;return this.enterScope(ze(i,!1)|Xe),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!i),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,r),this.yieldPos=s,this.awaitPos=n,this.awaitIdentPos=o,this.finishNode(e,"ArrowFunctionExpression")};g.parseFunctionBody=function(e,t,i,r){var s=t&&this.type!==a.braceL,n=this.strict,o=!1;if(s)e.body=this.parseMaybeAssign(r),e.expression=!0,this.checkParams(e,!1);else{var h=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);(!n||h)&&(o=this.strictDirective(this.end),o&&h&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list"));var c=this.labels;this.labels=[],o&&(this.strict=!0),this.checkParams(e,!n&&!o&&!t&&!i&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,Nt),e.body=this.parseBlock(!1,void 0,o&&!n),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=c}this.exitScope()};g.isSimpleParamList=function(e){for(var t=0,i=e;t<i.length;t+=1){var r=i[t];if(r.type!=="Identifier")return!1}return!0};g.checkParams=function(e,t){for(var i=Object.create(null),r=0,s=e.params;r<s.length;r+=1){var n=s[r];this.checkLValInnerPattern(n,Qe,t?null:i)}};g.parseExprList=function(e,t,i,r){for(var s=[],n=!0;!this.eat(e);){if(n)n=!1;else if(this.expect(a.comma),t&&this.afterTrailingComma(e))break;var o=void 0;i&&this.type===a.comma?o=null:this.type===a.ellipsis?(o=this.parseSpread(r),r&&this.type===a.comma&&r.trailingComma<0&&(r.trailingComma=this.start)):o=this.parseMaybeAssign(!1,r),s.push(o)}return s};g.checkUnreserved=function(e){var t=e.start,i=e.end,r=e.name;if(this.inGenerator&&r==="yield"&&this.raiseRecoverable(t,"Cannot use 'yield' as identifier inside a generator"),this.inAsync&&r==="await"&&this.raiseRecoverable(t,"Cannot use 'await' as identifier inside an async function"),!(this.currentThisScope().flags&_e)&&r==="arguments"&&this.raiseRecoverable(t,"Cannot use 'arguments' in class field initializer"),this.inClassStaticBlock&&(r==="arguments"||r==="await")&&this.raise(t,"Cannot use "+r+" in class static initialization block"),this.keywords.test(r)&&this.raise(t,"Unexpected keyword '"+r+"'"),!(this.options.ecmaVersion<6&&this.input.slice(t,i).indexOf("\\")!==-1)){var s=this.strict?this.reservedWordsStrict:this.reservedWords;s.test(r)&&(!this.inAsync&&r==="await"&&this.raiseRecoverable(t,"Cannot use keyword 'await' outside an async function"),this.raiseRecoverable(t,"The keyword '"+r+"' is reserved"))}};g.parseIdent=function(e){var t=this.parseIdentNode();return this.next(!!e),this.finishNode(t,"Identifier"),e||(this.checkUnreserved(t),t.name==="await"&&!this.awaitIdentPos&&(this.awaitIdentPos=t.start)),t};g.parseIdentNode=function(){var e=this.startNode();return this.type===a.name?e.name=this.value:this.type.keyword?(e.name=this.type.keyword,(e.name==="class"||e.name==="function")&&(this.lastTokEnd!==this.lastTokStart+1||this.input.charCodeAt(this.lastTokStart)!==46)&&this.context.pop(),this.type=a.name):this.unexpected(),e};g.parsePrivateIdent=function(){var e=this.startNode();return this.type===a.privateId?e.name=this.value:this.unexpected(),this.next(),this.finishNode(e,"PrivateIdentifier"),this.options.checkPrivateFields&&(this.privateNameStack.length===0?this.raise(e.start,"Private field '#"+e.name+"' must be declared in an enclosing class"):this.privateNameStack[this.privateNameStack.length-1].used.push(e)),e};g.parseYield=function(e){this.yieldPos||(this.yieldPos=this.start);var t=this.startNode();return this.next(),this.type===a.semi||this.canInsertSemicolon()||this.type!==a.star&&!this.type.startsExpr?(t.delegate=!1,t.argument=null):(t.delegate=this.eat(a.star),t.argument=this.parseMaybeAssign(e)),this.finishNode(t,"YieldExpression")};g.parseAwait=function(e){this.awaitPos||(this.awaitPos=this.start);var t=this.startNode();return this.next(),t.argument=this.parseMaybeUnary(null,!0,!1,e),this.finishNode(t,"AwaitExpression")};var ve=A.prototype;ve.raise=function(e,t){var i=Et(this.input,e);t+=" ("+i.line+":"+i.column+")",this.sourceFile&&(t+=" in "+this.sourceFile);var r=new SyntaxError(t);throw r.pos=e,r.loc=i,r.raisedAt=this.pos,r};ve.raiseRecoverable=ve.raise;ve.curPosition=function(){if(this.options.locations)return new ue(this.curLine,this.pos-this.lineStart)};var J=A.prototype,nr=function(t){this.flags=t,this.var=[],this.lexical=[],this.functions=[]};J.enterScope=function(e){this.scopeStack.push(new nr(e))};J.exitScope=function(){this.scopeStack.pop()};J.treatFunctionsAsVarInScope=function(e){return e.flags&z||!this.inModule&&e.flags&X};J.declareName=function(e,t,i){var r=!1;if(t===q){var s=this.currentScope();r=s.lexical.indexOf(e)>-1||s.functions.indexOf(e)>-1||s.var.indexOf(e)>-1,s.lexical.push(e),this.inModule&&s.flags&X&&delete this.undefinedExports[e]}else if(t===Pt){var n=this.currentScope();n.lexical.push(e)}else if(t===It){var o=this.currentScope();this.treatFunctionsAsVar?r=o.lexical.indexOf(e)>-1:r=o.lexical.indexOf(e)>-1||o.var.indexOf(e)>-1,o.functions.push(e)}else for(var h=this.scopeStack.length-1;h>=0;--h){var c=this.scopeStack[h];if(c.lexical.indexOf(e)>-1&&!(c.flags&At&&c.lexical[0]===e)||!this.treatFunctionsAsVarInScope(c)&&c.functions.indexOf(e)>-1){r=!0;break}if(c.var.push(e),this.inModule&&c.flags&X&&delete this.undefinedExports[e],c.flags&_e)break}r&&this.raiseRecoverable(i,"Identifier '"+e+"' has already been declared")};J.checkLocalExport=function(e){this.scopeStack[0].lexical.indexOf(e.name)===-1&&this.scopeStack[0].var.indexOf(e.name)===-1&&(this.undefinedExports[e.name]=e)};J.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]};J.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&(_e|he|Q))return t}};J.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(t.flags&(_e|he|Q)&&!(t.flags&Xe))return t}};var ke=function(t,i,r){this.type="",this.start=i,this.end=0,t.options.locations&&(this.loc=new Se(t,r)),t.options.directSourceFile&&(this.sourceFile=t.options.directSourceFile),t.options.ranges&&(this.range=[i,0])},ce=A.prototype;ce.startNode=function(){return new ke(this,this.start,this.startLoc)};ce.startNodeAt=function(e,t){return new ke(this,e,t)};function Vt(e,t,i,r){return e.type=t,e.end=i,this.options.locations&&(e.loc.end=r),this.options.ranges&&(e.range[1]=i),e}ce.finishNode=function(e,t){return Vt.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)};ce.finishNodeAt=function(e,t,i,r){return Vt.call(this,e,t,i,r)};ce.copyNode=function(e){var t=new ke(this,e.start,this.startLoc);for(var i in e)t[i]=e[i];return t};var or="Berf Beria_Erfe Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sidetic Sidt Sunu Sunuwar Tai_Yo Tayo Todhri Todr Tolong_Siki Tols Tulu_Tigalari Tutg Unknown Zzzz",Ot="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",Dt=Ot+" Extended_Pictographic",Mt=Dt,Bt=Mt+" EBase EComp EMod EPres ExtPict",Ft=Bt,ur=Ft,hr={9:Ot,10:Dt,11:Mt,12:Bt,13:Ft,14:ur},cr="Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji",pr={9:"",10:"",11:"",12:"",13:"",14:cr},xt="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",jt="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Ut=jt+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",Gt=Ut+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",Wt=Gt+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",qt=Wt+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith",lr=qt+" "+or,fr={9:jt,10:Ut,11:Gt,12:Wt,13:qt,14:lr},Ht={};function dr(e){var t=Ht[e]={binary:H(hr[e]+" "+xt),binaryOfStrings:H(pr[e]),nonBinary:{General_Category:H(xt),Script:H(fr[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(xe=0,Ue=[9,10,11,12,13,14];xe<Ue.length;xe+=1)yt=Ue[xe],dr(yt);var yt,xe,Ue,f=A.prototype,be=function(t,i){this.parent=t,this.base=i||this};be.prototype.separatedFrom=function(t){for(var i=this;i;i=i.parent)for(var r=t;r;r=r.parent)if(i.base===r.base&&i!==r)return!0;return!1};be.prototype.sibling=function(){return new be(this.parent,this.base)};var U=function(t){this.parser=t,this.validFlags="gim"+(t.options.ecmaVersion>=6?"uy":"")+(t.options.ecmaVersion>=9?"s":"")+(t.options.ecmaVersion>=13?"d":"")+(t.options.ecmaVersion>=15?"v":""),this.unicodeProperties=Ht[t.options.ecmaVersion>=14?14:t.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchV=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=Object.create(null),this.backReferenceNames=[],this.branchID=null};U.prototype.reset=function(t,i,r){var s=r.indexOf("v")!==-1,n=r.indexOf("u")!==-1;this.start=t|0,this.source=i+"",this.flags=r,s&&this.parser.options.ecmaVersion>=15?(this.switchU=!0,this.switchV=!0,this.switchN=!0):(this.switchU=n&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=n&&this.parser.options.ecmaVersion>=9)};U.prototype.raise=function(t){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+t)};U.prototype.at=function(t,i){i===void 0&&(i=!1);var r=this.source,s=r.length;if(t>=s)return-1;var n=r.charCodeAt(t);if(!(i||this.switchU)||n<=55295||n>=57344||t+1>=s)return n;var o=r.charCodeAt(t+1);return o>=56320&&o<=57343?(n<<10)+o-56613888:n};U.prototype.nextIndex=function(t,i){i===void 0&&(i=!1);var r=this.source,s=r.length;if(t>=s)return s;var n=r.charCodeAt(t),o;return!(i||this.switchU)||n<=55295||n>=57344||t+1>=s||(o=r.charCodeAt(t+1))<56320||o>57343?t+1:t+2};U.prototype.current=function(t){return t===void 0&&(t=!1),this.at(this.pos,t)};U.prototype.lookahead=function(t){return t===void 0&&(t=!1),this.at(this.nextIndex(this.pos,t),t)};U.prototype.advance=function(t){t===void 0&&(t=!1),this.pos=this.nextIndex(this.pos,t)};U.prototype.eat=function(t,i){return i===void 0&&(i=!1),this.current(i)===t?(this.advance(i),!0):!1};U.prototype.eatChars=function(t,i){i===void 0&&(i=!1);for(var r=this.pos,s=0,n=t;s<n.length;s+=1){var o=n[s],h=this.at(r,i);if(h===-1||h!==o)return!1;r=this.nextIndex(r,i)}return this.pos=r,!0};f.validateRegExpFlags=function(e){for(var t=e.validFlags,i=e.flags,r=!1,s=!1,n=0;n<i.length;n++){var o=i.charAt(n);t.indexOf(o)===-1&&this.raise(e.start,"Invalid regular expression flag"),i.indexOf(o,n+1)>-1&&this.raise(e.start,"Duplicate regular expression flag"),o==="u"&&(r=!0),o==="v"&&(s=!0)}this.options.ecmaVersion>=15&&r&&s&&this.raise(e.start,"Invalid regular expression flag")};function mr(e){for(var t in e)return!0;return!1}f.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&mr(e.groupNames)&&(e.switchN=!0,this.regexp_pattern(e))};f.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames=Object.create(null),e.backReferenceNames.length=0,e.branchID=null,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,i=e.backReferenceNames;t<i.length;t+=1){var r=i[t];e.groupNames[r]||e.raise("Invalid named capture referenced")}};f.regexp_disjunction=function(e){var t=this.options.ecmaVersion>=16;for(t&&(e.branchID=new be(e.branchID,null)),this.regexp_alternative(e);e.eat(124);)t&&(e.branchID=e.branchID.sibling()),this.regexp_alternative(e);t&&(e.branchID=e.branchID.parent),this.regexp_eatQuantifier(e,!0)&&e.raise("Nothing to repeat"),e.eat(123)&&e.raise("Lone quantifier brackets")};f.regexp_alternative=function(e){for(;e.pos<e.source.length&&this.regexp_eatTerm(e););};f.regexp_eatTerm=function(e){return this.regexp_eatAssertion(e)?(e.lastAssertionIsQuantifiable&&this.regexp_eatQuantifier(e)&&e.switchU&&e.raise("Invalid quantifier"),!0):(e.switchU?this.regexp_eatAtom(e):this.regexp_eatExtendedAtom(e))?(this.regexp_eatQuantifier(e),!0):!1};f.regexp_eatAssertion=function(e){var t=e.pos;if(e.lastAssertionIsQuantifiable=!1,e.eat(94)||e.eat(36))return!0;if(e.eat(92)){if(e.eat(66)||e.eat(98))return!0;e.pos=t}if(e.eat(40)&&e.eat(63)){var i=!1;if(this.options.ecmaVersion>=9&&(i=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!i,!0}return e.pos=t,!1};f.regexp_eatQuantifier=function(e,t){return t===void 0&&(t=!1),this.regexp_eatQuantifierPrefix(e,t)?(e.eat(63),!0):!1};f.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)};f.regexp_eatBracedQuantifier=function(e,t){var i=e.pos;if(e.eat(123)){var r=0,s=-1;if(this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(s=e.lastIntValue),e.eat(125)))return s!==-1&&s<r&&!t&&e.raise("numbers out of order in {} quantifier"),!0;e.switchU&&!t&&e.raise("Incomplete quantifier"),e.pos=i}return!1};f.regexp_eatAtom=function(e){return this.regexp_eatPatternCharacters(e)||e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)};f.regexp_eatReverseSolidusAtomEscape=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatAtomEscape(e))return!0;e.pos=t}return!1};f.regexp_eatUncapturingGroup=function(e){var t=e.pos;if(e.eat(40)){if(e.eat(63)){if(this.options.ecmaVersion>=16){var i=this.regexp_eatModifiers(e),r=e.eat(45);if(i||r){for(var s=0;s<i.length;s++){var n=i.charAt(s);i.indexOf(n,s+1)>-1&&e.raise("Duplicate regular expression modifiers")}if(r){var o=this.regexp_eatModifiers(e);!i&&!o&&e.current()===58&&e.raise("Invalid regular expression modifiers");for(var h=0;h<o.length;h++){var c=o.charAt(h);(o.indexOf(c,h+1)>-1||i.indexOf(c)>-1)&&e.raise("Duplicate regular expression modifiers")}}}}if(e.eat(58)){if(this.regexp_disjunction(e),e.eat(41))return!0;e.raise("Unterminated group")}}e.pos=t}return!1};f.regexp_eatCapturingGroup=function(e){if(e.eat(40)){if(this.options.ecmaVersion>=9?this.regexp_groupSpecifier(e):e.current()===63&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1};f.regexp_eatModifiers=function(e){for(var t="",i=0;(i=e.current())!==-1&&xr(i);)t+=G(i),e.advance();return t};function xr(e){return e===105||e===109||e===115}f.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)};f.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1};f.regexp_eatSyntaxCharacter=function(e){var t=e.current();return Kt(t)?(e.lastIntValue=t,e.advance(),!0):!1};function Kt(e){return e===36||e>=40&&e<=43||e===46||e===63||e>=91&&e<=94||e>=123&&e<=125}f.regexp_eatPatternCharacters=function(e){for(var t=e.pos,i=0;(i=e.current())!==-1&&!Kt(i);)e.advance();return e.pos!==t};f.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return t!==-1&&t!==36&&!(t>=40&&t<=43)&&t!==46&&t!==63&&t!==91&&t!==94&&t!==124?(e.advance(),!0):!1};f.regexp_groupSpecifier=function(e){if(e.eat(63)){this.regexp_eatGroupName(e)||e.raise("Invalid group");var t=this.options.ecmaVersion>=16,i=e.groupNames[e.lastStringValue];if(i)if(t)for(var r=0,s=i;r<s.length;r+=1){var n=s[r];n.separatedFrom(e.branchID)||e.raise("Duplicate capture group name")}else e.raise("Duplicate capture group name");t?(i||(e.groupNames[e.lastStringValue]=[])).push(e.branchID):e.groupNames[e.lastStringValue]=!0}};f.regexp_eatGroupName=function(e){if(e.lastStringValue="",e.eat(60)){if(this.regexp_eatRegExpIdentifierName(e)&&e.eat(62))return!0;e.raise("Invalid capture group name")}return!1};f.regexp_eatRegExpIdentifierName=function(e){if(e.lastStringValue="",this.regexp_eatRegExpIdentifierStart(e)){for(e.lastStringValue+=G(e.lastIntValue);this.regexp_eatRegExpIdentifierPart(e);)e.lastStringValue+=G(e.lastIntValue);return!0}return!1};f.regexp_eatRegExpIdentifierStart=function(e){var t=e.pos,i=this.options.ecmaVersion>=11,r=e.current(i);return e.advance(i),r===92&&this.regexp_eatRegExpUnicodeEscapeSequence(e,i)&&(r=e.lastIntValue),yr(r)?(e.lastIntValue=r,!0):(e.pos=t,!1)};function yr(e){return j(e,!0)||e===36||e===95}f.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,i=this.options.ecmaVersion>=11,r=e.current(i);return e.advance(i),r===92&&this.regexp_eatRegExpUnicodeEscapeSequence(e,i)&&(r=e.lastIntValue),gr(r)?(e.lastIntValue=r,!0):(e.pos=t,!1)};function gr(e){return K(e,!0)||e===36||e===95||e===8204||e===8205}f.regexp_eatAtomEscape=function(e){return this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e)?!0:(e.switchU&&(e.current()===99&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)};f.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var i=e.lastIntValue;if(e.switchU)return i>e.maxBackReference&&(e.maxBackReference=i),!0;if(i<=e.numCapturingParens)return!0;e.pos=t}return!1};f.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1};f.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)};f.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1};f.regexp_eatZero=function(e){return e.current()===48&&!Ae(e.lookahead())?(e.lastIntValue=0,e.advance(),!0):!1};f.regexp_eatControlEscape=function(e){var t=e.current();return t===116?(e.lastIntValue=9,e.advance(),!0):t===110?(e.lastIntValue=10,e.advance(),!0):t===118?(e.lastIntValue=11,e.advance(),!0):t===102?(e.lastIntValue=12,e.advance(),!0):t===114?(e.lastIntValue=13,e.advance(),!0):!1};f.regexp_eatControlLetter=function(e){var t=e.current();return Jt(t)?(e.lastIntValue=t%32,e.advance(),!0):!1};function Jt(e){return e>=65&&e<=90||e>=97&&e<=122}f.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){t===void 0&&(t=!1);var i=e.pos,r=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(r&&s>=55296&&s<=56319){var n=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var o=e.lastIntValue;if(o>=56320&&o<=57343)return e.lastIntValue=(s-55296)*1024+(o-56320)+65536,!0}e.pos=n,e.lastIntValue=s}return!0}if(r&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&vr(e.lastIntValue))return!0;r&&e.raise("Invalid unicode escape"),e.pos=i}return!1};function vr(e){return e>=0&&e<=1114111}f.regexp_eatIdentityEscape=function(e){if(e.switchU)return this.regexp_eatSyntaxCharacter(e)?!0:e.eat(47)?(e.lastIntValue=47,!0):!1;var t=e.current();return t!==99&&(!e.switchN||t!==107)?(e.lastIntValue=t,e.advance(),!0):!1};f.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do e.lastIntValue=10*e.lastIntValue+(t-48),e.advance();while((t=e.current())>=48&&t<=57);return!0}return!1};var Xt=0,W=1,D=2;f.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(br(t))return e.lastIntValue=-1,e.advance(),W;var i=!1;if(e.switchU&&this.options.ecmaVersion>=9&&((i=t===80)||t===112)){e.lastIntValue=-1,e.advance();var r;if(e.eat(123)&&(r=this.regexp_eatUnicodePropertyValueExpression(e))&&e.eat(125))return i&&r===D&&e.raise("Invalid property name"),r;e.raise("Invalid property name")}return Xt};function br(e){return e===100||e===68||e===115||e===83||e===119||e===87}f.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var i=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,i,r),W}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var s=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,s)}return Xt};f.regexp_validateUnicodePropertyNameAndValue=function(e,t,i){te(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(i)||e.raise("Invalid property value")};f.regexp_validateUnicodePropertyNameOrValue=function(e,t){if(e.unicodeProperties.binary.test(t))return W;if(e.switchV&&e.unicodeProperties.binaryOfStrings.test(t))return D;e.raise("Invalid property name")};f.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";zt(t=e.current());)e.lastStringValue+=G(t),e.advance();return e.lastStringValue!==""};function zt(e){return Jt(e)||e===95}f.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";Sr(t=e.current());)e.lastStringValue+=G(t),e.advance();return e.lastStringValue!==""};function Sr(e){return zt(e)||Ae(e)}f.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)};f.regexp_eatCharacterClass=function(e){if(e.eat(91)){var t=e.eat(94),i=this.regexp_classContents(e);return e.eat(93)||e.raise("Unterminated character class"),t&&i===D&&e.raise("Negated character class may contain strings"),!0}return!1};f.regexp_classContents=function(e){return e.current()===93?W:e.switchV?this.regexp_classSetExpression(e):(this.regexp_nonEmptyClassRanges(e),W)};f.regexp_nonEmptyClassRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var i=e.lastIntValue;e.switchU&&(t===-1||i===-1)&&e.raise("Invalid character class"),t!==-1&&i!==-1&&t>i&&e.raise("Range out of order in character class")}}};f.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var i=e.current();(i===99||Zt(i))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var r=e.current();return r!==93?(e.lastIntValue=r,e.advance(),!0):!1};f.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)};f.regexp_classSetExpression=function(e){var t=W,i;if(!this.regexp_eatClassSetRange(e))if(i=this.regexp_eatClassSetOperand(e)){i===D&&(t=D);for(var r=e.pos;e.eatChars([38,38]);){if(e.current()!==38&&(i=this.regexp_eatClassSetOperand(e))){i!==D&&(t=W);continue}e.raise("Invalid character in character class")}if(r!==e.pos)return t;for(;e.eatChars([45,45]);)this.regexp_eatClassSetOperand(e)||e.raise("Invalid character in character class");if(r!==e.pos)return t}else e.raise("Invalid character in character class");for(;;)if(!this.regexp_eatClassSetRange(e)){if(i=this.regexp_eatClassSetOperand(e),!i)return t;i===D&&(t=D)}};f.regexp_eatClassSetRange=function(e){var t=e.pos;if(this.regexp_eatClassSetCharacter(e)){var i=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassSetCharacter(e)){var r=e.lastIntValue;return i!==-1&&r!==-1&&i>r&&e.raise("Range out of order in character class"),!0}e.pos=t}return!1};f.regexp_eatClassSetOperand=function(e){return this.regexp_eatClassSetCharacter(e)?W:this.regexp_eatClassStringDisjunction(e)||this.regexp_eatNestedClass(e)};f.regexp_eatNestedClass=function(e){var t=e.pos;if(e.eat(91)){var i=e.eat(94),r=this.regexp_classContents(e);if(e.eat(93))return i&&r===D&&e.raise("Negated character class may contain strings"),r;e.pos=t}if(e.eat(92)){var s=this.regexp_eatCharacterClassEscape(e);if(s)return s;e.pos=t}return null};f.regexp_eatClassStringDisjunction=function(e){var t=e.pos;if(e.eatChars([92,113])){if(e.eat(123)){var i=this.regexp_classStringDisjunctionContents(e);if(e.eat(125))return i}else e.raise("Invalid escape");e.pos=t}return null};f.regexp_classStringDisjunctionContents=function(e){for(var t=this.regexp_classString(e);e.eat(124);)this.regexp_classString(e)===D&&(t=D);return t};f.regexp_classString=function(e){for(var t=0;this.regexp_eatClassSetCharacter(e);)t++;return t===1?W:D};f.regexp_eatClassSetCharacter=function(e){var t=e.pos;if(e.eat(92))return this.regexp_eatCharacterEscape(e)||this.regexp_eatClassSetReservedPunctuator(e)?!0:e.eat(98)?(e.lastIntValue=8,!0):(e.pos=t,!1);var i=e.current();return i<0||i===e.lookahead()&&Cr(i)||_r(i)?!1:(e.advance(),e.lastIntValue=i,!0)};function Cr(e){return e===33||e>=35&&e<=38||e>=42&&e<=44||e===46||e>=58&&e<=64||e===94||e===96||e===126}function _r(e){return e===40||e===41||e===45||e===47||e>=91&&e<=93||e>=123&&e<=125}f.regexp_eatClassSetReservedPunctuator=function(e){var t=e.current();return Er(t)?(e.lastIntValue=t,e.advance(),!0):!1};function Er(e){return e===33||e===35||e===37||e===38||e===44||e===45||e>=58&&e<=62||e===64||e===96||e===126}f.regexp_eatClassControlLetter=function(e){var t=e.current();return Ae(t)||t===95?(e.lastIntValue=t%32,e.advance(),!0):!1};f.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1};f.regexp_eatDecimalDigits=function(e){var t=e.pos,i=0;for(e.lastIntValue=0;Ae(i=e.current());)e.lastIntValue=10*e.lastIntValue+(i-48),e.advance();return e.pos!==t};function Ae(e){return e>=48&&e<=57}f.regexp_eatHexDigits=function(e){var t=e.pos,i=0;for(e.lastIntValue=0;Qt(i=e.current());)e.lastIntValue=16*e.lastIntValue+Yt(i),e.advance();return e.pos!==t};function Qt(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Yt(e){return e>=65&&e<=70?10+(e-65):e>=97&&e<=102?10+(e-97):e-48}f.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var i=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=t*64+i*8+e.lastIntValue:e.lastIntValue=t*8+i}else e.lastIntValue=t;return!0}return!1};f.regexp_eatOctalDigit=function(e){var t=e.current();return Zt(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)};function Zt(e){return e>=48&&e<=55}f.regexp_eatFixedHexDigits=function(e,t){var i=e.pos;e.lastIntValue=0;for(var r=0;r<t;++r){var s=e.current();if(!Qt(s))return e.pos=i,!1;e.lastIntValue=16*e.lastIntValue+Yt(s),e.advance()}return!0};var Ze=function(t){this.type=t.type,this.value=t.value,this.start=t.start,this.end=t.end,t.options.locations&&(this.loc=new Se(t,t.startLoc,t.endLoc)),t.options.ranges&&(this.range=[t.start,t.end])},b=A.prototype;b.next=function(e){!e&&this.type.keyword&&this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword "+this.type.keyword),this.options.onToken&&this.options.onToken(new Ze(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()};b.getToken=function(){return this.next(),new Ze(this)};typeof Symbol<"u"&&(b[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===a.eof,value:t}}}});b.nextToken=function(){var e=this.curContext();if((!e||!e.preserveSpace)&&this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length)return this.finishToken(a.eof);if(e.override)return e.override(this);this.readToken(this.fullCharCodeAtPos())};b.readToken=function(e){return j(e,this.options.ecmaVersion>=6)||e===92?this.readWord():this.getTokenFromCode(e)};b.fullCharCodeAt=function(e){var t=this.input.charCodeAt(e);if(t<=55295||t>=56320)return t;var i=this.input.charCodeAt(e+1);return i<=56319||i>=57344?t:(t<<10)+i-56613888};b.fullCharCodeAtPos=function(){return this.fullCharCodeAt(this.pos)};b.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,i=this.input.indexOf("*/",this.pos+=2);if(i===-1&&this.raise(this.pos-2,"Unterminated comment"),this.pos=i+2,this.options.locations)for(var r=void 0,s=t;(r=St(this.input,s,this.pos))>-1;)++this.curLine,s=this.lineStart=r;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,i),t,this.pos,e,this.curPosition())};b.skipLineComment=function(e){for(var t=this.pos,i=this.options.onComment&&this.curPosition(),r=this.input.charCodeAt(this.pos+=e);this.pos<this.input.length&&!ee(r);)r=this.input.charCodeAt(++this.pos);this.options.onComment&&this.options.onComment(!1,this.input.slice(t+e,this.pos),t,this.pos,i,this.curPosition())};b.skipSpace=function(){e:for(;this.pos<this.input.length;){var e=this.input.charCodeAt(this.pos);switch(e){case 32:case 160:++this.pos;break;case 13:this.input.charCodeAt(this.pos+1)===10&&++this.pos;case 10:case 8232:case 8233:++this.pos,this.options.locations&&(++this.curLine,this.lineStart=this.pos);break;case 47:switch(this.input.charCodeAt(this.pos+1)){case 42:this.skipBlockComment();break;case 47:this.skipLineComment(2);break;default:break e}break;default:if(e>8&&e<14||e>=5760&&Ct.test(String.fromCharCode(e)))++this.pos;else break e}}};b.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var i=this.type;this.type=e,this.value=t,this.updateContext(i)};b.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&e===46&&t===46?(this.pos+=3,this.finishToken(a.ellipsis)):(++this.pos,this.finishToken(a.dot))};b.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):e===61?this.finishOp(a.assign,2):this.finishOp(a.slash,1)};b.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),i=1,r=e===42?a.star:a.modulo;return this.options.ecmaVersion>=7&&e===42&&t===42&&(++i,r=a.starstar,t=this.input.charCodeAt(this.pos+2)),t===61?this.finishOp(a.assign,i+1):this.finishOp(r,i)};b.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);if(t===e){if(this.options.ecmaVersion>=12){var i=this.input.charCodeAt(this.pos+2);if(i===61)return this.finishOp(a.assign,3)}return this.finishOp(e===124?a.logicalOR:a.logicalAND,2)}return t===61?this.finishOp(a.assign,2):this.finishOp(e===124?a.bitwiseOR:a.bitwiseAND,1)};b.readToken_caret=function(){var e=this.input.charCodeAt(this.pos+1);return e===61?this.finishOp(a.assign,2):this.finishOp(a.bitwiseXOR,1)};b.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?t===45&&!this.inModule&&this.input.charCodeAt(this.pos+2)===62&&(this.lastTokEnd===0||R.test(this.input.slice(this.lastTokEnd,this.pos)))?(this.skipLineComment(3),this.skipSpace(),this.nextToken()):this.finishOp(a.incDec,2):t===61?this.finishOp(a.assign,2):this.finishOp(a.plusMin,1)};b.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),i=1;return t===e?(i=e===62&&this.input.charCodeAt(this.pos+2)===62?3:2,this.input.charCodeAt(this.pos+i)===61?this.finishOp(a.assign,i+1):this.finishOp(a.bitShift,i)):t===33&&e===60&&!this.inModule&&this.input.charCodeAt(this.pos+2)===45&&this.input.charCodeAt(this.pos+3)===45?(this.skipLineComment(4),this.skipSpace(),this.nextToken()):(t===61&&(i=2),this.finishOp(a.relational,i))};b.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return t===61?this.finishOp(a.equality,this.input.charCodeAt(this.pos+2)===61?3:2):e===61&&t===62&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(a.arrow)):this.finishOp(e===61?a.eq:a.prefix,1)};b.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(t===46){var i=this.input.charCodeAt(this.pos+2);if(i<48||i>57)return this.finishOp(a.questionDot,2)}if(t===63){if(e>=12){var r=this.input.charCodeAt(this.pos+2);if(r===61)return this.finishOp(a.assign,3)}return this.finishOp(a.coalesce,2)}}return this.finishOp(a.question,1)};b.readToken_numberSign=function(){var e=this.options.ecmaVersion,t=35;if(e>=13&&(++this.pos,t=this.fullCharCodeAtPos(),j(t,!0)||t===92))return this.finishToken(a.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+G(t)+"'")};b.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(a.parenL);case 41:return++this.pos,this.finishToken(a.parenR);case 59:return++this.pos,this.finishToken(a.semi);case 44:return++this.pos,this.finishToken(a.comma);case 91:return++this.pos,this.finishToken(a.bracketL);case 93:return++this.pos,this.finishToken(a.bracketR);case 123:return++this.pos,this.finishToken(a.braceL);case 125:return++this.pos,this.finishToken(a.braceR);case 58:return++this.pos,this.finishToken(a.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(a.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(t===120||t===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(t===111||t===79)return this.readRadixNumber(8);if(t===98||t===66)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(a.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+G(e)+"'")};b.finishOp=function(e,t){var i=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,i)};b.readRegexp=function(){for(var e,t,i=this.pos;;){this.pos>=this.input.length&&this.raise(i,"Unterminated regular expression");var r=this.input.charAt(this.pos);if(R.test(r)&&this.raise(i,"Unterminated regular expression"),e)e=!1;else{if(r==="[")t=!0;else if(r==="]"&&t)t=!1;else if(r==="/"&&!t)break;e=r==="\\"}++this.pos}var s=this.input.slice(i,this.pos);++this.pos;var n=this.pos,o=this.readWord1();this.containsEsc&&this.unexpected(n);var h=this.regexpState||(this.regexpState=new U(this));h.reset(i,s,o),this.validateRegExpFlags(h),this.validateRegExpPattern(h);var c=null;try{c=new RegExp(s,o)}catch{}return this.finishToken(a.regexp,{pattern:s,flags:o,value:c})};b.readInt=function(e,t,i){for(var r=this.options.ecmaVersion>=12&&t===void 0,s=i&&this.input.charCodeAt(this.pos)===48,n=this.pos,o=0,h=0,c=0,l=t??1/0;c<l;++c,++this.pos){var m=this.input.charCodeAt(this.pos),S=void 0;if(r&&m===95){s&&this.raiseRecoverable(this.pos,"Numeric separator is not allowed in legacy octal numeric literals"),h===95&&this.raiseRecoverable(this.pos,"Numeric separator must be exactly one underscore"),c===0&&this.raiseRecoverable(this.pos,"Numeric separator is not allowed at the first of digits"),h=m;continue}if(m>=97?S=m-97+10:m>=65?S=m-65+10:m>=48&&m<=57?S=m-48:S=1/0,S>=e)break;h=m,o=o*e+S}return r&&h===95&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===n||t!=null&&this.pos-n!==t?null:o};function kr(e,t){return t?parseInt(e,8):parseFloat(e.replace(/_/g,""))}function $t(e){return typeof BigInt!="function"?null:BigInt(e.replace(/_/g,""))}b.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var i=this.readInt(e);return i==null&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&this.input.charCodeAt(this.pos)===110?(i=$t(this.input.slice(t,this.pos)),++this.pos):j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(a.num,i)};b.readNumber=function(e){var t=this.pos;!e&&this.readInt(10,void 0,!0)===null&&this.raise(t,"Invalid number");var i=this.pos-t>=2&&this.input.charCodeAt(t)===48;i&&this.strict&&this.raise(t,"Invalid number");var r=this.input.charCodeAt(this.pos);if(!i&&!e&&this.options.ecmaVersion>=11&&r===110){var s=$t(this.input.slice(t,this.pos));return++this.pos,j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(a.num,s)}i&&/[89]/.test(this.input.slice(t,this.pos))&&(i=!1),r===46&&!i&&(++this.pos,this.readInt(10),r=this.input.charCodeAt(this.pos)),(r===69||r===101)&&!i&&(r=this.input.charCodeAt(++this.pos),(r===43||r===45)&&++this.pos,this.readInt(10)===null&&this.raise(t,"Invalid number")),j(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var n=kr(this.input.slice(t,this.pos),i);return this.finishToken(a.num,n)};b.readCodePoint=function(){var e=this.input.charCodeAt(this.pos),t;if(e===123){this.options.ecmaVersion<6&&this.unexpected();var i=++this.pos;t=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,t>1114111&&this.invalidStringToken(i,"Code point out of bounds")}else t=this.readHexChar(4);return t};b.readString=function(e){for(var t="",i=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var r=this.input.charCodeAt(this.pos);if(r===e)break;r===92?(t+=this.input.slice(i,this.pos),t+=this.readEscapedChar(!1),i=this.pos):r===8232||r===8233?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(ee(r)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(i,this.pos++),this.finishToken(a.string,t)};var ei={};b.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e===ei)this.readInvalidTemplateToken();else throw e}this.inTemplateElement=!1};b.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw ei;this.raise(e,t)};b.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var i=this.input.charCodeAt(this.pos);if(i===96||i===36&&this.input.charCodeAt(this.pos+1)===123)return this.pos===this.start&&(this.type===a.template||this.type===a.invalidTemplate)?i===36?(this.pos+=2,this.finishToken(a.dollarBraceL)):(++this.pos,this.finishToken(a.backQuote)):(e+=this.input.slice(t,this.pos),this.finishToken(a.template,e));if(i===92)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(ee(i)){switch(e+=this.input.slice(t,this.pos),++this.pos,i){case 13:this.input.charCodeAt(this.pos)===10&&++this.pos;case 10:e+=` `;break;default:e+=String.fromCharCode(i);break}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}};b.readInvalidTemplateToken=function(){for(;this.pos<this.input.length;this.pos++)switch(this.input[this.pos]){case"\\":++this.pos;break;case"$":if(this.input[this.pos+1]!=="{")break;case"`":return this.finishToken(a.invalidTemplate,this.input.slice(this.start,this.pos));case"\r":this.input[this.pos+1]===`@@ -10,8 +10,8 @@ `:case"\u2028":case"\u2029":++this.curLine,this.lineStart=this.pos+1;break}this.raise(this.start,"Unterminated template")};b.readEscapedChar=function(e){var t=this.input.charCodeAt(++this.pos);switch(++this.pos,t){case 110:return`-`;case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return G(this.readCodePoint());case 116:return"	";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 13:this.input.charCodeAt(this.pos)===10&&++this.pos;case 10:return this.options.locations&&(this.lineStart=this.pos,++this.curLine),"";case 56:case 57:if(this.strict&&this.invalidStringToken(this.pos-1,"Invalid escape sequence"),e){var i=this.pos-1;this.invalidStringToken(i,"Invalid escape sequence in template string")}default:if(t>=48&&t<=55){var r=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(r,8);return s>255&&(r=r.slice(0,-1),s=parseInt(r,8)),this.pos+=r.length-1,t=this.input.charCodeAt(this.pos),(r!=="0"||t===56||t===57)&&(this.strict||e)&&this.invalidStringToken(this.pos-1-r.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return ee(t)?(this.options.locations&&(this.lineStart=this.pos,++this.curLine),""):String.fromCharCode(t)}};b.readHexChar=function(e){var t=this.pos,i=this.readInt(16,e);return i===null&&this.invalidStringToken(t,"Bad character escape sequence"),i};b.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,i=this.pos,r=this.options.ecmaVersion>=6;this.pos<this.input.length;){var s=this.fullCharCodeAtPos();if(K(s,r))this.pos+=s<=65535?1:2;else if(s===92){this.containsEsc=!0,e+=this.input.slice(i,this.pos);var n=this.pos;this.input.charCodeAt(++this.pos)!==117&&this.invalidStringToken(this.pos,"Expecting Unicode escape sequence \\uXXXX"),++this.pos;var o=this.readCodePoint();(t?j:K)(o,r)||this.invalidStringToken(n,"Invalid Unicode escape"),e+=G(o),i=this.pos}else break;t=!1}return e+this.input.slice(i,this.pos)};b.readWord=function(){var e=this.readWord1(),t=a.name;return this.keywords.test(e)&&(t=Ke[e]),this.finishToken(t,e)};var Tr="8.17.0";T.acorn={Parser:T,version:Tr,defaultOptions:We,Position:ue,SourceLocation:Se,getLineInfo:Et,Node:ke,TokenType:_,tokTypes:a,keywordTypes:Ke,TokContext:F,tokContexts:E,isIdentifierChar:K,isIdentifierStart:j,Token:Ze,isNewLine:ee,lineBreak:R,lineBreakG:zi,nonASCIIwhitespace:Ct};var Ri=lt(et(),1);function Lr(e,t){let i=new SyntaxError(e+" ("+t.loc.start.line+":"+t.loc.start.column+")");return Object.assign(i,t)}var Ae=Lr;function we(e){let t=[];for(let i of e)try{return i()}catch(r){t.push(r)}throw Object.assign(new Error("All combinations failed"),{errors:t})}var re=(e,t)=>(i,r,...s)=>i|1&&r==null?void 0:(t.call(r)??r[e]).apply(r,s);var Rr=Array.prototype.findLast??function(e){for(let t=this.length-1;t>=0;t--){let i=this[t];if(e(i,t,this))return i}},Vr=re("findLast",function(){if(Array.isArray(this))return Rr}),ai=Vr;var Ie=Symbol.for("comments");function Or(e){return this[e<0?this.length+e:e]}var Dr=re("at",function(){if(Array.isArray(this)||typeof this=="string")return Or}),Pe=Dr;function Y(e){let t=new Set(e);return i=>t.has(i?.type)}function se(e){return e.range?.[1]??e.end}function w(e){let t=e.range?.[0]??e.start,i=(e.declaration?.decorators??e.decorators)?.[0];return i?Math.min(w(i),t):t}var Mr=5,Br=8,Fr=8,ni=e=>t=>t.label?I(t.label):w(t)+e,jr=e=>e.__contentEnd??se(e),oi=["ExpressionStatement","Directive","ImportDeclaration","ExportDefaultDeclaration","ExportNamedDeclaration","ExportAllDeclaration","ReturnStatement","ThrowStatement","DoWhileStatement"],Ur=new Map([["BreakStatement",ni(Mr)],["ContinueStatement",ni(Br)],["DebuggerStatement",e=>w(e)+Fr],["VariableDeclaration",e=>I(Pe(0,e.declarations,-1))],...oi.map(e=>[e,jr])]),tt=Y(oi);function I(e){let{type:t}=e;return t==="IfStatement"?I(e.alternate??e.consequent):t==="ForInStatement"||t==="ForOfStatement"||t==="ForStatement"||t==="LabeledStatement"||t==="WithStatement"||t==="WhileStatement"?I(e.body):Ur.get(t)?.(e)??se(e)}var ae=Y(["Block","CommentBlock","MultiLine"]),ui=Y(["Line","CommentLine","SingleLine","HashbangComment","HTMLOpen","HTMLClose","Hashbang","InterpreterDirective"]);function ne(e,t,i){if(!e.has(t)){let r=i(t);e.set(t,r)}return e.get(t)}var Gr=new WeakMap;function hi(e){return ne(Gr,e,t=>ae(t)&&t.value[0]==="*"&&/@(?:type|satisfies)\b/.test(t.value))}var Wr=String.prototype.replaceAll??function(e,t){return e.global?this.replace(e,t):this.split(e).join(t)},qr=re("replaceAll",function(){if(typeof this=="string")return Wr}),Z=qr;function Hr(e){return Z(0,e,/[^\n]/g," ")}var ci=Hr;function Kr(e,t){for(let i of t){let r=w(i),s=I(i);e=e.slice(0,r)+ci(e.slice(r,s))+e.slice(s)}return e}var Jr=new WeakMap;function pi(e){let t=e[Ie];return ne(Jr,t,i=>Kr(e.originalText,i))}function Xr(e){if(!ae(e))return[];if(!e.value.includes(`+`;case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return G(this.readCodePoint());case 116:return"	";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 13:this.input.charCodeAt(this.pos)===10&&++this.pos;case 10:return this.options.locations&&(this.lineStart=this.pos,++this.curLine),"";case 56:case 57:if(this.strict&&this.invalidStringToken(this.pos-1,"Invalid escape sequence"),e){var i=this.pos-1;this.invalidStringToken(i,"Invalid escape sequence in template string")}default:if(t>=48&&t<=55){var r=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(r,8);return s>255&&(r=r.slice(0,-1),s=parseInt(r,8)),this.pos+=r.length-1,t=this.input.charCodeAt(this.pos),(r!=="0"||t===56||t===57)&&(this.strict||e)&&this.invalidStringToken(this.pos-1-r.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return ee(t)?(this.options.locations&&(this.lineStart=this.pos,++this.curLine),""):String.fromCharCode(t)}};b.readHexChar=function(e){var t=this.pos,i=this.readInt(16,e);return i===null&&this.invalidStringToken(t,"Bad character escape sequence"),i};b.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,i=this.pos,r=this.options.ecmaVersion>=6;this.pos<this.input.length;){var s=this.fullCharCodeAtPos();if(K(s,r))this.pos+=s<=65535?1:2;else if(s===92){this.containsEsc=!0,e+=this.input.slice(i,this.pos);var n=this.pos;this.input.charCodeAt(++this.pos)!==117&&this.invalidStringToken(this.pos,"Expecting Unicode escape sequence \\uXXXX"),++this.pos;var o=this.readCodePoint();(t?j:K)(o,r)||this.invalidStringToken(n,"Invalid Unicode escape"),e+=G(o),i=this.pos}else break;t=!1}return e+this.input.slice(i,this.pos)};b.readWord=function(){var e=this.readWord1(),t=a.name;return this.keywords.test(e)&&(t=Ke[e]),this.finishToken(t,e)};var Ar="8.17.0";A.acorn={Parser:A,version:Ar,defaultOptions:We,Position:ue,SourceLocation:Se,getLineInfo:Et,Node:ke,TokenType:_,tokTypes:a,keywordTypes:Ke,TokContext:F,tokContexts:k,isIdentifierChar:K,isIdentifierStart:j,Token:Ze,isNewLine:ee,lineBreak:R,lineBreakG:zi,nonASCIIwhitespace:Ct};var Ri=lt(et(),1);function Lr(e,t){let i=new SyntaxError(e+" ("+t.loc.start.line+":"+t.loc.start.column+")");return Object.assign(i,t)}var Te=Lr;function we(e){let t=[];for(let i of e)try{return i()}catch(r){t.push(r)}throw Object.assign(new Error("All combinations failed"),{errors:t})}var re=(e,t)=>(i,r,...s)=>i|1&&r==null?void 0:(t.call(r)??r[e]).apply(r,s);var Rr=Array.prototype.findLast??function(e){for(let t=this.length-1;t>=0;t--){let i=this[t];if(e(i,t,this))return i}},Vr=re("findLast",function(){if(Array.isArray(this))return Rr}),ai=Vr;var Ie=Symbol.for("comments");function Or(e){return this[e<0?this.length+e:e]}var Dr=re("at",function(){if(Array.isArray(this)||typeof this=="string")return Or}),Pe=Dr;function Y(e){let t=new Set(e);return i=>t.has(i?.type)}function se(e){return e.range?.[1]??e.end}function w(e){let t=e.range?.[0]??e.start,i=(e.declaration?.decorators??e.decorators)?.[0];return i?Math.min(w(i),t):t}var Mr=5,Br=8,Fr=8,ni=e=>t=>t.label?I(t.label):w(t)+e,jr=e=>e.__contentEnd??se(e),oi=["ExpressionStatement","Directive","ImportDeclaration","ExportDefaultDeclaration","ExportNamedDeclaration","ExportAllDeclaration","ReturnStatement","ThrowStatement","DoWhileStatement"],Ur=new Map([["BreakStatement",ni(Mr)],["ContinueStatement",ni(Br)],["DebuggerStatement",e=>w(e)+Fr],["VariableDeclaration",e=>I(Pe(0,e.declarations,-1))],...oi.map(e=>[e,jr])]),tt=Y(oi);function I(e){let{type:t}=e;return t==="IfStatement"?I(e.alternate??e.consequent):t==="ForInStatement"||t==="ForOfStatement"||t==="ForStatement"||t==="LabeledStatement"||t==="WithStatement"||t==="WhileStatement"?I(e.body):Ur.get(t)?.(e)??se(e)}var ae=Y(["Block","CommentBlock","MultiLine"]),ui=Y(["Line","CommentLine","SingleLine","HashbangComment","HTMLOpen","HTMLClose","Hashbang","InterpreterDirective"]);function ne(e,t,i){if(!e.has(t)){let r=i(t);e.set(t,r)}return e.get(t)}var Gr=new WeakMap;function hi(e){return ne(Gr,e,t=>ae(t)&&t.value[0]==="*"&&/@(?:type|satisfies)\b/.test(t.value))}var Wr=String.prototype.replaceAll??function(e,t){return e.global?this.replace(e,t):this.split(e).join(t)},qr=re("replaceAll",function(){if(typeof this=="string")return Wr}),Z=qr;function Hr(e){return Z(0,e,/[^\n]/g," ")}var ci=Hr;function Kr(e,t){for(let i of t){let r=w(i),s=I(i);e=e.slice(0,r)+ci(e.slice(r,s))+e.slice(s)}return e}var Jr=new WeakMap;function pi(e){let t=e[Ie];return ne(Jr,t,i=>Kr(e.originalText,i))}function Xr(e){if(!ae(e))return[];if(!e.value.includes(` `))return[];let t=[];for(let i of`*${e.value}*`.split(`-`)){if(i=i.trimStart(),!i.startsWith("*"))return[];t.push(i)}return t}var li=new WeakMap;function zr(e){return ne(li,e,Xr)}function fi(e){li.delete(e)}function it(e){return zr(e).length>0}function di(e){if(e.length<2)return;let t;for(let i=e.length-1;i>=0;i--){let r=e[i];if(t&&I(r)===w(t)&&it(r)&&it(t)&&(e.splice(i+1,1),r.value+="*//*"+t.value,r.range=[w(r),I(t)],fi(r)),!ui(r)&&!ae(r))throw new TypeError(`Unknown comment type: "${r.type}".`);t=r}}function Qr(e){return e!==null&&typeof e=="object"}var mi=Qr;var le=null;function fe(e){if(le!==null&&typeof le.property){let t=le;return le=fe.prototype=null,t}return le=fe.prototype=e??Object.create(null),new fe}var Yr=10;for(let e=0;e<=Yr;e++)fe();function rt(e){return fe(e)}function Zr(e,t="type"){rt(e);function i(r){let s=r[t],n=e[s];if(!Array.isArray(n))throw Object.assign(new Error(`Missing visitor keys for '${s}'.`),{node:r});return n}return i}var xi=Zr;var u=[["elements"],["left","right"],["value"],["directives","body"],["label"],["callee","typeArguments","arguments"],["test","consequent","alternate"],["body","test"],["expression"],["left","right","body"],["id","typeParameters","params","predicate","returnType","body"],["object","property"],["properties"],["decorators","key","typeParameters","params","returnType","body"],["decorators","key","value"],["argument"],["expressions"],["id","init"],["body"],["decorators","id","typeParameters","superClass","superTypeArguments","mixins","implements","body"],["declaration","specifiers","source","attributes"],["local"],["exported"],["decorators","variance","key","typeAnnotation","value"],["id"],["key","value"],["elementType"],["id","typeParameters"],["id","typeParameters","extends","body"],["id","body"],["typeAnnotation"],["id","typeParameters","right"],["name","typeAnnotation"],["types"],["qualification","id"],["elementTypes"],["expression","typeAnnotation"],["params"],["members"],["objectType","indexType"],["decorators","key","typeAnnotation","value"],["id","typeParameters","params","returnType","body"],["key","typeParameters","params","returnType"],["typeParameters","params","returnType"],["parameterName","typeAnnotation"],["checkType","extendsType","trueType","falseType"],["typeParameter"],["literal"],["expression","typeArguments"],["decorators","key","typeAnnotation"],["argument","cases"],["pattern","body","guard"],["properties","rest"],["node"]],yi={ArrayExpression:u[0],AssignmentExpression:u[1],BinaryExpression:u[1],InterpreterDirective:[],Directive:u[2],DirectiveLiteral:[],BlockStatement:u[3],BreakStatement:u[4],CallExpression:u[5],CatchClause:["param","body"],ConditionalExpression:u[6],ContinueStatement:u[4],DebuggerStatement:[],DoWhileStatement:u[7],EmptyStatement:[],ExpressionStatement:u[8],File:["program"],ForInStatement:u[9],ForStatement:["init","test","update","body"],FunctionDeclaration:u[10],FunctionExpression:u[10],Identifier:["typeAnnotation","decorators"],IfStatement:u[6],LabeledStatement:["label","body"],StringLiteral:[],NumericLiteral:[],NullLiteral:[],BooleanLiteral:[],RegExpLiteral:[],LogicalExpression:u[1],MemberExpression:u[11],NewExpression:u[5],Program:u[3],ObjectExpression:u[12],ObjectMethod:u[13],ObjectProperty:u[14],RestElement:["argument","typeAnnotation","decorators"],ReturnStatement:u[15],SequenceExpression:u[16],ParenthesizedExpression:u[8],SwitchCase:["test","consequent"],SwitchStatement:["discriminant","cases"],ThisExpression:[],ThrowStatement:u[15],TryStatement:["block","handler","finalizer"],UnaryExpression:u[15],UpdateExpression:u[15],VariableDeclaration:["declarations"],VariableDeclarator:u[17],WhileStatement:u[7],WithStatement:["object","body"],AssignmentPattern:["left","right","decorators","typeAnnotation"],ArrayPattern:["elements","typeAnnotation","decorators"],ArrowFunctionExpression:["typeParameters","params","predicate","returnType","body"],ClassBody:u[18],ClassExpression:u[19],ClassDeclaration:u[19],ExportAllDeclaration:["source","attributes","exported"],ExportDefaultDeclaration:["declaration"],ExportNamedDeclaration:u[20],ExportSpecifier:["local","exported"],ForOfStatement:u[9],ImportDeclaration:["specifiers","source","attributes"],ImportDefaultSpecifier:u[21],ImportNamespaceSpecifier:u[21],ImportSpecifier:["imported","local"],MetaProperty:["meta","property"],ClassMethod:u[13],ObjectPattern:["decorators","properties","typeAnnotation"],SpreadElement:u[15],Super:[],TaggedTemplateExpression:["tag","typeArguments","quasi"],TemplateElement:[],TemplateLiteral:["quasis","expressions"],YieldExpression:u[15],AwaitExpression:u[15],ImportExpression:["source","options"],BigIntLiteral:[],ExportNamespaceSpecifier:u[22],OptionalMemberExpression:u[11],OptionalCallExpression:u[5],ClassProperty:u[23],ClassPrivateProperty:u[23],ClassPrivateMethod:u[13],PrivateName:u[24],StaticBlock:u[18],ImportAttribute:u[25],AnyTypeAnnotation:[],ArrayTypeAnnotation:u[26],BooleanTypeAnnotation:[],BooleanLiteralTypeAnnotation:[],NullLiteralTypeAnnotation:[],ClassImplements:u[27],DeclareClass:["id","typeParameters","extends","mixins","implements","body"],DeclareFunction:["id","predicate"],DeclareInterface:u[28],DeclareModule:u[29],DeclareModuleExports:u[30],DeclareTypeAlias:u[31],DeclareOpaqueType:["id","typeParameters","supertype","lowerBound","upperBound"],DeclareVariable:["id","declarations"],DeclareExportDeclaration:u[20],DeclareExportAllDeclaration:["source","attributes"],DeclaredPredicate:u[2],ExistsTypeAnnotation:[],FunctionTypeAnnotation:["typeParameters","this","params","rest","returnType"],FunctionTypeParam:u[32],GenericTypeAnnotation:u[27],InferredPredicate:[],InterfaceExtends:u[27],InterfaceDeclaration:u[28],InterfaceTypeAnnotation:["extends","body"],IntersectionTypeAnnotation:u[33],MixedTypeAnnotation:[],EmptyTypeAnnotation:[],NullableTypeAnnotation:u[30],NumberLiteralTypeAnnotation:[],BigIntLiteralTypeAnnotation:[],NumberTypeAnnotation:[],ObjectTypeAnnotation:["properties","indexers","callProperties","internalSlots"],ObjectTypeInternalSlot:["id","value"],ObjectTypeCallProperty:u[2],ObjectTypeIndexer:["variance","id","key","value"],ObjectTypeProperty:["key","value","variance"],ObjectTypeSpreadProperty:u[15],OpaqueType:["id","typeParameters","supertype","impltype","lowerBound","upperBound"],QualifiedTypeIdentifier:u[34],StringLiteralTypeAnnotation:[],StringTypeAnnotation:[],SymbolTypeAnnotation:[],ThisTypeAnnotation:[],TupleTypeAnnotation:u[35],TypeofTypeAnnotation:["argument","typeArguments"],TypeAlias:u[31],TypeAnnotation:u[30],TypeCastExpression:u[36],TypeParameter:["bound","default","variance"],TypeParameterDeclaration:u[37],TypeParameterInstantiation:u[37],UnionTypeAnnotation:u[33],Variance:[],VoidTypeAnnotation:[],EnumDeclaration:u[29],EnumBooleanBody:u[38],EnumNumberBody:u[38],EnumStringBody:u[38],EnumSymbolBody:u[38],EnumBooleanMember:u[17],EnumNumberMember:u[17],EnumStringMember:u[17],EnumDefaultedMember:u[24],IndexedAccessType:u[39],OptionalIndexedAccessType:u[39],JSXAttribute:["name","value"],JSXClosingElement:["name"],JSXElement:["openingElement","children","closingElement"],JSXEmptyExpression:[],JSXExpressionContainer:u[8],JSXSpreadChild:u[8],JSXIdentifier:[],JSXMemberExpression:u[11],JSXNamespacedName:["namespace","name"],JSXOpeningElement:["name","typeArguments","attributes"],JSXSpreadAttribute:u[15],JSXText:[],JSXFragment:["openingFragment","children","closingFragment"],JSXOpeningFragment:[],JSXClosingFragment:[],Placeholder:[],V8IntrinsicIdentifier:[],ArgumentPlaceholder:[],BindExpression:["object","callee"],ClassAccessorProperty:u[40],Decorator:u[8],DoExpression:u[18],ExportDefaultSpecifier:u[22],ModuleExpression:u[18],TopicReference:[],VoidPattern:[],TSParameterProperty:["parameter","decorators"],TSDeclareFunction:u[41],TSDeclareMethod:u[42],TSQualifiedName:u[1],TSCallSignatureDeclaration:u[43],TSConstructSignatureDeclaration:u[43],TSPropertySignature:["key","typeAnnotation"],TSMethodSignature:u[42],TSIndexSignature:["parameters","typeAnnotation"],TSAnyKeyword:[],TSBooleanKeyword:[],TSBigIntKeyword:[],TSIntrinsicKeyword:[],TSNeverKeyword:[],TSNullKeyword:[],TSNumberKeyword:[],TSObjectKeyword:[],TSStringKeyword:[],TSSymbolKeyword:[],TSUndefinedKeyword:[],TSUnknownKeyword:[],TSVoidKeyword:[],TSThisType:[],TSFunctionType:u[43],TSConstructorType:u[43],TSTypeReference:["typeName","typeArguments"],TSTypePredicate:u[44],TSTypeQuery:["exprName","typeArguments"],TSTypeLiteral:u[38],TSArrayType:u[26],TSTupleType:u[35],TSOptionalType:u[30],TSRestType:u[30],TSNamedTupleMember:["label","elementType"],TSUnionType:u[33],TSIntersectionType:u[33],TSConditionalType:u[45],TSInferType:u[46],TSParenthesizedType:u[30],TSTypeOperator:u[30],TSIndexedAccessType:u[39],TSMappedType:["key","constraint","nameType","typeAnnotation"],TSTemplateLiteralType:["quasis","types"],TSLiteralType:u[47],TSClassImplements:u[48],TSInterfaceHeritage:u[48],TSInterfaceDeclaration:u[28],TSInterfaceBody:u[18],TSTypeAliasDeclaration:["id","typeParameters","typeAnnotation"],TSInstantiationExpression:u[48],TSAsExpression:u[36],TSSatisfiesExpression:u[36],TSTypeAssertion:u[36],TSEnumBody:u[38],TSEnumDeclaration:u[29],TSEnumMember:["id","initializer"],TSModuleDeclaration:u[29],TSModuleBlock:u[18],TSImportType:["source","options","qualifier","typeArguments"],TSImportEqualsDeclaration:["id","moduleReference"],TSExternalModuleReference:u[8],TSNonNullExpression:u[8],TSExportAssignment:u[8],TSNamespaceExportDeclaration:u[24],TSTypeAnnotation:u[30],TSTypeParameterInstantiation:u[37],TSTypeParameterDeclaration:u[37],TSTypeParameter:["name","constraint","default"],ChainExpression:u[8],Literal:[],MethodDefinition:u[14],PrivateIdentifier:[],Property:u[25],PropertyDefinition:u[23],AccessorProperty:u[40],TSAbstractAccessorProperty:u[49],TSAbstractKeyword:[],TSAbstractMethodDefinition:u[25],TSAbstractPropertyDefinition:u[49],TSAsyncKeyword:[],TSDeclareKeyword:[],TSEmptyBodyFunctionExpression:["id","typeParameters","params","returnType"],TSExportKeyword:[],TSPrivateKeyword:[],TSProtectedKeyword:[],TSPublicKeyword:[],TSReadonlyKeyword:[],TSStaticKeyword:[],AsConstExpression:u[8],AsExpression:u[36],BigIntTypeAnnotation:[],ComponentDeclaration:["id","params","body","typeParameters","rendersType"],ComponentParameter:["name","local"],ComponentTypeAnnotation:["params","rest","typeParameters","rendersType"],ComponentTypeParameter:u[32],ConditionalTypeAnnotation:u[45],DeclareComponent:["id","params","rest","typeParameters","rendersType"],DeclareEnum:u[29],DeclareHook:u[24],DeclareNamespace:u[29],EnumBigIntBody:u[38],EnumBigIntMember:u[17],EnumBody:u[38],HookDeclaration:u[41],HookTypeAnnotation:["params","returnType","rest","typeParameters"],InferTypeAnnotation:u[46],KeyofTypeAnnotation:u[15],MatchArrayPattern:["elements","rest"],MatchAsPattern:["pattern","target"],MatchBindingPattern:u[24],MatchExpression:u[50],MatchExpressionCase:u[51],MatchIdentifierPattern:u[24],MatchInstanceObjectPattern:u[52],MatchInstancePattern:["targetConstructor","properties"],MatchLiteralPattern:u[47],MatchMemberPattern:["base","property"],MatchObjectPattern:u[52],MatchObjectPatternProperty:["key","pattern"],MatchOrPattern:["patterns"],MatchRestPattern:u[15],MatchStatement:u[50],MatchStatementCase:u[51],MatchUnaryPattern:u[15],MatchWildcardPattern:[],NeverTypeAnnotation:[],ObjectTypeMappedTypeProperty:["keyTparam","propType","sourceType","variance"],QualifiedTypeofIdentifier:u[34],RecordDeclaration:["id","typeParameters","implements","body"],RecordDeclarationBody:u[0],RecordDeclarationImplements:["id","typeArguments"],RecordDeclarationProperty:["key","typeAnnotation","defaultValue"],RecordDeclarationStaticProperty:["key","typeAnnotation","value"],RecordExpression:["recordConstructor","typeArguments","properties"],RecordExpressionProperties:u[12],SatisfiesExpression:u[36],TupleTypeLabeledElement:["label","elementType","variance"],TupleTypeSpreadElement:["label","typeAnnotation"],TypeOperator:u[30],TypePredicate:u[44],UndefinedTypeAnnotation:[],UnknownTypeAnnotation:[],NGChainedExpression:u[16],NGEmptyExpression:[],NGPipeExpression:["left","right","arguments"],NGMicrosyntax:u[18],NGMicrosyntaxAs:["key","alias"],NGMicrosyntaxExpression:["expression","alias"],NGMicrosyntaxKey:[],NGMicrosyntaxKeyedExpression:["key","expression"],NGMicrosyntaxLet:u[25],NGRoot:u[53],JsExpressionRoot:u[53],JsonRoot:u[53],TSJSDocAllType:[],TSJSDocUnknownType:[],TSJSDocNullableType:u[30],TSJSDocNonNullableType:u[30]};var $r=xi(yi),gi=$r;function Ne(e,t){if(!mi(e))return e;if(Array.isArray(e)){for(let r=0;r<e.length;r++)e[r]=Ne(e[r],t);return e}if(t.onEnter){let r=t.onEnter(e)??e;if(r!==e)return Ne(r,t);e=r}let i=gi(e);for(let r=0;r<i.length;r++)e[i[r]]=Ne(e[i[r]],t);return t.onLeave&&(e=t.onLeave(e)||e),e}var vi=Ne;var Ga=Y(["RegExpLiteral","BigIntLiteral","NumericLiteral","StringLiteral","DirectiveLiteral","Literal","JSXText","TemplateElement","StringLiteralTypeAnnotation","NumberLiteralTypeAnnotation","BigIntLiteralTypeAnnotation"]);function es(e,t){let{text:i,astType:r}=t,s=r==="oxc-ts",{comments:n}=e;di(n);let o=e.type==="File"?e.program:e;o.interpreter&&(n.unshift(o.interpreter),delete o.interpreter),e.hashbang&&(s&&n.unshift(e.hashbang),delete e.hashbang),e.type==="Program"&&(e.range=[0,i.length]);let c;return e=vi(e,{onEnter(h){switch(ts(h,n,i),h.type){case"ParenthesizedExpression":{let{expression:l}=h,m=w(h);if(l.type==="TypeCastExpression")return l.range=[m,I(h)],l;let S=!1;if(!s){if(!c){c=[];for(let p of n)hi(p)&&c.push(I(p))}let k=ai(0,c,p=>p<=m);S=k&&i.slice(k,m).trim().length===0}return S?void 0:(l.extra={...l.extra,parenthesized:!0},l)}case"TemplateLiteral":if(h.expressions.length!==h.quasis.length-1)throw new Error("Malformed template literal.");break;case"TemplateElement":if(r==="flow"||r==="hermes"||r==="espree"||r==="typescript"||s){let l=w(h)+1,m=I(h)-(h.tail?1:2);h.range=[l,m]}break;case"TSParenthesizedType":return h.typeAnnotation;case"TopicReference":e.extra={...e.extra,__isUsingHackPipeline:!0};break;case"TSUnionType":case"TSIntersectionType":if(h.types.length===1)return h.types[0];break;case"TupleTypeAnnotation":h.types&&!h.elementTypes&&(h.elementTypes=h.types);break;case"ImportDeclaration":r==="hermes"&&h.assertions&&!h.attributes&&(h.attributes=h.assertions,delete h.assertions);break}},onLeave(h){switch(h.type){case"LogicalExpression":if(bi(h))return st(h);break}}}),e}function bi(e){return e.type==="LogicalExpression"&&e.right.type==="LogicalExpression"&&e.operator===e.right.operator}function st(e){return bi(e)?st({type:"LogicalExpression",operator:e.operator,left:st({type:"LogicalExpression",operator:e.operator,left:e.left,right:e.right.left,range:[w(e.left),I(e.right.left)]}),right:e.right.right,range:[w(e),I(e)]}):e}function ts(e,t,i){if(!tt(e))return;let r=se(e);if(i[r-1]!==";")return;let s=pi({[Ie]:t,originalText:i});r-=1;let n=s.slice(w(e),r),o=n.trimEnd();e.__contentEnd=r-(n.length-o.length)}var Le=es;var is=Object.hasOwn??Function.prototype.call.bind(Object.prototype.hasOwnProperty),at=is;var rs=/\*\/$/,ss=/^\/\*\*?/,as=/^\s*(\/\*\*?(.|\r?\n)*?\*\/)/,ns=/(^|\s+)\/\/([^\n\r]*)/g,Si=/^(\r?\n)+/,os=/(?:^|\r?\n) *(@[^\n\r]*?) *\r?\n *(?![^\n\r@]*\/\/[^]*)([^\s@][^\n\r@]+?) *\r?\n/g,Ci=/(?:^|\r?\n) *@(\S+) *([^\n\r]*)/g,us=/(\r?\n|^) *\* ?/g,hs=[];function _i(e){let t=e.match(as);return t?t[0].trimStart():""}function Ei(e){e=Z(0,e.replace(ss,"").replace(rs,""),us,"$1");let i="";for(;i!==e;)i=e,e=Z(0,e,os,`+`)){if(i=i.trimStart(),!i.startsWith("*"))return[];t.push(i)}return t}var li=new WeakMap;function zr(e){return ne(li,e,Xr)}function fi(e){li.delete(e)}function it(e){return zr(e).length>0}function di(e){if(e.length<2)return;let t;for(let i=e.length-1;i>=0;i--){let r=e[i];if(t&&I(r)===w(t)&&it(r)&&it(t)&&(e.splice(i+1,1),r.value+="*//*"+t.value,r.range=[w(r),I(t)],fi(r)),!ui(r)&&!ae(r))throw new TypeError(`Unknown comment type: "${r.type}".`);t=r}}function Qr(e){return e!==null&&typeof e=="object"}var mi=Qr;var le=null;function fe(e){if(le!==null&&typeof le.property){let t=le;return le=fe.prototype=null,t}return le=fe.prototype=e??Object.create(null),new fe}var Yr=10;for(let e=0;e<=Yr;e++)fe();function rt(e){return fe(e)}function Zr(e,t="type"){rt(e);function i(r){let s=r[t],n=e[s];if(!Array.isArray(n))throw Object.assign(new Error(`Missing visitor keys for '${s}'.`),{node:r});return n}return i}var xi=Zr;var u=[["elements"],["left","right"],["value"],["directives","body"],["label"],["callee","typeArguments","arguments"],["test","consequent","alternate"],["body","test"],["expression"],["left","right","body"],["id","typeParameters","params","predicate","returnType","body"],["object","property"],["properties"],["decorators","key","typeParameters","params","returnType","body"],["decorators","key","value"],["argument"],["expressions"],["id","init"],["body"],["decorators","id","typeParameters","superClass","superTypeArguments","mixins","implements","body"],["declaration","specifiers","source","attributes"],["local"],["exported"],["decorators","variance","key","typeAnnotation","value"],["id"],["key","value"],["elementType"],["id","typeParameters"],["id","typeParameters","extends","body"],["id","body"],["typeAnnotation"],["id","typeParameters","right"],["name","typeAnnotation"],["types"],["qualification","id"],["elementTypes"],["expression","typeAnnotation"],["params"],["members"],["objectType","indexType"],["decorators","key","typeAnnotation","value"],["id","typeParameters","params","returnType","body"],["key","typeParameters","params","returnType"],["typeParameters","params","returnType"],["parameterName","typeAnnotation"],["checkType","extendsType","trueType","falseType"],["typeParameter"],["literal"],["expression","typeArguments"],["decorators","key","typeAnnotation"],["argument","cases"],["pattern","body","guard"],["properties","rest"],["node"]],yi={ArrayExpression:u[0],AssignmentExpression:u[1],BinaryExpression:u[1],InterpreterDirective:[],Directive:u[2],DirectiveLiteral:[],BlockStatement:u[3],BreakStatement:u[4],CallExpression:u[5],CatchClause:["param","body"],ConditionalExpression:u[6],ContinueStatement:u[4],DebuggerStatement:[],DoWhileStatement:u[7],EmptyStatement:[],ExpressionStatement:u[8],File:["program"],ForInStatement:u[9],ForStatement:["init","test","update","body"],FunctionDeclaration:u[10],FunctionExpression:u[10],Identifier:["typeAnnotation","decorators"],IfStatement:u[6],LabeledStatement:["label","body"],StringLiteral:[],NumericLiteral:[],NullLiteral:[],BooleanLiteral:[],RegExpLiteral:[],LogicalExpression:u[1],MemberExpression:u[11],NewExpression:u[5],Program:u[3],ObjectExpression:u[12],ObjectMethod:u[13],ObjectProperty:u[14],RestElement:["argument","typeAnnotation","decorators"],ReturnStatement:u[15],SequenceExpression:u[16],ParenthesizedExpression:u[8],SwitchCase:["test","consequent"],SwitchStatement:["discriminant","cases"],ThisExpression:[],ThrowStatement:u[15],TryStatement:["block","handler","finalizer"],UnaryExpression:u[15],UpdateExpression:u[15],VariableDeclaration:["declarations"],VariableDeclarator:u[17],WhileStatement:u[7],WithStatement:["object","body"],AssignmentPattern:["left","right","decorators","typeAnnotation"],ArrayPattern:["elements","typeAnnotation","decorators"],ArrowFunctionExpression:["typeParameters","params","predicate","returnType","body"],ClassBody:u[18],ClassExpression:u[19],ClassDeclaration:u[19],ExportAllDeclaration:["source","attributes","exported"],ExportDefaultDeclaration:["declaration"],ExportNamedDeclaration:u[20],ExportSpecifier:["local","exported"],ForOfStatement:u[9],ImportDeclaration:["specifiers","source","attributes"],ImportDefaultSpecifier:u[21],ImportNamespaceSpecifier:u[21],ImportSpecifier:["imported","local"],MetaProperty:["meta","property"],ClassMethod:u[13],ObjectPattern:["decorators","properties","typeAnnotation"],SpreadElement:u[15],Super:[],TaggedTemplateExpression:["tag","typeArguments","quasi"],TemplateElement:[],TemplateLiteral:["quasis","expressions"],YieldExpression:u[15],AwaitExpression:u[15],ImportExpression:["source","options"],BigIntLiteral:[],ExportNamespaceSpecifier:u[22],OptionalMemberExpression:u[11],OptionalCallExpression:u[5],ClassProperty:u[23],ClassPrivateProperty:u[23],ClassPrivateMethod:u[13],PrivateName:u[24],StaticBlock:u[18],ImportAttribute:u[25],AnyTypeAnnotation:[],ArrayTypeAnnotation:u[26],BooleanTypeAnnotation:[],BooleanLiteralTypeAnnotation:[],NullLiteralTypeAnnotation:[],ClassImplements:u[27],DeclareClass:["id","typeParameters","extends","mixins","implements","body"],DeclareFunction:["id","predicate"],DeclareInterface:u[28],DeclareModule:u[29],DeclareModuleExports:u[30],DeclareTypeAlias:u[31],DeclareOpaqueType:["id","typeParameters","supertype","lowerBound","upperBound"],DeclareVariable:["id","declarations"],DeclareExportDeclaration:u[20],DeclareExportAllDeclaration:["source","attributes"],DeclaredPredicate:u[2],ExistsTypeAnnotation:[],FunctionTypeAnnotation:["typeParameters","this","params","rest","returnType"],FunctionTypeParam:u[32],GenericTypeAnnotation:u[27],InferredPredicate:[],InterfaceExtends:u[27],InterfaceDeclaration:u[28],InterfaceTypeAnnotation:["extends","body"],IntersectionTypeAnnotation:u[33],MixedTypeAnnotation:[],EmptyTypeAnnotation:[],NullableTypeAnnotation:u[30],NumberLiteralTypeAnnotation:[],BigIntLiteralTypeAnnotation:[],NumberTypeAnnotation:[],ObjectTypeAnnotation:["properties","indexers","callProperties","internalSlots"],ObjectTypeInternalSlot:["id","value"],ObjectTypeCallProperty:u[2],ObjectTypeIndexer:["variance","id","key","value"],ObjectTypeProperty:["key","value","variance"],ObjectTypeSpreadProperty:u[15],OpaqueType:["id","typeParameters","supertype","impltype","lowerBound","upperBound"],QualifiedTypeIdentifier:u[34],StringLiteralTypeAnnotation:[],StringTypeAnnotation:[],SymbolTypeAnnotation:[],ThisTypeAnnotation:[],TupleTypeAnnotation:u[35],TypeofTypeAnnotation:["argument","typeArguments"],TypeAlias:u[31],TypeAnnotation:u[30],TypeCastExpression:u[36],TypeParameter:["bound","default","variance"],TypeParameterDeclaration:u[37],TypeParameterInstantiation:u[37],UnionTypeAnnotation:u[33],Variance:[],VoidTypeAnnotation:[],EnumDeclaration:u[29],EnumBooleanBody:u[38],EnumNumberBody:u[38],EnumStringBody:u[38],EnumSymbolBody:u[38],EnumBooleanMember:u[17],EnumNumberMember:u[17],EnumStringMember:u[17],EnumDefaultedMember:u[24],IndexedAccessType:u[39],OptionalIndexedAccessType:u[39],JSXAttribute:["name","value"],JSXClosingElement:["name"],JSXElement:["openingElement","children","closingElement"],JSXEmptyExpression:[],JSXExpressionContainer:u[8],JSXSpreadChild:u[8],JSXIdentifier:[],JSXMemberExpression:u[11],JSXNamespacedName:["namespace","name"],JSXOpeningElement:["name","typeArguments","attributes"],JSXSpreadAttribute:u[15],JSXText:[],JSXFragment:["openingFragment","children","closingFragment"],JSXOpeningFragment:[],JSXClosingFragment:[],Placeholder:[],V8IntrinsicIdentifier:[],ArgumentPlaceholder:[],BindExpression:["object","callee"],ClassAccessorProperty:u[40],Decorator:u[8],DoExpression:u[18],ExportDefaultSpecifier:u[22],ModuleExpression:u[18],TopicReference:[],VoidPattern:[],TSParameterProperty:["parameter","decorators"],TSDeclareFunction:u[41],TSDeclareMethod:u[42],TSQualifiedName:u[1],TSCallSignatureDeclaration:u[43],TSConstructSignatureDeclaration:u[43],TSPropertySignature:["key","typeAnnotation"],TSMethodSignature:u[42],TSIndexSignature:["parameters","typeAnnotation"],TSAnyKeyword:[],TSBooleanKeyword:[],TSBigIntKeyword:[],TSIntrinsicKeyword:[],TSNeverKeyword:[],TSNullKeyword:[],TSNumberKeyword:[],TSObjectKeyword:[],TSStringKeyword:[],TSSymbolKeyword:[],TSUndefinedKeyword:[],TSUnknownKeyword:[],TSVoidKeyword:[],TSThisType:[],TSFunctionType:u[43],TSConstructorType:u[43],TSTypeReference:["typeName","typeArguments"],TSTypePredicate:u[44],TSTypeQuery:["exprName","typeArguments"],TSTypeLiteral:u[38],TSArrayType:u[26],TSTupleType:u[35],TSOptionalType:u[30],TSRestType:u[30],TSNamedTupleMember:["label","elementType"],TSUnionType:u[33],TSIntersectionType:u[33],TSConditionalType:u[45],TSInferType:u[46],TSParenthesizedType:u[30],TSTypeOperator:u[30],TSIndexedAccessType:u[39],TSMappedType:["key","constraint","nameType","typeAnnotation"],TSTemplateLiteralType:["quasis","types"],TSLiteralType:u[47],TSClassImplements:u[48],TSInterfaceHeritage:u[48],TSInterfaceDeclaration:u[28],TSInterfaceBody:u[18],TSTypeAliasDeclaration:["id","typeParameters","typeAnnotation"],TSInstantiationExpression:u[48],TSAsExpression:u[36],TSSatisfiesExpression:u[36],TSTypeAssertion:u[36],TSEnumBody:u[38],TSEnumDeclaration:u[29],TSEnumMember:["id","initializer"],TSModuleDeclaration:u[29],TSModuleBlock:u[18],TSImportType:["source","options","qualifier","typeArguments"],TSImportEqualsDeclaration:["id","moduleReference"],TSExternalModuleReference:u[8],TSNonNullExpression:u[8],TSExportAssignment:u[8],TSNamespaceExportDeclaration:u[24],TSTypeAnnotation:u[30],TSTypeParameterInstantiation:u[37],TSTypeParameterDeclaration:u[37],TSTypeParameter:["name","constraint","default"],ChainExpression:u[8],Literal:[],MethodDefinition:u[14],PrivateIdentifier:[],Property:u[25],PropertyDefinition:u[23],AccessorProperty:u[40],TSAbstractAccessorProperty:u[49],TSAbstractKeyword:[],TSAbstractMethodDefinition:u[25],TSAbstractPropertyDefinition:u[49],TSAsyncKeyword:[],TSDeclareKeyword:[],TSEmptyBodyFunctionExpression:["id","typeParameters","params","returnType"],TSExportKeyword:[],TSPrivateKeyword:[],TSProtectedKeyword:[],TSPublicKeyword:[],TSReadonlyKeyword:[],TSStaticKeyword:[],AsConstExpression:u[8],AsExpression:u[36],BigIntTypeAnnotation:[],ComponentDeclaration:["id","params","body","typeParameters","rendersType"],ComponentParameter:["name","local"],ComponentTypeAnnotation:["params","rest","typeParameters","rendersType"],ComponentTypeParameter:u[32],ConditionalTypeAnnotation:u[45],DeclareComponent:["id","params","rest","typeParameters","rendersType"],DeclareEnum:u[29],DeclareHook:u[24],DeclareNamespace:u[29],EnumBigIntBody:u[38],EnumBigIntMember:u[17],EnumBody:u[38],HookDeclaration:u[41],HookTypeAnnotation:["params","returnType","rest","typeParameters"],InferTypeAnnotation:u[46],KeyofTypeAnnotation:u[15],MatchArrayPattern:["elements","rest"],MatchAsPattern:["pattern","target"],MatchBindingPattern:u[24],MatchExpression:u[50],MatchExpressionCase:u[51],MatchIdentifierPattern:u[24],MatchInstanceObjectPattern:u[52],MatchInstancePattern:["targetConstructor","properties"],MatchLiteralPattern:u[47],MatchMemberPattern:["base","property"],MatchObjectPattern:u[52],MatchObjectPatternProperty:["key","pattern"],MatchOrPattern:["patterns"],MatchRestPattern:u[15],MatchStatement:u[50],MatchStatementCase:u[51],MatchUnaryPattern:u[15],MatchWildcardPattern:[],NeverTypeAnnotation:[],ObjectTypeMappedTypeProperty:["keyTparam","propType","sourceType","variance"],QualifiedTypeofIdentifier:u[34],RecordDeclaration:["id","typeParameters","implements","body"],RecordDeclarationBody:u[0],RecordDeclarationImplements:["id","typeArguments"],RecordDeclarationProperty:["key","typeAnnotation","defaultValue"],RecordDeclarationStaticProperty:["key","typeAnnotation","value"],RecordExpression:["recordConstructor","typeArguments","properties"],RecordExpressionProperties:u[12],SatisfiesExpression:u[36],TupleTypeLabeledElement:["label","elementType","variance"],TupleTypeSpreadElement:["label","typeAnnotation"],TypeOperator:u[30],TypePredicate:u[44],UndefinedTypeAnnotation:[],UnknownTypeAnnotation:[],NGChainedExpression:u[16],NGEmptyExpression:[],NGPipeExpression:["left","right","arguments"],NGMicrosyntax:u[18],NGMicrosyntaxAs:["key","alias"],NGMicrosyntaxExpression:["expression","alias"],NGMicrosyntaxKey:[],NGMicrosyntaxKeyedExpression:["key","expression"],NGMicrosyntaxLet:u[25],NGRoot:u[53],JsExpressionRoot:u[53],JsonRoot:u[53],TSJSDocAllType:[],TSJSDocUnknownType:[],TSJSDocNullableType:u[30],TSJSDocNonNullableType:u[30]};var $r=xi(yi),gi=$r;function Ne(e,t){if(!mi(e))return e;if(Array.isArray(e)){for(let r=0;r<e.length;r++)e[r]=Ne(e[r],t);return e}if(t.onEnter){let r=t.onEnter(e)??e;if(r!==e)return Ne(r,t);e=r}let i=gi(e);for(let r=0;r<i.length;r++)e[i[r]]=Ne(e[i[r]],t);return t.onLeave&&(e=t.onLeave(e)||e),e}var vi=Ne;var Ga=Y(["RegExpLiteral","BigIntLiteral","NumericLiteral","StringLiteral","DirectiveLiteral","Literal","JSXText","TemplateElement","StringLiteralTypeAnnotation","NumberLiteralTypeAnnotation","BigIntLiteralTypeAnnotation"]);function es(e,t){let{text:i,astType:r}=t,{comments:s}=e;di(s);let n=e.type==="File"?e.program:e;n.interpreter&&(s.unshift(n.interpreter),delete n.interpreter),e.hashbang&&((r==="oxc-ts"||r==="yuku-js"||r==="yuku-ts")&&s.unshift(e.hashbang),delete e.hashbang),e.type==="Program"&&(e.range=[0,i.length]);let o;return e=vi(e,{onEnter(h){switch(ts(h,s,i),h.type){case"ParenthesizedExpression":{let{expression:c}=h,l=w(h);if(c.type==="TypeCastExpression")return c.range=[l,I(h)],c;let m=!1;if(r!=="oxc-ts"){if(!o){o=[];for(let E of s)hi(E)&&o.push(I(E))}let S=ai(0,o,E=>E<=l);m=S&&i.slice(S,l).trim().length===0}return m?void 0:(c.extra={...c.extra,parenthesized:!0},c)}case"TemplateLiteral":if(h.expressions.length!==h.quasis.length-1)throw new Error("Malformed template literal.");break;case"TemplateElement":if(r==="flow"||r==="hermes"||r==="espree"||r==="typescript"||r==="oxc-ts"||r==="yuku-ts"){let c=w(h)+1,l=I(h)-(h.tail?1:2);h.range=[c,l]}break;case"TSParenthesizedType":return h.typeAnnotation;case"TopicReference":e.extra={...e.extra,__isUsingHackPipeline:!0};break;case"TSUnionType":case"TSIntersectionType":if(h.types.length===1)return h.types[0];break;case"TupleTypeAnnotation":h.types&&!h.elementTypes&&(h.elementTypes=h.types);break;case"ImportDeclaration":r==="hermes"&&h.assertions&&!h.attributes&&(h.attributes=h.assertions,delete h.assertions);break}},onLeave(h){switch(h.type){case"LogicalExpression":if(bi(h))return st(h);break}}}),e}function bi(e){return e.type==="LogicalExpression"&&e.right.type==="LogicalExpression"&&e.operator===e.right.operator}function st(e){return bi(e)?st({type:"LogicalExpression",operator:e.operator,left:st({type:"LogicalExpression",operator:e.operator,left:e.left,right:e.right.left,range:[w(e.left),I(e.right.left)]}),right:e.right.right,range:[w(e),I(e)]}):e}function ts(e,t,i){if(!tt(e))return;let r=se(e);if(i[r-1]!==";")return;let s=pi({[Ie]:t,originalText:i});r-=1;let n=s.slice(w(e),r),o=n.trimEnd();e.__contentEnd=r-(n.length-o.length)}var Le=es;var is=Object.hasOwn??Function.prototype.call.bind(Object.prototype.hasOwnProperty),at=is;var rs=/\*\/$/,ss=/^\/\*\*?/,as=/^\s*(\/\*\*?(.|\r?\n)*?\*\/)/,ns=/(^|\s+)\/\/([^\n\r]*)/g,Si=/^(\r?\n)+/,os=/(?:^|\r?\n) *(@[^\n\r]*?) *\r?\n *(?![^\n\r@]*\/\/[^]*)([^\s@][^\n\r@]+?) *\r?\n/g,Ci=/(?:^|\r?\n) *@(\S+) *([^\n\r]*)/g,us=/(\r?\n|^) *\* ?/g,hs=[];function _i(e){let t=e.match(as);return t?t[0].trimStart():""}function Ei(e){e=Z(0,e.replace(ss,"").replace(rs,""),us,"$1");let i="";for(;i!==e;)i=e,e=Z(0,e,os,` $1 $2-`);e=e.replace(Si,"").trimEnd();let r=Object.create(null),s=Z(0,e,Ci,"").replace(Si,"").trimEnd(),n;for(;n=Ci.exec(e);){let o=Z(0,n[2],ns,"");if(typeof r[n[1]]=="string"||Array.isArray(r[n[1]])){let c=r[n[1]];r[n[1]]=[...hs,...Array.isArray(c)?c:[c],o]}else r[n[1]]=o}return{comments:s,pragmas:r}}var ki=["noformat","noprettier"],Ti=["format","prettier"];function cs(e){if(!e.startsWith("#!"))return"";let t=e.indexOf(`-`);return t===-1?e:e.slice(0,t)}var Ai=cs;function wi(e){let t=Ai(e);t&&(e=e.slice(t.length+1));let i=_i(e),{pragmas:r,comments:s}=Ei(i);return{shebang:t,text:e,pragmas:r,comments:s}}function Ii(e){let{pragmas:t}=wi(e);return Ti.some(i=>at(t,i))}function Pi(e){let{pragmas:t}=wi(e);return ki.some(i=>at(t,i))}function ps(e){return e=typeof e=="function"?{parse:e}:e,{astFormat:"estree",hasPragma:Ii,hasIgnorePragma:Pi,locStart:w,locEnd:I,...e}}var Re=ps;var Ve="module",Ni="commonjs",Oe=[Ve,Ni];function De(e){if(typeof e=="string"){if(e=e.toLowerCase(),/\.(?:mjs|mts)$/i.test(e))return Ve;if(/\.(?:cjs|cts)$/i.test(e))return Ni}}var ls={ecmaVersion:"latest",allowReserved:!0,allowReturnOutsideFunction:!0,allowSuperOutsideMethod:!0,checkPrivateFields:!1,locations:!1,ranges:!0,preserveParens:!0};function fs(e){let{message:t,loc:i}=e;if(!i)return e;let{line:r,column:s}=i;return Ae(t.replace(/ \(\d+:\d+\)$/,""),{loc:{start:{line:r,column:s+1}},cause:e})}var Li,ds=()=>(Li??(Li=T.extend((0,Ri.default)())),Li);function ms(e,t){let i=ds(),r=[],s=i.parse(e,{...ls,sourceType:t,allowImportExportEverywhere:t===Ve,onComment:r});return s.comments=r,s}function xs(e,t){let i=De(t?.filepath),r=(i?[i]:Oe).map(n=>()=>ms(e,n)),s;try{s=we(r)}catch({errors:[n]}){throw fs(n)}return Le(s,{text:e})}var ys=Re(xs);var ht={};Be(ht,{espree:()=>As});var Di=lt(et(),1);var Vi=[3,5,6,7,8,9,10,11,12,13,14,15,16,17],gs=Pe(0,Vi,-1);function vs(){return gs}function bs(e=5){let t=e==="latest"?vs():e;if(typeof t!="number")throw new Error(`ecmaVersion must be a number or "latest". Received value of type ${typeof e} instead.`);if(t>=2015&&(t-=2009),!Vi.includes(t))throw new Error("Invalid ecmaVersion.");return t}function Ss(e="script"){if(e==="script"||e==="module"||e==="commonjs")return e;throw new Error("Invalid sourceType.")}function Oi(e){let t=bs(e.ecmaVersion),i=Ss(e.sourceType),r=e.range===!0,s=e.loc===!0;if(t!==3&&e.allowReserved)throw new Error("`allowReserved` is only supported when ecmaVersion is 3");if(typeof e.allowReserved<"u"&&typeof e.allowReserved!="boolean")throw new Error("`allowReserved`, when present, must be `true` or `false`");let n=t===3?e.allowReserved||"never":!1,o=e.ecmaFeatures||{},c=e.sourceType==="commonjs"||!!o.globalReturn;if(i==="module"&&t<6)throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");return Object.assign({},e,{ecmaVersion:t,sourceType:i,ranges:r,locations:s,allowReserved:n,allowReturnOutsideFunction:c})}var $=Symbol("espree's internal state"),ot=Symbol("espree's esprimaFinishNode");function Cs(e,t,i,r,s,n,o){let c;e?c="Block":o.slice(i,i+2)==="#!"?c="Hashbang":c="Line";let h={type:c,value:t};return typeof i=="number"&&(h.start=i,h.end=r,h.range=[i,r]),typeof s=="object"&&(h.loc={start:s,end:n}),h}var ut=()=>e=>{let t=Object.assign({},e.acorn.tokTypes);return e.acornJsx&&Object.assign(t,e.acornJsx.tokTypes),class extends e{constructor(r,s){(typeof r!="object"||r===null)&&(r={}),typeof s!="string"&&!(s instanceof String)&&(s=String(s));let n=r.sourceType,o=Oi(r),c=o.ecmaFeatures||{},h=null,l={originalSourceType:n||o.sourceType,tokens:h?[]:null,comments:o.comment===!0?[]:null,impliedStrict:c.impliedStrict===!0&&o.ecmaVersion>=5,ecmaVersion:o.ecmaVersion,jsxAttrValueToken:!1,lastToken:null,templateElements:[]};super({ecmaVersion:o.ecmaVersion,sourceType:o.sourceType,ranges:o.ranges,locations:o.locations,allowReserved:o.allowReserved,allowReturnOutsideFunction:o.allowReturnOutsideFunction,onToken(m){h&&h.onToken(m,l),m.type!==t.eof&&(l.lastToken=m)},onComment(m,S,k,p,x,y){if(l.comments){let v=Cs(m,S,k,p,x,y,s);l.comments.push(v)}}},s),this[$]=l}tokenize(){do this.next();while(this.type!==t.eof);this.next();let r=this[$],s=r.tokens;return r.comments&&(s.comments=r.comments),s}finishNode(r,s){let n=super.finishNode(r,s);return this[ot](n)}finishNodeAt(r,s,n,o){let c=super.finishNodeAt(r,s,n,o);return this[ot](c)}parse(){let r=this[$],n=super.parse();return n.sourceType=r.originalSourceType,r.comments&&(n.comments=r.comments),r.tokens&&(n.tokens=r.tokens),this[$].templateElements.forEach(o=>{let h=o.tail?1:2;o.start+=-1,o.end+=h,o.range&&(o.range[0]+=-1,o.range[1]+=h),o.loc&&(o.loc.start.column+=-1,o.loc.end.column+=h)}),n}parseTopLevel(r){return this[$].impliedStrict&&(this.strict=!0),super.parseTopLevel(r)}raise(r,s){let n=e.acorn.getLineInfo(this.input,r),o=new SyntaxError(s);throw o.index=r,o.lineNumber=n.line,o.column=n.column+1,o}raiseRecoverable(r,s){this.raise(r,s)}unexpected(r){let s="Unexpected token";if(r!=null){if(this.pos=r,this.options.locations)for(;this.pos<this.lineStart;)this.lineStart=this.input.lastIndexOf(`-`,this.lineStart-2)+1,--this.curLine;this.nextToken()}this.end>this.start&&(s+=` ${this.input.slice(this.start,this.end)}`),this.raise(this.start,s)}jsx_readString(r){let s=super.jsx_readString(r);return this.type===t.string&&(this[$].jsxAttrValueToken=!0),s}[ot](r){return r.type==="TemplateElement"&&this[$].templateElements.push(r),r.type.includes("Function")&&!("generator"in r)&&(r.generator=!1),r}}};var _s={_regular:null,_jsx:null,get regular(){if(this._regular===null){let e=ut();this._regular=T.extend(e)}return this._regular},get jsx(){if(this._jsx===null){let e=ut(),t=(0,Di.default)();this._jsx=T.extend(t,e)}return this._jsx},get(e){return!!(e&&e.ecmaFeatures&&e.ecmaFeatures.jsx)?this.jsx:this.regular}};function Mi(e,t){let i=_s.get(t);return new i(t,e).parse()}var Es={ecmaVersion:"latest",range:!0,loc:!1,comment:!0,tokens:!1,ecmaFeatures:{jsx:!0,impliedStrict:!1}};function ks(e){let{message:t,lineNumber:i,column:r}=e;return typeof i!="number"?e:Ae(t,{loc:{start:{line:i,column:r}},cause:e})}function Ts(e,t){let i=De(t?.filepath),r=(i?[i]:Oe).map(n=>()=>Mi(e,{...Es,sourceType:n})),s;try{s=we(r)}catch({errors:[n]}){throw ks(n)}return Le(s,{text:e,astType:"espree"})}var As=Re(Ts);var ws={...nt,...ht};return Wi(Is);});+`);e=e.replace(Si,"").trimEnd();let r=Object.create(null),s=Z(0,e,Ci,"").replace(Si,"").trimEnd(),n;for(;n=Ci.exec(e);){let o=Z(0,n[2],ns,"");if(typeof r[n[1]]=="string"||Array.isArray(r[n[1]])){let h=r[n[1]];r[n[1]]=[...hs,...Array.isArray(h)?h:[h],o]}else r[n[1]]=o}return{comments:s,pragmas:r}}var ki=["noformat","noprettier"],Ai=["format","prettier"];function cs(e){if(!e.startsWith("#!"))return"";let t=e.indexOf(`+`);return t===-1?e:e.slice(0,t)}var Ti=cs;function wi(e){let t=Ti(e);t&&(e=e.slice(t.length+1));let i=_i(e),{pragmas:r,comments:s}=Ei(i);return{shebang:t,text:e,pragmas:r,comments:s}}function Ii(e){let{pragmas:t}=wi(e);return Ai.some(i=>at(t,i))}function Pi(e){let{pragmas:t}=wi(e);return ki.some(i=>at(t,i))}function ps(e){return e=typeof e=="function"?{parse:e}:e,{astFormat:"estree",hasPragma:Ii,hasIgnorePragma:Pi,locStart:w,locEnd:I,...e}}var Re=ps;var Ve="module",Ni="commonjs",Oe=[Ve,Ni];function De(e){if(typeof e=="string"){if(e=e.toLowerCase(),/\.(?:mjs|mts)$/i.test(e))return Ve;if(/\.(?:cjs|cts)$/i.test(e))return Ni}}var ls={ecmaVersion:"latest",allowReserved:!0,allowReturnOutsideFunction:!0,allowSuperOutsideMethod:!0,checkPrivateFields:!1,locations:!1,ranges:!0,preserveParens:!0};function fs(e){let{message:t,loc:i}=e;if(!i)return e;let{line:r,column:s}=i;return Te(t.replace(/ \(\d+:\d+\)$/,""),{loc:{start:{line:r,column:s+1}},cause:e})}var Li,ds=()=>(Li??(Li=A.extend((0,Ri.default)())),Li);function ms(e,t){let i=ds(),r=[],s=i.parse(e,{...ls,sourceType:t,allowImportExportEverywhere:t===Ve,onComment:r});return s.comments=r,s}function xs(e,t){let i=De(t?.filepath),r=(i?[i]:Oe).map(n=>()=>ms(e,n)),s;try{s=we(r)}catch({errors:[n]}){throw fs(n)}return Le(s,{text:e})}var ys=Re(xs);var ht={};Be(ht,{espree:()=>Ts});var Di=lt(et(),1);var Vi=[3,5,6,7,8,9,10,11,12,13,14,15,16,17],gs=Pe(0,Vi,-1);function vs(){return gs}function bs(e=5){let t=e==="latest"?vs():e;if(typeof t!="number")throw new Error(`ecmaVersion must be a number or "latest". Received value of type ${typeof e} instead.`);if(t>=2015&&(t-=2009),!Vi.includes(t))throw new Error("Invalid ecmaVersion.");return t}function Ss(e="script"){if(e==="script"||e==="module"||e==="commonjs")return e;throw new Error("Invalid sourceType.")}function Oi(e){let t=bs(e.ecmaVersion),i=Ss(e.sourceType),r=e.range===!0,s=e.loc===!0;if(t!==3&&e.allowReserved)throw new Error("`allowReserved` is only supported when ecmaVersion is 3");if(typeof e.allowReserved<"u"&&typeof e.allowReserved!="boolean")throw new Error("`allowReserved`, when present, must be `true` or `false`");let n=t===3?e.allowReserved||"never":!1,o=e.ecmaFeatures||{},h=e.sourceType==="commonjs"||!!o.globalReturn;if(i==="module"&&t<6)throw new Error("sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options.");return Object.assign({},e,{ecmaVersion:t,sourceType:i,ranges:r,locations:s,allowReserved:n,allowReturnOutsideFunction:h})}var $=Symbol("espree's internal state"),ot=Symbol("espree's esprimaFinishNode");function Cs(e,t,i,r,s,n,o){let h;e?h="Block":o.slice(i,i+2)==="#!"?h="Hashbang":h="Line";let c={type:h,value:t};return typeof i=="number"&&(c.start=i,c.end=r,c.range=[i,r]),typeof s=="object"&&(c.loc={start:s,end:n}),c}var ut=()=>e=>{let t=Object.assign({},e.acorn.tokTypes);return e.acornJsx&&Object.assign(t,e.acornJsx.tokTypes),class extends e{constructor(r,s){(typeof r!="object"||r===null)&&(r={}),typeof s!="string"&&!(s instanceof String)&&(s=String(s));let n=r.sourceType,o=Oi(r),h=o.ecmaFeatures||{},c=null,l={originalSourceType:n||o.sourceType,tokens:c?[]:null,comments:o.comment===!0?[]:null,impliedStrict:h.impliedStrict===!0&&o.ecmaVersion>=5,ecmaVersion:o.ecmaVersion,jsxAttrValueToken:!1,lastToken:null,templateElements:[]};super({ecmaVersion:o.ecmaVersion,sourceType:o.sourceType,ranges:o.ranges,locations:o.locations,allowReserved:o.allowReserved,allowReturnOutsideFunction:o.allowReturnOutsideFunction,onToken(m){c&&c.onToken(m,l),m.type!==t.eof&&(l.lastToken=m)},onComment(m,S,E,p,x,y){if(l.comments){let v=Cs(m,S,E,p,x,y,s);l.comments.push(v)}}},s),this[$]=l}tokenize(){do this.next();while(this.type!==t.eof);this.next();let r=this[$],s=r.tokens;return r.comments&&(s.comments=r.comments),s}finishNode(r,s){let n=super.finishNode(r,s);return this[ot](n)}finishNodeAt(r,s,n,o){let h=super.finishNodeAt(r,s,n,o);return this[ot](h)}parse(){let r=this[$],n=super.parse();return n.sourceType=r.originalSourceType,r.comments&&(n.comments=r.comments),r.tokens&&(n.tokens=r.tokens),this[$].templateElements.forEach(o=>{let c=o.tail?1:2;o.start+=-1,o.end+=c,o.range&&(o.range[0]+=-1,o.range[1]+=c),o.loc&&(o.loc.start.column+=-1,o.loc.end.column+=c)}),n}parseTopLevel(r){return this[$].impliedStrict&&(this.strict=!0),super.parseTopLevel(r)}raise(r,s){let n=e.acorn.getLineInfo(this.input,r),o=new SyntaxError(s);throw o.index=r,o.lineNumber=n.line,o.column=n.column+1,o}raiseRecoverable(r,s){this.raise(r,s)}unexpected(r){let s="Unexpected token";if(r!=null){if(this.pos=r,this.options.locations)for(;this.pos<this.lineStart;)this.lineStart=this.input.lastIndexOf(`+`,this.lineStart-2)+1,--this.curLine;this.nextToken()}this.end>this.start&&(s+=` ${this.input.slice(this.start,this.end)}`),this.raise(this.start,s)}jsx_readString(r){let s=super.jsx_readString(r);return this.type===t.string&&(this[$].jsxAttrValueToken=!0),s}[ot](r){return r.type==="TemplateElement"&&this[$].templateElements.push(r),r.type.includes("Function")&&!("generator"in r)&&(r.generator=!1),r}}};var _s={_regular:null,_jsx:null,get regular(){if(this._regular===null){let e=ut();this._regular=A.extend(e)}return this._regular},get jsx(){if(this._jsx===null){let e=ut(),t=(0,Di.default)();this._jsx=A.extend(t,e)}return this._jsx},get(e){return!!(e&&e.ecmaFeatures&&e.ecmaFeatures.jsx)?this.jsx:this.regular}};function Mi(e,t){let i=_s.get(t);return new i(t,e).parse()}var Es={ecmaVersion:"latest",range:!0,loc:!1,comment:!0,tokens:!1,ecmaFeatures:{jsx:!0,impliedStrict:!1}};function ks(e){let{message:t,lineNumber:i,column:r}=e;return typeof i!="number"?e:Te(t,{loc:{start:{line:i,column:r}},cause:e})}function As(e,t){let i=De(t?.filepath),r=(i?[i]:Oe).map(n=>()=>Mi(e,{...Es,sourceType:n})),s;try{s=we(r)}catch({errors:[n]}){throw ks(n)}return Le(s,{text:e,astType:"espree"})}var Ts=Re(As);var ws={...nt,...ht};return Wi(Is);});
react npm
19.2.8 1mo ago nominal
critical-tier BURST ×11
latest 19.2.8 versions 2914 maintainers 2 critical-tier (snapshotted)
19.2.5
19.1.6
19.0.5
19.2.6
19.1.7
19.0.6
19.0.7
19.1.8
19.2.7
19.2.8
19.1.9
19.0.8
BURST
2 releases in 37m: 0.2.0, 0.2.1
info · registry-verified · 2012-01-10 · 14y ago
BURST
2 releases in 40m: 0.14.4, 0.14.5
info · registry-verified · 2015-12-29 · 10y ago
BURST
3 releases in 26m: 0.14.10, 15.7.0, 16.14.0
info · registry-verified · 2020-10-14 · 5y ago
BURST
3 releases in 5m: 19.2.1, 19.1.2, 19.0.1
info · registry-verified · 2025-12-03 · 8mo ago
BURST
3 releases in 3m: 19.2.2, 19.1.3, 19.0.2
info · registry-verified · 2025-12-11 · 8mo ago
BURST
3 releases in 1m: 19.2.3, 19.1.4, 19.0.3
info · registry-verified · 2025-12-11 · 8mo ago
BURST
3 releases in 2m: 19.2.4, 19.1.5, 19.0.4
info · registry-verified · 2026-01-26 · 6mo ago
BURST
3 releases in 1m: 19.2.5, 19.1.6, 19.0.5
info · registry-verified · 2026-04-08 · 4mo ago
BURST
3 releases in 1m: 19.2.6, 19.1.7, 19.0.6
info · registry-verified · 2026-05-06 · 3mo ago
BURST
3 releases in 4m: 19.0.7, 19.1.8, 19.2.7
info · registry-verified · 2026-06-01 · 2mo ago
BURST
3 releases in 2m: 19.2.8, 19.1.9, 19.0.8 · ACTIVE
info · registry-verified · 2026-07-21 · 1mo ago
release diff 19.1.9 → 19.0.8
+0 added · -0 removed · ~9 modified
cjs/react-jsx-dev-runtime.development.js +421 lines
--- +++ @@ -16,3 +16,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -23,2 +23,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -31,4 +33,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -42,4 +42,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -98,16 +96,251 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternals.H;+      ReactSharedInternals.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(+                        " at new ",+                        " at "+                      );+                    fn.displayName &&+                      _frame.includes("<anonymous>") &&+                      (_frame = _frame.replace("<anonymous>", fn.displayName));+                    "function" === typeof fn &&+                      componentFrameCache.set(fn, _frame);+                    return _frame;+                  }+                while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter);+              }+              break;+            }+        }+      } finally {+        (reentry = !1),+          (ReactSharedInternals.H = previousDispatcher),+          reenableLogs(),+          (Error.prepareStackTrace = frame);+      }
… 328 more lines (truncated)
cjs/react-jsx-dev-runtime.react-server.development.js +423 lines
--- +++ @@ -16,3 +16,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -23,2 +23,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -31,4 +33,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -42,4 +42,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -98,16 +96,251 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternalsServer.H;+      ReactSharedInternalsServer.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(+                        " at new ",+                        " at "+                      );+                    fn.displayName &&+                      _frame.includes("<anonymous>") &&+                      (_frame = _frame.replace("<anonymous>", fn.displayName));+                    "function" === typeof fn &&+                      componentFrameCache.set(fn, _frame);+                    return _frame;+                  }+                while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter);+              }+              break;+            }+        }+      } finally {+        (reentry = !1),+          (ReactSharedInternalsServer.H = previousDispatcher),+          reenableLogs(),+          (Error.prepareStackTrace = frame);+      }
… 362 more lines (truncated)
cjs/react-jsx-runtime.development.js +422 lines
--- +++ @@ -16,3 +16,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -23,2 +23,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -31,4 +33,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -42,4 +42,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -98,16 +96,251 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternals.H;+      ReactSharedInternals.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(+                        " at new ",+                        " at "+                      );+                    fn.displayName &&+                      _frame.includes("<anonymous>") &&+                      (_frame = _frame.replace("<anonymous>", fn.displayName));+                    "function" === typeof fn &&+                      componentFrameCache.set(fn, _frame);+                    return _frame;+                  }+                while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter);+              }+              break;+            }+        }+      } finally {+        (reentry = !1),+          (ReactSharedInternals.H = previousDispatcher),+          reenableLogs(),+          (Error.prepareStackTrace = frame);+      }
… 344 more lines (truncated)
cjs/react-jsx-runtime.react-server.development.js +423 lines
--- +++ @@ -16,3 +16,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -23,2 +23,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -31,4 +33,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -42,4 +42,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -98,16 +96,251 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternalsServer.H;+      ReactSharedInternalsServer.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(+                        " at new ",+                        " at "+                      );+                    fn.displayName &&+                      _frame.includes("<anonymous>") &&+                      (_frame = _frame.replace("<anonymous>", fn.displayName));+                    "function" === typeof fn &&+                      componentFrameCache.set(fn, _frame);+                    return _frame;+                  }+                while (1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter);+              }+              break;+            }+        }+      } finally {+        (reentry = !1),+          (ReactSharedInternalsServer.H = previousDispatcher),+          reenableLogs(),+          (Error.prepareStackTrace = frame);+      }
… 362 more lines (truncated)
cjs/react.development.js +412 lines
--- +++ @@ -89,3 +89,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -96,2 +96,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -104,4 +106,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -115,4 +115,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -144,16 +142,272 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function isValidElementType(type) {+      return "string" === typeof type ||+        "function" === typeof type ||+        type === REACT_FRAGMENT_TYPE ||+        type === REACT_PROFILER_TYPE ||+        type === REACT_STRICT_MODE_TYPE ||+        type === REACT_SUSPENSE_TYPE ||+        type === REACT_SUSPENSE_LIST_TYPE ||+        type === REACT_OFFSCREEN_TYPE ||+        ("object" === typeof type &&+          null !== type &&+          (type.$$typeof === REACT_LAZY_TYPE ||+            type.$$typeof === REACT_MEMO_TYPE ||+            type.$$typeof === REACT_CONTEXT_TYPE ||+            type.$$typeof === REACT_CONSUMER_TYPE ||+            type.$$typeof === REACT_FORWARD_REF_TYPE ||+            type.$$typeof === REACT_CLIENT_REFERENCE$1 ||+            void 0 !== type.getModuleId))+        ? !0+        : !1;+    }+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternals.H;+      ReactSharedInternals.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(
… 390 more lines (truncated)
cjs/react.production.js +6 lines
--- +++ @@ -74,3 +74,3 @@ var isArrayImpl = Array.isArray,-  ReactSharedInternals = { H: null, A: null, T: null, S: null, V: null },+  ReactSharedInternals = { H: null, A: null, T: null, S: null },   hasOwnProperty = Object.prototype.hasOwnProperty;@@ -359,7 +359,4 @@   ReactSharedInternals;-exports.__COMPILER_RUNTIME = {-  __proto__: null,-  c: function (size) {-    return ReactSharedInternals.H.useMemoCache(size);-  }+exports.act = function () {+  throw Error("act(...) is not supported in production builds of React."); };@@ -496,9 +493,4 @@ };-exports.useEffect = function (create, createDeps, update) {-  var dispatcher = ReactSharedInternals.H;-  if ("function" === typeof update)-    throw Error(-      "useEffect CRUD overload is not enabled in this build of React."-    );-  return dispatcher.useEffect(create, createDeps);+exports.useEffect = function (create, deps) {+  return ReactSharedInternals.H.useEffect(create, deps); };@@ -545,2 +537,2 @@ };-exports.version = "19.1.9";+exports.version = "19.0.8";
cjs/react.react-server.development.js +406 lines
--- +++ @@ -51,3 +51,3 @@       if ("function" === typeof type)-        return type.$$typeof === REACT_CLIENT_REFERENCE+        return type.$$typeof === REACT_CLIENT_REFERENCE$2           ? null@@ -58,2 +58,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -66,4 +68,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -77,4 +77,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -106,16 +104,272 @@     }-    function getTaskName(type) {-      if (type === REACT_FRAGMENT_TYPE) return "<>";-      if (-        "object" === typeof type &&-        null !== type &&-        type.$$typeof === REACT_LAZY_TYPE-      )-        return "<...>";+    function isValidElementType(type) {+      return "string" === typeof type ||+        "function" === typeof type ||+        type === REACT_FRAGMENT_TYPE ||+        type === REACT_PROFILER_TYPE ||+        type === REACT_STRICT_MODE_TYPE ||+        type === REACT_SUSPENSE_TYPE ||+        type === REACT_SUSPENSE_LIST_TYPE ||+        type === REACT_OFFSCREEN_TYPE ||+        ("object" === typeof type &&+          null !== type &&+          (type.$$typeof === REACT_LAZY_TYPE ||+            type.$$typeof === REACT_MEMO_TYPE ||+            type.$$typeof === REACT_CONTEXT_TYPE ||+            type.$$typeof === REACT_CONSUMER_TYPE ||+            type.$$typeof === REACT_FORWARD_REF_TYPE ||+            type.$$typeof === REACT_CLIENT_REFERENCE$1 ||+            void 0 !== type.getModuleId))+        ? !0+        : !1;+    }+    function disabledLog() {}+    function disableLogs() {+      if (0 === disabledDepth) {+        prevLog = console.log;+        prevInfo = console.info;+        prevWarn = console.warn;+        prevError = console.error;+        prevGroup = console.group;+        prevGroupCollapsed = console.groupCollapsed;+        prevGroupEnd = console.groupEnd;+        var props = {+          configurable: !0,+          enumerable: !0,+          value: disabledLog,+          writable: !0+        };+        Object.defineProperties(console, {+          info: props,+          log: props,+          warn: props,+          error: props,+          group: props,+          groupCollapsed: props,+          groupEnd: props+        });+      }+      disabledDepth++;+    }+    function reenableLogs() {+      disabledDepth--;+      if (0 === disabledDepth) {+        var props = { configurable: !0, enumerable: !0, writable: !0 };+        Object.defineProperties(console, {+          log: assign({}, props, { value: prevLog }),+          info: assign({}, props, { value: prevInfo }),+          warn: assign({}, props, { value: prevWarn }),+          error: assign({}, props, { value: prevError }),+          group: assign({}, props, { value: prevGroup }),+          groupCollapsed: assign({}, props, { value: prevGroupCollapsed }),+          groupEnd: assign({}, props, { value: prevGroupEnd })+        });+      }+      0 > disabledDepth &&+        console.error(+          "disabledDepth fell below zero. This is a bug in React. Please file an issue."+        );+    }+    function describeBuiltInComponentFrame(name) {+      if (void 0 === prefix)+        try {+          throw Error();+        } catch (x) {+          var match = x.stack.trim().match(/\n( *(at )?)/);+          prefix = (match && match[1]) || "";+          suffix =+            -1 < x.stack.indexOf("\n    at")+              ? " (<anonymous>)"+              : -1 < x.stack.indexOf("@")+                ? "@unknown:0:0"+                : "";+        }+      return "\n" + prefix + name + suffix;+    }+    function describeNativeComponentFrame(fn, construct) {+      if (!fn || reentry) return "";+      var frame = componentFrameCache.get(fn);+      if (void 0 !== frame) return frame;+      reentry = !0;+      frame = Error.prepareStackTrace;+      Error.prepareStackTrace = void 0;+      var previousDispatcher = null;+      previousDispatcher = ReactSharedInternals.H;+      ReactSharedInternals.H = null;+      disableLogs();       try {-        var name = getComponentNameFromType(type);-        return name ? "<" + name + ">" : "<...>";-      } catch (x) {-        return "<...>";-      }+        var RunInRootFrame = {+          DetermineComponentFrameRoot: function () {+            try {+              if (construct) {+                var Fake = function () {+                  throw Error();+                };+                Object.defineProperty(Fake.prototype, "props", {+                  set: function () {+                    throw Error();+                  }+                });+                if ("object" === typeof Reflect && Reflect.construct) {+                  try {+                    Reflect.construct(Fake, []);+                  } catch (x) {+                    var control = x;+                  }+                  Reflect.construct(fn, [], Fake);+                } else {+                  try {+                    Fake.call();+                  } catch (x$0) {+                    control = x$0;+                  }+                  fn.call(Fake.prototype);+                }+              } else {+                try {+                  throw Error();+                } catch (x$1) {+                  control = x$1;+                }+                (Fake = fn()) &&+                  "function" === typeof Fake.catch &&+                  Fake.catch(function () {});+              }+            } catch (sample) {+              if (sample && control && "string" === typeof sample.stack)+                return [sample.stack, control.stack];+            }+            return [null, null];+          }+        };+        RunInRootFrame.DetermineComponentFrameRoot.displayName =+          "DetermineComponentFrameRoot";+        var namePropDescriptor = Object.getOwnPropertyDescriptor(+          RunInRootFrame.DetermineComponentFrameRoot,+          "name"+        );+        namePropDescriptor &&+          namePropDescriptor.configurable &&+          Object.defineProperty(+            RunInRootFrame.DetermineComponentFrameRoot,+            "name",+            { value: "DetermineComponentFrameRoot" }+          );+        var _RunInRootFrame$Deter =+            RunInRootFrame.DetermineComponentFrameRoot(),+          sampleStack = _RunInRootFrame$Deter[0],+          controlStack = _RunInRootFrame$Deter[1];+        if (sampleStack && controlStack) {+          var sampleLines = sampleStack.split("\n"),+            controlLines = controlStack.split("\n");+          for (+            _RunInRootFrame$Deter = namePropDescriptor = 0;+            namePropDescriptor < sampleLines.length &&+            !sampleLines[namePropDescriptor].includes(+              "DetermineComponentFrameRoot"+            );++          )+            namePropDescriptor++;+          for (+            ;+            _RunInRootFrame$Deter < controlLines.length &&+            !controlLines[_RunInRootFrame$Deter].includes(+              "DetermineComponentFrameRoot"+            );++          )+            _RunInRootFrame$Deter++;+          if (+            namePropDescriptor === sampleLines.length ||+            _RunInRootFrame$Deter === controlLines.length+          )+            for (+              namePropDescriptor = sampleLines.length - 1,+                _RunInRootFrame$Deter = controlLines.length - 1;+              1 <= namePropDescriptor &&+              0 <= _RunInRootFrame$Deter &&+              sampleLines[namePropDescriptor] !==+                controlLines[_RunInRootFrame$Deter];++            )+              _RunInRootFrame$Deter--;+          for (+            ;+            1 <= namePropDescriptor && 0 <= _RunInRootFrame$Deter;+            namePropDescriptor--, _RunInRootFrame$Deter--+          )+            if (+              sampleLines[namePropDescriptor] !==+              controlLines[_RunInRootFrame$Deter]+            ) {+              if (1 !== namePropDescriptor || 1 !== _RunInRootFrame$Deter) {+                do+                  if (+                    (namePropDescriptor--,+                    _RunInRootFrame$Deter--,+                    0 > _RunInRootFrame$Deter ||+                      sampleLines[namePropDescriptor] !==+                        controlLines[_RunInRootFrame$Deter])+                  ) {+                    var _frame =+                      "\n" ++                      sampleLines[namePropDescriptor].replace(
… 338 more lines (truncated)
cjs/react.react-server.production.js +1 lines
--- +++ @@ -342,5 +342,2 @@ };-exports.captureOwnerStack = function () {-  return null;-}; exports.cloneElement = function (element, config, children) {@@ -428,2 +425,2 @@ };-exports.version = "19.1.9";+exports.version = "19.0.8";
package.json +1 lines
--- +++ @@ -6,3 +6,3 @@   ],-  "version": "19.1.9",+  "version": "19.0.8",   "homepage": "https://react.dev/",
react-dom npm
19.2.8 1mo ago nominal
critical-tier BURST ×11
latest 19.2.8 versions 2869 maintainers 2 critical-tier (snapshotted)
19.2.5
19.1.6
19.0.5
19.2.6
19.1.7
19.0.6
19.0.7
19.1.8
19.2.7
19.2.8
19.1.9
19.0.8
BURST
2 releases in 40m: 0.14.4, 0.14.5
info · registry-verified · 2015-12-29 · 10y ago
BURST
5 releases in 14m: 16.0.1, 16.1.2, 16.2.1, 16.3.3, 16.4.2
info · registry-verified · 2018-08-01 · 8y ago
BURST
3 releases in 25m: 0.14.10, 15.7.0, 16.14.0
info · registry-verified · 2020-10-14 · 5y ago
BURST
3 releases in 5m: 19.2.1, 19.1.2, 19.0.1
info · registry-verified · 2025-12-03 · 8mo ago
BURST
3 releases in 3m: 19.2.2, 19.1.3, 19.0.2
info · registry-verified · 2025-12-11 · 8mo ago
BURST
3 releases in 1m: 19.2.3, 19.1.4, 19.0.3
info · registry-verified · 2025-12-11 · 8mo ago
BURST
3 releases in 2m: 19.2.4, 19.1.5, 19.0.4
info · registry-verified · 2026-01-26 · 6mo ago
BURST
3 releases in 1m: 19.2.5, 19.1.6, 19.0.5
info · registry-verified · 2026-04-08 · 4mo ago
BURST
3 releases in 1m: 19.2.6, 19.1.7, 19.0.6
info · registry-verified · 2026-05-06 · 3mo ago
BURST
3 releases in 4m: 19.0.7, 19.1.8, 19.2.7
info · registry-verified · 2026-06-01 · 2mo ago
BURST
3 releases in 2m: 19.2.8, 19.1.9, 19.0.8 · ACTIVE
info · registry-verified · 2026-07-21 · 1mo ago
release diff 19.1.9 → 19.0.8
+0 added · -0 removed · ~21 modified
cjs/react-dom-client.development.js +7700 lines
--- +++ @@ -75,3 +75,5 @@     }-    function warnForMissingKey() {}+    function createFiber(tag, pendingProps, key, mode) {+      return new FiberNode(tag, pendingProps, key, mode);+    }     function warnInvalidHookAccess() {@@ -87,2 +89,3 @@     function noop$2() {}+    function warnForMissingKey() {}     function setToSortedString(set) {@@ -94,9 +97,5 @@     }-    function createFiber(tag, pendingProps, key, mode) {-      return new FiberNode(tag, pendingProps, key, mode);-    }     function scheduleRoot(root, element) {       root.context === emptyContextObject &&-        (updateContainerImpl(root.current, 2, element, root, null, null),-        flushSyncWork$1());+        (updateContainerSync(element, root, null, null), flushSyncWork$1());     }@@ -106,3 +105,3 @@         update = update.updatedFamilies;-        flushPendingEffects();+        flushPassiveEffects();         scheduleFibersWithFamiliesRecursively(@@ -123,116 +122,2 @@       );-    }-    function getNearestMountedFiber(fiber) {-      var node = fiber,-        nearestMounted = fiber;-      if (fiber.alternate) for (; node.return; ) node = node.return;-      else {-        fiber = node;-        do-          (node = fiber),-            0 !== (node.flags & 4098) && (nearestMounted = node.return),-            (fiber = node.return);-        while (fiber);-      }-      return 3 === node.tag ? nearestMounted : null;-    }-    function getSuspenseInstanceFromFiber(fiber) {-      if (13 === fiber.tag) {-        var suspenseState = fiber.memoizedState;-        null === suspenseState &&-          ((fiber = fiber.alternate),-          null !== fiber && (suspenseState = fiber.memoizedState));-        if (null !== suspenseState) return suspenseState.dehydrated;-      }-      return null;-    }-    function assertIsMounted(fiber) {-      if (getNearestMountedFiber(fiber) !== fiber)-        throw Error("Unable to find node on an unmounted component.");-    }-    function findCurrentFiberUsingSlowPath(fiber) {-      var alternate = fiber.alternate;-      if (!alternate) {-        alternate = getNearestMountedFiber(fiber);-        if (null === alternate)-          throw Error("Unable to find node on an unmounted component.");-        return alternate !== fiber ? null : fiber;-      }-      for (var a = fiber, b = alternate; ; ) {-        var parentA = a.return;-        if (null === parentA) break;-        var parentB = parentA.alternate;-        if (null === parentB) {-          b = parentA.return;-          if (null !== b) {-            a = b;-            continue;-          }-          break;-        }-        if (parentA.child === parentB.child) {-          for (parentB = parentA.child; parentB; ) {-            if (parentB === a) return assertIsMounted(parentA), fiber;-            if (parentB === b) return assertIsMounted(parentA), alternate;-            parentB = parentB.sibling;-          }-          throw Error("Unable to find node on an unmounted component.");-        }-        if (a.return !== b.return) (a = parentA), (b = parentB);-        else {-          for (var didFindChild = !1, _child = parentA.child; _child; ) {-            if (_child === a) {-              didFindChild = !0;-              a = parentA;-              b = parentB;-              break;-            }-            if (_child === b) {-              didFindChild = !0;-              b = parentA;-              a = parentB;-              break;-            }-            _child = _child.sibling;-          }-          if (!didFindChild) {-            for (_child = parentB.child; _child; ) {-              if (_child === a) {-                didFindChild = !0;-                a = parentB;-                b = parentA;-                break;-              }-              if (_child === b) {-                didFindChild = !0;-                b = parentB;-                a = parentA;-                break;-              }-              _child = _child.sibling;-            }-            if (!didFindChild)-              throw Error(-                "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."-              );-          }-        }-        if (a.alternate !== b)-          throw Error(-            "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."-          );-      }-      if (3 !== a.tag)-        throw Error("Unable to find node on an unmounted component.");-      return a.stateNode.current === a ? fiber : alternate;-    }-    function findCurrentHostFiberImpl(node) {-      var tag = node.tag;-      if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;-      for (node = node.child; null !== node; ) {-        tag = findCurrentHostFiberImpl(node);-        if (null !== tag) return tag;-        node = node.sibling;-      }-      return null;     }@@ -256,2 +141,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -264,4 +151,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -275,4 +160,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -314,4 +197,2 @@       switch (fiber.tag) {-        case 31:-          return "Activity";         case 24:@@ -376,777 +257,2 @@       return null;-    }-    function createCursor(defaultValue) {-      return { current: defaultValue };-    }-    function pop(cursor, fiber) {-      0 > index$jscomp$0-        ? console.error("Unexpected pop.")-        : (fiber !== fiberStack[index$jscomp$0] &&-            console.error("Unexpected Fiber popped."),-          (cursor.current = valueStack[index$jscomp$0]),-          (valueStack[index$jscomp$0] = null),-          (fiberStack[index$jscomp$0] = null),-          index$jscomp$0--);-    }-    function push(cursor, value, fiber) {-      index$jscomp$0++;-      valueStack[index$jscomp$0] = cursor.current;-      fiberStack[index$jscomp$0] = fiber;-      cursor.current = value;-    }-    function requiredContext(c) {-      null === c &&-        console.error(-          "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."-        );-      return c;-    }-    function pushHostContainer(fiber, nextRootInstance) {-      push(rootInstanceStackCursor, nextRootInstance, fiber);-      push(contextFiberStackCursor, fiber, fiber);-      push(contextStackCursor, null, fiber);-      var nextRootContext = nextRootInstance.nodeType;-      switch (nextRootContext) {-        case 9:-        case 11:-          nextRootContext = 9 === nextRootContext ? "#document" : "#fragment";-          nextRootInstance = (nextRootInstance =-            nextRootInstance.documentElement)-            ? (nextRootInstance = nextRootInstance.namespaceURI)-              ? getOwnHostContext(nextRootInstance)-              : HostContextNamespaceNone-            : HostContextNamespaceNone;-          break;-        default:-          if (-            ((nextRootContext = nextRootInstance.tagName),-            (nextRootInstance = nextRootInstance.namespaceURI))-          )-            (nextRootInstance = getOwnHostContext(nextRootInstance)),-              (nextRootInstance = getChildHostContextProd(-                nextRootInstance,-                nextRootContext-              ));-          else-            switch (nextRootContext) {-              case "svg":-                nextRootInstance = HostContextNamespaceSvg;-                break;-              case "math":-                nextRootInstance = HostContextNamespaceMath;-                break;-              default:-                nextRootInstance = HostContextNamespaceNone;-            }-      }-      nextRootContext = nextRootContext.toLowerCase();-      nextRootContext = updatedAncestorInfoDev(null, nextRootContext);-      nextRootContext = {-        context: nextRootInstance,-        ancestorInfo: nextRootContext-      };-      pop(contextStackCursor, fiber);-      push(contextStackCursor, nextRootContext, fiber);-    }-    function popHostContainer(fiber) {-      pop(contextStackCursor, fiber);-      pop(contextFiberStackCursor, fiber);-      pop(rootInstanceStackCursor, fiber);-    }-    function getHostContext() {-      return requiredContext(contextStackCursor.current);-    }
… 16555 more lines (truncated)
cjs/react-dom-client.production.js +5524 lines
--- +++ @@ -38,110 +38,3 @@ }-function getNearestMountedFiber(fiber) {-  var node = fiber,-    nearestMounted = fiber;-  if (fiber.alternate) for (; node.return; ) node = node.return;-  else {-    fiber = node;-    do-      (node = fiber),-        0 !== (node.flags & 4098) && (nearestMounted = node.return),-        (fiber = node.return);-    while (fiber);-  }-  return 3 === node.tag ? nearestMounted : null;-}-function getSuspenseInstanceFromFiber(fiber) {-  if (13 === fiber.tag) {-    var suspenseState = fiber.memoizedState;-    null === suspenseState &&-      ((fiber = fiber.alternate),-      null !== fiber && (suspenseState = fiber.memoizedState));-    if (null !== suspenseState) return suspenseState.dehydrated;-  }-  return null;-}-function assertIsMounted(fiber) {-  if (getNearestMountedFiber(fiber) !== fiber)-    throw Error(formatProdErrorMessage(188));-}-function findCurrentFiberUsingSlowPath(fiber) {-  var alternate = fiber.alternate;-  if (!alternate) {-    alternate = getNearestMountedFiber(fiber);-    if (null === alternate) throw Error(formatProdErrorMessage(188));-    return alternate !== fiber ? null : fiber;-  }-  for (var a = fiber, b = alternate; ; ) {-    var parentA = a.return;-    if (null === parentA) break;-    var parentB = parentA.alternate;-    if (null === parentB) {-      b = parentA.return;-      if (null !== b) {-        a = b;-        continue;-      }-      break;-    }-    if (parentA.child === parentB.child) {-      for (parentB = parentA.child; parentB; ) {-        if (parentB === a) return assertIsMounted(parentA), fiber;-        if (parentB === b) return assertIsMounted(parentA), alternate;-        parentB = parentB.sibling;-      }-      throw Error(formatProdErrorMessage(188));-    }-    if (a.return !== b.return) (a = parentA), (b = parentB);-    else {-      for (var didFindChild = !1, child$0 = parentA.child; child$0; ) {-        if (child$0 === a) {-          didFindChild = !0;-          a = parentA;-          b = parentB;-          break;-        }-        if (child$0 === b) {-          didFindChild = !0;-          b = parentA;-          a = parentB;-          break;-        }-        child$0 = child$0.sibling;-      }-      if (!didFindChild) {-        for (child$0 = parentB.child; child$0; ) {-          if (child$0 === a) {-            didFindChild = !0;-            a = parentB;-            b = parentA;-            break;-          }-          if (child$0 === b) {-            didFindChild = !0;-            b = parentB;-            a = parentA;-            break;-          }-          child$0 = child$0.sibling;-        }-        if (!didFindChild) throw Error(formatProdErrorMessage(189));-      }-    }-    if (a.alternate !== b) throw Error(formatProdErrorMessage(190));-  }-  if (3 !== a.tag) throw Error(formatProdErrorMessage(188));-  return a.stateNode.current === a ? fiber : alternate;-}-function findCurrentHostFiberImpl(node) {-  var tag = node.tag;-  if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;-  for (node = node.child; null !== node; ) {-    tag = findCurrentHostFiberImpl(node);-    if (null !== tag) return tag;-    node = node.sibling;-  }-  return null;-}-var assign = Object.assign,-  REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"),+var REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"),   REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),@@ -160,8 +53,8 @@ Symbol.for("react.scope");-var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");+Symbol.for("react.debug_trace_mode");+var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); Symbol.for("react.legacy_hidden"); Symbol.for("react.tracing_marker");-var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");-Symbol.for("react.view_transition");-var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;+var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),+  MAYBE_ITERATOR_SYMBOL = Symbol.iterator; function getIteratorFn(maybeIterable) {@@ -184,2 +77,4 @@       return "Fragment";+    case REACT_PORTAL_TYPE:+      return "Portal";     case REACT_PROFILER_TYPE:@@ -192,4 +87,2 @@       return "SuspenseList";-    case REACT_ACTIVITY_TYPE:-      return "Activity";   }@@ -197,4 +90,2 @@     switch (type.$$typeof) {-      case REACT_PORTAL_TYPE:-        return "Portal";       case REACT_CONTEXT_TYPE:@@ -226,568 +117,7 @@ }-var isArrayImpl = Array.isArray,-  ReactSharedInternals =+var ReactSharedInternals =     React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,-  ReactDOMSharedInternals =-    ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,-  sharedNotPendingObject = {-    pending: !1,-    data: null,-    method: null,-    action: null-  },-  valueStack = [],-  index = -1;-function createCursor(defaultValue) {-  return { current: defaultValue };-}-function pop(cursor) {-  0 > index ||-    ((cursor.current = valueStack[index]), (valueStack[index] = null), index--);-}-function push(cursor, value) {-  index++;-  valueStack[index] = cursor.current;-  cursor.current = value;-}-var contextStackCursor = createCursor(null),-  contextFiberStackCursor = createCursor(null),-  rootInstanceStackCursor = createCursor(null),-  hostTransitionProviderCursor = createCursor(null);-function pushHostContainer(fiber, nextRootInstance) {-  push(rootInstanceStackCursor, nextRootInstance);-  push(contextFiberStackCursor, fiber);-  push(contextStackCursor, null);-  switch (nextRootInstance.nodeType) {-    case 9:-    case 11:-      fiber = (fiber = nextRootInstance.documentElement)-        ? (fiber = fiber.namespaceURI)-          ? getOwnHostContext(fiber)-          : 0-        : 0;-      break;-    default:-      if (-        ((fiber = nextRootInstance.tagName),-        (nextRootInstance = nextRootInstance.namespaceURI))-      )-        (nextRootInstance = getOwnHostContext(nextRootInstance)),-          (fiber = getChildHostContextProd(nextRootInstance, fiber));-      else-        switch (fiber) {-          case "svg":-            fiber = 1;-            break;-          case "math":-            fiber = 2;-            break;-          default:-            fiber = 0;-        }-  }-  pop(contextStackCursor);-  push(contextStackCursor, fiber);-}-function popHostContainer() {-  pop(contextStackCursor);-  pop(contextFiberStackCursor);-  pop(rootInstanceStackCursor);-}-function pushHostContext(fiber) {-  null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber);-  var context = contextStackCursor.current;-  var JSCompiler_inline_result = getChildHostContextProd(context, fiber.type);-  context !== JSCompiler_inline_result &&-    (push(contextFiberStackCursor, fiber),-    push(contextStackCursor, JSCompiler_inline_result));-}-function popHostContext(fiber) {-  contextFiberStackCursor.current === fiber &&-    (pop(contextStackCursor), pop(contextFiberStackCursor));-  hostTransitionProviderCursor.current === fiber &&-    (pop(hostTransitionProviderCursor),-    (HostTransitionContext._currentValue = sharedNotPendingObject));-}-var hasOwnProperty = Object.prototype.hasOwnProperty,-  scheduleCallback$3 = Scheduler.unstable_scheduleCallback,-  cancelCallback$1 = Scheduler.unstable_cancelCallback,-  shouldYield = Scheduler.unstable_shouldYield,-  requestPaint = Scheduler.unstable_requestPaint,-  now = Scheduler.unstable_now,-  getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,-  ImmediatePriority = Scheduler.unstable_ImmediatePriority,-  UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,-  NormalPriority$1 = Scheduler.unstable_NormalPriority,-  LowPriority = Scheduler.unstable_LowPriority,-  IdlePriority = Scheduler.unstable_IdlePriority,-  log$1 = Scheduler.log,-  unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue,-  rendererID = null,-  injectedHook = null;-function setIsStrictModeForDevtools(newIsStrictMode) {-  "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode);-  if (injectedHook && "function" === typeof injectedHook.setStrictMode)-    try {-      injectedHook.setStrictMode(rendererID, newIsStrictMode);
… 11729 more lines (truncated)
cjs/react-dom-profiling.development.js +7708 lines
--- +++ @@ -75,3 +75,5 @@     }-    function warnForMissingKey() {}+    function createFiber(tag, pendingProps, key, mode) {+      return new FiberNode(tag, pendingProps, key, mode);+    }     function warnInvalidHookAccess() {@@ -87,2 +89,3 @@     function noop$3() {}+    function warnForMissingKey() {}     function setToSortedString(set) {@@ -94,9 +97,5 @@     }-    function createFiber(tag, pendingProps, key, mode) {-      return new FiberNode(tag, pendingProps, key, mode);-    }     function scheduleRoot(root, element) {       root.context === emptyContextObject &&-        (updateContainerImpl(root.current, 2, element, root, null, null),-        flushSyncWork$1());+        (updateContainerSync(element, root, null, null), flushSyncWork$1());     }@@ -106,3 +105,3 @@         update = update.updatedFamilies;-        flushPendingEffects();+        flushPassiveEffects();         scheduleFibersWithFamiliesRecursively(@@ -123,116 +122,2 @@       );-    }-    function getNearestMountedFiber(fiber) {-      var node = fiber,-        nearestMounted = fiber;-      if (fiber.alternate) for (; node.return; ) node = node.return;-      else {-        fiber = node;-        do-          (node = fiber),-            0 !== (node.flags & 4098) && (nearestMounted = node.return),-            (fiber = node.return);-        while (fiber);-      }-      return 3 === node.tag ? nearestMounted : null;-    }-    function getSuspenseInstanceFromFiber(fiber) {-      if (13 === fiber.tag) {-        var suspenseState = fiber.memoizedState;-        null === suspenseState &&-          ((fiber = fiber.alternate),-          null !== fiber && (suspenseState = fiber.memoizedState));-        if (null !== suspenseState) return suspenseState.dehydrated;-      }-      return null;-    }-    function assertIsMounted(fiber) {-      if (getNearestMountedFiber(fiber) !== fiber)-        throw Error("Unable to find node on an unmounted component.");-    }-    function findCurrentFiberUsingSlowPath(fiber) {-      var alternate = fiber.alternate;-      if (!alternate) {-        alternate = getNearestMountedFiber(fiber);-        if (null === alternate)-          throw Error("Unable to find node on an unmounted component.");-        return alternate !== fiber ? null : fiber;-      }-      for (var a = fiber, b = alternate; ; ) {-        var parentA = a.return;-        if (null === parentA) break;-        var parentB = parentA.alternate;-        if (null === parentB) {-          b = parentA.return;-          if (null !== b) {-            a = b;-            continue;-          }-          break;-        }-        if (parentA.child === parentB.child) {-          for (parentB = parentA.child; parentB; ) {-            if (parentB === a) return assertIsMounted(parentA), fiber;-            if (parentB === b) return assertIsMounted(parentA), alternate;-            parentB = parentB.sibling;-          }-          throw Error("Unable to find node on an unmounted component.");-        }-        if (a.return !== b.return) (a = parentA), (b = parentB);-        else {-          for (var didFindChild = !1, _child = parentA.child; _child; ) {-            if (_child === a) {-              didFindChild = !0;-              a = parentA;-              b = parentB;-              break;-            }-            if (_child === b) {-              didFindChild = !0;-              b = parentA;-              a = parentB;-              break;-            }-            _child = _child.sibling;-          }-          if (!didFindChild) {-            for (_child = parentB.child; _child; ) {-              if (_child === a) {-                didFindChild = !0;-                a = parentB;-                b = parentA;-                break;-              }-              if (_child === b) {-                didFindChild = !0;-                b = parentB;-                a = parentA;-                break;-              }-              _child = _child.sibling;-            }-            if (!didFindChild)-              throw Error(-                "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."-              );-          }-        }-        if (a.alternate !== b)-          throw Error(-            "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."-          );-      }-      if (3 !== a.tag)-        throw Error("Unable to find node on an unmounted component.");-      return a.stateNode.current === a ? fiber : alternate;-    }-    function findCurrentHostFiberImpl(node) {-      var tag = node.tag;-      if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;-      for (node = node.child; null !== node; ) {-        tag = findCurrentHostFiberImpl(node);-        if (null !== tag) return tag;-        node = node.sibling;-      }-      return null;     }@@ -256,2 +141,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -264,4 +151,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -275,4 +160,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -314,4 +197,2 @@       switch (fiber.tag) {-        case 31:-          return "Activity";         case 24:@@ -376,785 +257,2 @@       return null;-    }-    function resolveDispatcher() {-      var dispatcher = ReactSharedInternals.H;-      null === dispatcher &&-        console.error(-          "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem."-        );-      return dispatcher;-    }-    function createCursor(defaultValue) {-      return { current: defaultValue };-    }-    function pop(cursor, fiber) {-      0 > index$jscomp$0-        ? console.error("Unexpected pop.")-        : (fiber !== fiberStack[index$jscomp$0] &&-            console.error("Unexpected Fiber popped."),-          (cursor.current = valueStack[index$jscomp$0]),-          (valueStack[index$jscomp$0] = null),-          (fiberStack[index$jscomp$0] = null),-          index$jscomp$0--);-    }-    function push(cursor, value, fiber) {-      index$jscomp$0++;-      valueStack[index$jscomp$0] = cursor.current;-      fiberStack[index$jscomp$0] = fiber;-      cursor.current = value;-    }-    function requiredContext(c) {-      null === c &&-        console.error(-          "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."-        );-      return c;-    }-    function pushHostContainer(fiber, nextRootInstance) {-      push(rootInstanceStackCursor, nextRootInstance, fiber);-      push(contextFiberStackCursor, fiber, fiber);-      push(contextStackCursor, null, fiber);-      var nextRootContext = nextRootInstance.nodeType;-      switch (nextRootContext) {-        case 9:-        case 11:-          nextRootContext = 9 === nextRootContext ? "#document" : "#fragment";-          nextRootInstance = (nextRootInstance =-            nextRootInstance.documentElement)-            ? (nextRootInstance = nextRootInstance.namespaceURI)-              ? getOwnHostContext(nextRootInstance)-              : HostContextNamespaceNone-            : HostContextNamespaceNone;-          break;-        default:-          if (-            ((nextRootContext = nextRootInstance.tagName),-            (nextRootInstance = nextRootInstance.namespaceURI))-          )-            (nextRootInstance = getOwnHostContext(nextRootInstance)),-              (nextRootInstance = getChildHostContextProd(-                nextRootInstance,-                nextRootContext-              ));-          else-            switch (nextRootContext) {-              case "svg":-                nextRootInstance = HostContextNamespaceSvg;-                break;-              case "math":-                nextRootInstance = HostContextNamespaceMath;-                break;-              default:-                nextRootInstance = HostContextNamespaceNone;-            }-      }-      nextRootContext = nextRootContext.toLowerCase();-      nextRootContext = updatedAncestorInfoDev(null, nextRootContext);-      nextRootContext = {-        context: nextRootInstance,-        ancestorInfo: nextRootContext-      };-      pop(contextStackCursor, fiber);-      push(contextStackCursor, nextRootContext, fiber);-    }
… 16571 more lines (truncated)
cjs/react-dom-profiling.profiling.js +5990 lines
--- +++ @@ -42,110 +42,3 @@ }-function getNearestMountedFiber(fiber) {-  var node = fiber,-    nearestMounted = fiber;-  if (fiber.alternate) for (; node.return; ) node = node.return;-  else {-    fiber = node;-    do-      (node = fiber),-        0 !== (node.flags & 4098) && (nearestMounted = node.return),-        (fiber = node.return);-    while (fiber);-  }-  return 3 === node.tag ? nearestMounted : null;-}-function getSuspenseInstanceFromFiber(fiber) {-  if (13 === fiber.tag) {-    var suspenseState = fiber.memoizedState;-    null === suspenseState &&-      ((fiber = fiber.alternate),-      null !== fiber && (suspenseState = fiber.memoizedState));-    if (null !== suspenseState) return suspenseState.dehydrated;-  }-  return null;-}-function assertIsMounted(fiber) {-  if (getNearestMountedFiber(fiber) !== fiber)-    throw Error(formatProdErrorMessage(188));-}-function findCurrentFiberUsingSlowPath(fiber) {-  var alternate = fiber.alternate;-  if (!alternate) {-    alternate = getNearestMountedFiber(fiber);-    if (null === alternate) throw Error(formatProdErrorMessage(188));-    return alternate !== fiber ? null : fiber;-  }-  for (var a = fiber, b = alternate; ; ) {-    var parentA = a.return;-    if (null === parentA) break;-    var parentB = parentA.alternate;-    if (null === parentB) {-      b = parentA.return;-      if (null !== b) {-        a = b;-        continue;-      }-      break;-    }-    if (parentA.child === parentB.child) {-      for (parentB = parentA.child; parentB; ) {-        if (parentB === a) return assertIsMounted(parentA), fiber;-        if (parentB === b) return assertIsMounted(parentA), alternate;-        parentB = parentB.sibling;-      }-      throw Error(formatProdErrorMessage(188));-    }-    if (a.return !== b.return) (a = parentA), (b = parentB);-    else {-      for (var didFindChild = !1, child$0 = parentA.child; child$0; ) {-        if (child$0 === a) {-          didFindChild = !0;-          a = parentA;-          b = parentB;-          break;-        }-        if (child$0 === b) {-          didFindChild = !0;-          b = parentA;-          a = parentB;-          break;-        }-        child$0 = child$0.sibling;-      }-      if (!didFindChild) {-        for (child$0 = parentB.child; child$0; ) {-          if (child$0 === a) {-            didFindChild = !0;-            a = parentB;-            b = parentA;-            break;-          }-          if (child$0 === b) {-            didFindChild = !0;-            b = parentB;-            a = parentA;-            break;-          }-          child$0 = child$0.sibling;-        }-        if (!didFindChild) throw Error(formatProdErrorMessage(189));-      }-    }-    if (a.alternate !== b) throw Error(formatProdErrorMessage(190));-  }-  if (3 !== a.tag) throw Error(formatProdErrorMessage(188));-  return a.stateNode.current === a ? fiber : alternate;-}-function findCurrentHostFiberImpl(node) {-  var tag = node.tag;-  if (5 === tag || 26 === tag || 27 === tag || 6 === tag) return node;-  for (node = node.child; null !== node; ) {-    tag = findCurrentHostFiberImpl(node);-    if (null !== tag) return tag;-    node = node.sibling;-  }-  return null;-}-var assign = Object.assign,-  REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"),+var REACT_LEGACY_ELEMENT_TYPE = Symbol.for("react.element"),   REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),@@ -164,8 +57,8 @@ Symbol.for("react.scope");-var REACT_ACTIVITY_TYPE = Symbol.for("react.activity");+Symbol.for("react.debug_trace_mode");+var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); Symbol.for("react.legacy_hidden"); Symbol.for("react.tracing_marker");-var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");-Symbol.for("react.view_transition");-var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;+var REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),+  MAYBE_ITERATOR_SYMBOL = Symbol.iterator; function getIteratorFn(maybeIterable) {@@ -188,2 +81,4 @@       return "Fragment";+    case REACT_PORTAL_TYPE:+      return "Portal";     case REACT_PROFILER_TYPE:@@ -196,4 +91,2 @@       return "SuspenseList";-    case REACT_ACTIVITY_TYPE:-      return "Activity";   }@@ -201,4 +94,2 @@     switch (type.$$typeof) {-      case REACT_PORTAL_TYPE:-        return "Portal";       case REACT_CONTEXT_TYPE:@@ -230,646 +121,7 @@ }-var isArrayImpl = Array.isArray,-  ReactSharedInternals =+var ReactSharedInternals =     React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,-  ReactDOMSharedInternals =-    ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,-  sharedNotPendingObject = {-    pending: !1,-    data: null,-    method: null,-    action: null-  },-  valueStack = [],-  index = -1;-function createCursor(defaultValue) {-  return { current: defaultValue };-}-function pop(cursor) {-  0 > index ||-    ((cursor.current = valueStack[index]), (valueStack[index] = null), index--);-}-function push(cursor, value) {-  index++;-  valueStack[index] = cursor.current;-  cursor.current = value;-}-var contextStackCursor = createCursor(null),-  contextFiberStackCursor = createCursor(null),-  rootInstanceStackCursor = createCursor(null),-  hostTransitionProviderCursor = createCursor(null);-function pushHostContainer(fiber, nextRootInstance) {-  push(rootInstanceStackCursor, nextRootInstance);-  push(contextFiberStackCursor, fiber);-  push(contextStackCursor, null);-  switch (nextRootInstance.nodeType) {-    case 9:-    case 11:-      fiber = (fiber = nextRootInstance.documentElement)-        ? (fiber = fiber.namespaceURI)-          ? getOwnHostContext(fiber)-          : 0-        : 0;-      break;-    default:-      if (-        ((fiber = nextRootInstance.tagName),-        (nextRootInstance = nextRootInstance.namespaceURI))-      )-        (nextRootInstance = getOwnHostContext(nextRootInstance)),-          (fiber = getChildHostContextProd(nextRootInstance, fiber));-      else-        switch (fiber) {-          case "svg":-            fiber = 1;-            break;-          case "math":-            fiber = 2;-            break;-          default:-            fiber = 0;-        }-  }-  pop(contextStackCursor);-  push(contextStackCursor, fiber);-}-function popHostContainer() {-  pop(contextStackCursor);-  pop(contextFiberStackCursor);-  pop(rootInstanceStackCursor);-}-function pushHostContext(fiber) {-  null !== fiber.memoizedState && push(hostTransitionProviderCursor, fiber);-  var context = contextStackCursor.current;-  var JSCompiler_inline_result = getChildHostContextProd(context, fiber.type);-  context !== JSCompiler_inline_result &&-    (push(contextFiberStackCursor, fiber),-    push(contextStackCursor, JSCompiler_inline_result));-}-function popHostContext(fiber) {-  contextFiberStackCursor.current === fiber &&-    (pop(contextStackCursor), pop(contextFiberStackCursor));-  hostTransitionProviderCursor.current === fiber &&-    (pop(hostTransitionProviderCursor),-    (HostTransitionContext._currentValue = sharedNotPendingObject));-}-var hasOwnProperty = Object.prototype.hasOwnProperty,-  scheduleCallback$3 = Scheduler.unstable_scheduleCallback,-  cancelCallback$1 = Scheduler.unstable_cancelCallback,-  shouldYield = Scheduler.unstable_shouldYield,-  requestPaint = Scheduler.unstable_requestPaint,-  now$1 = Scheduler.unstable_now,-  getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel,-  ImmediatePriority = Scheduler.unstable_ImmediatePriority,-  UserBlockingPriority = Scheduler.unstable_UserBlockingPriority,-  NormalPriority$1 = Scheduler.unstable_NormalPriority,-  LowPriority = Scheduler.unstable_LowPriority,-  IdlePriority = Scheduler.unstable_IdlePriority,-  log$1 = Scheduler.log,-  unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue,-  rendererID = null,-  injectedHook = null,-  injectedProfilingHooks = null,-  isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__;-function setIsStrictModeForDevtools(newIsStrictMode) {-  "function" === typeof log$1 && unstable_setDisableYieldValue(newIsStrictMode);-  if (injectedHook && "function" === typeof injectedHook.setStrictMode)
… 12683 more lines (truncated)
cjs/react-dom-server-legacy.browser.development.js +521 lines
--- +++ @@ -760,10 +760,2 @@     }-    function createPreambleState() {-      return {-        htmlChunks: null,-        headChunks: null,-        bodyChunks: null,-        contribution: NoContribution-      };-    }     function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -827,22 +819,12 @@           );-        case "head":-          if (parentContext.insertionMode < HTML_MODE)-            return createFormatContext(-              HTML_HEAD_MODE,-              null,-              parentContext.tagScope-            );-          break;-        case "html":-          if (parentContext.insertionMode === ROOT_HTML_MODE)-            return createFormatContext(-              HTML_HTML_MODE,-              null,-              parentContext.tagScope-            );       }-      return parentContext.insertionMode >= HTML_TABLE_MODE ||-        parentContext.insertionMode < HTML_MODE+      return parentContext.insertionMode >= HTML_TABLE_MODE         ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-        : parentContext;+        : parentContext.insertionMode === ROOT_HTML_MODE+          ? "html" === type+            ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+            : createFormatContext(HTML_MODE, null, parentContext.tagScope)+          : parentContext.insertionMode === HTML_HTML_MODE+            ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+            : parentContext;     }@@ -1474,25 +1456,2 @@     }-    function pushStartSingletonElement(target, props, tag) {-      target.push(startChunkForTag(tag));-      var innerHTML = (tag = null),-        propKey;-      for (propKey in props)-        if (hasOwnProperty.call(props, propKey)) {-          var propValue = props[propKey];-          if (null != propValue)-            switch (propKey) {-              case "children":-                tag = propValue;-                break;-              case "dangerouslySetInnerHTML":-                innerHTML = propValue;-                break;-              default:-                pushAttribute(target, propKey, propValue);-            }-        }-      target.push(endOfStartTag);-      pushInnerHTML(target, innerHTML, tag);-      return tag;-    }     function pushStartGenericElement(target, props, tag) {@@ -1537,3 +1496,2 @@       renderState,-      preambleState,       hoistableState,@@ -2173,3 +2131,3 @@               ? console.error(-                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",                   children$jscomp$6.length@@ -2632,3 +2590,2 @@               0 < headers.remainingCapacity &&-              "string" !== typeof props.srcSet &&               ("high" === props.fetchPriority ||@@ -2693,9 +2650,9 @@         case "head":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble = preambleState || renderState.preamble;-            if (preamble.headChunks)-              throw Error("The `<head>` tag may only be rendered once.");-            preamble.headChunks = [];-            var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-              preamble.headChunks,+          if (+            formatContext.insertionMode < HTML_MODE &&+            null === renderState.headChunks+          ) {+            renderState.headChunks = [];+            var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+              renderState.headChunks,               props,@@ -2710,12 +2667,12 @@           return JSCompiler_inline_result$jscomp$9;-        case "body":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble$jscomp$0 = preambleState || renderState.preamble;-            if (preamble$jscomp$0.bodyChunks)-              throw Error("The `<body>` tag may only be rendered once.");-            preamble$jscomp$0.bodyChunks = [];-            var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-              preamble$jscomp$0.bodyChunks,+        case "html":+          if (+            formatContext.insertionMode === ROOT_HTML_MODE &&+            null === renderState.htmlChunks+          ) {+            renderState.htmlChunks = [doctypeChunk];+            var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+              renderState.htmlChunks,               props,-              "body"+              "html"             );@@ -2725,23 +2682,5 @@               props,-              "body"+              "html"             );           return JSCompiler_inline_result$jscomp$10;-        case "html":-          if (formatContext.insertionMode === ROOT_HTML_MODE) {-            var preamble$jscomp$1 = preambleState || renderState.preamble;-            if (preamble$jscomp$1.htmlChunks)-              throw Error("The `<html>` tag may only be rendered once.");-            preamble$jscomp$1.htmlChunks = [doctypeChunk];-            var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-              preamble$jscomp$1.htmlChunks,-              props,-              "html"-            );-          } else-            JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-              target$jscomp$0,-              props,-              "html"-            );-          return JSCompiler_inline_result$jscomp$11;         default:@@ -2812,17 +2751,2 @@     }-    function hoistPreambleState(renderState, preambleState) {-      renderState = renderState.preamble;-      null === renderState.htmlChunks &&-        preambleState.htmlChunks &&-        ((renderState.htmlChunks = preambleState.htmlChunks),-        (preambleState.contribution |= 1));-      null === renderState.headChunks &&-        preambleState.headChunks &&-        ((renderState.headChunks = preambleState.headChunks),-        (preambleState.contribution |= 4));-      null === renderState.bodyChunks &&-        preambleState.bodyChunks &&-        ((renderState.bodyChunks = preambleState.bodyChunks),-        (preambleState.contribution |= 2));-    }     function writeBootstrap(destination, renderState) {@@ -2846,9 +2770,2 @@     }-    function writePreambleContribution(destination, preambleState) {-      preambleState = preambleState.contribution;-      preambleState !== NoContribution &&-        (destination.push(boundaryPreambleContributionChunkStart),-        destination.push("" + preambleState),-        destination.push(boundaryPreambleContributionChunkEnd));-    }     function writeStartSegment(destination, renderState, formatContext, id) {@@ -2857,3 +2774,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -2922,3 +2838,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3316,3 +3231,4 @@         startInlineScript: "<script>",-        preamble: createPreambleState(),+        htmlChunks: null,+        headChunks: null,         externalRuntimeScript: null,@@ -3446,3 +3362,4 @@         startInlineScript: idPrefix.startInlineScript,-        preamble: idPrefix.preamble,+        htmlChunks: idPrefix.htmlChunks,+        headChunks: idPrefix.headChunks,         externalRuntimeScript: idPrefix.externalRuntimeScript,@@ -3497,2 +3414,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -3505,4 +3424,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -3516,4 +3433,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -4188,23 +4103,2 @@     }-    function formatOwnerStack(error) {-      var prevPrepareStackTrace = Error.prepareStackTrace;-      Error.prepareStackTrace = void 0;-      error = error.stack;-      Error.prepareStackTrace = prevPrepareStackTrace;-      error.startsWith("Error: react-stack-top-frame\n") &&-        (error = error.slice(29));-      prevPrepareStackTrace = error.indexOf("\n");-      -1 !== prevPrepareStackTrace &&-        (error = error.slice(prevPrepareStackTrace + 1));-      prevPrepareStackTrace = error.indexOf("react_stack_bottom_frame");-      -1 !== prevPrepareStackTrace &&-        (prevPrepareStackTrace = error.lastIndexOf(-          "\n",-          prevPrepareStackTrace-        ));-      if (-1 !== prevPrepareStackTrace)-        error = error.slice(0, prevPrepareStackTrace);-      else return "";-      return error;-    }     function describeComponentStackByType(type) {@@ -4213,3 +4107,3 @@         return type.prototype && type.prototype.isReactComponent-          ? describeNativeComponentFrame(type, !0)+          ? ((type = describeNativeComponentFrame(type, !0)), type)           : describeNativeComponentFrame(type, !1);@@ -4248,2 +4142,14 @@     }+    function getStackByComponentStackNode(componentStack) {+      try {+        var info = "";+        do+          (info += describeComponentStackByType(componentStack.type)),+            (componentStack = componentStack.parent);+        while (componentStack);+        return info;+      } catch (x) {
… 1719 more lines (truncated)
cjs/react-dom-server-legacy.browser.production.js +256 lines
--- +++ @@ -66,6 +66,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -331,10 +331,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -357,3 +349,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -361,3 +353,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -365,3 +357,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -369,18 +361,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -792,25 +783,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(">");-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -858,3 +826,2 @@   renderState,-  preambleState,   hoistableState,@@ -1329,3 +1296,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1348,3 +1315,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1430,3 +1397,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1471,3 +1438,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1574,3 +1541,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1688,3 +1655,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -1748,9 +1714,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error(formatProdErrorMessage(545, "`<head>`"));-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -1765,12 +1728,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error(formatProdErrorMessage(545, "`<body>`"));-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = [""];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -1780,23 +1743,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error(formatProdErrorMessage(545, "`<html>`"));-        preamble$jscomp$1.htmlChunks = [""];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,-          "html"-        );-      return JSCompiler_inline_result$jscomp$11;     default:@@ -1861,17 +1806,2 @@ }-function hoistPreambleState(renderState, preambleState) {-  renderState = renderState.preamble;-  null === renderState.htmlChunks &&-    preambleState.htmlChunks &&-    ((renderState.htmlChunks = preambleState.htmlChunks),-    (preambleState.contribution |= 1));-  null === renderState.headChunks &&-    preambleState.headChunks &&-    ((renderState.headChunks = preambleState.headChunks),-    (preambleState.contribution |= 4));-  null === renderState.bodyChunks &&-    preambleState.bodyChunks &&-    ((renderState.bodyChunks = preambleState.bodyChunks),-    (preambleState.contribution |= 2));-} function writeBootstrap(destination, renderState) {@@ -1892,9 +1822,2 @@ }-function writePreambleContribution(destination, preambleState) {-  preambleState = preambleState.contribution;-  0 !== preambleState &&-    (destination.push("\x3c!--"),-    destination.push("" + preambleState),-    destination.push("--\x3e"));-} function writeStartSegment(destination, renderState, formatContext, id) {@@ -1903,3 +1826,2 @@     case 1:-    case 3:     case 2:@@ -1912,3 +1834,3 @@       );-    case 4:+    case 3:       return (@@ -1920,3 +1842,3 @@       );-    case 5:+    case 4:       return (@@ -1928,3 +1850,3 @@       );-    case 6:+    case 5:       return (@@ -1936,3 +1858,3 @@       );-    case 7:+    case 6:       return (@@ -1944,3 +1866,3 @@       );-    case 8:+    case 7:       return (@@ -1952,3 +1874,3 @@       );-    case 9:+    case 8:       return (
… 825 more lines (truncated)
cjs/react-dom-server-legacy.node.development.js +521 lines
--- +++ @@ -760,10 +760,2 @@     }-    function createPreambleState() {-      return {-        htmlChunks: null,-        headChunks: null,-        bodyChunks: null,-        contribution: NoContribution-      };-    }     function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -827,22 +819,12 @@           );-        case "head":-          if (parentContext.insertionMode < HTML_MODE)-            return createFormatContext(-              HTML_HEAD_MODE,-              null,-              parentContext.tagScope-            );-          break;-        case "html":-          if (parentContext.insertionMode === ROOT_HTML_MODE)-            return createFormatContext(-              HTML_HTML_MODE,-              null,-              parentContext.tagScope-            );       }-      return parentContext.insertionMode >= HTML_TABLE_MODE ||-        parentContext.insertionMode < HTML_MODE+      return parentContext.insertionMode >= HTML_TABLE_MODE         ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-        : parentContext;+        : parentContext.insertionMode === ROOT_HTML_MODE+          ? "html" === type+            ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+            : createFormatContext(HTML_MODE, null, parentContext.tagScope)+          : parentContext.insertionMode === HTML_HTML_MODE+            ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+            : parentContext;     }@@ -1474,25 +1456,2 @@     }-    function pushStartSingletonElement(target, props, tag) {-      target.push(startChunkForTag(tag));-      var innerHTML = (tag = null),-        propKey;-      for (propKey in props)-        if (hasOwnProperty.call(props, propKey)) {-          var propValue = props[propKey];-          if (null != propValue)-            switch (propKey) {-              case "children":-                tag = propValue;-                break;-              case "dangerouslySetInnerHTML":-                innerHTML = propValue;-                break;-              default:-                pushAttribute(target, propKey, propValue);-            }-        }-      target.push(endOfStartTag);-      pushInnerHTML(target, innerHTML, tag);-      return tag;-    }     function pushStartGenericElement(target, props, tag) {@@ -1537,3 +1496,2 @@       renderState,-      preambleState,       hoistableState,@@ -2173,3 +2131,3 @@               ? console.error(-                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",                   children$jscomp$6.length@@ -2632,3 +2590,2 @@               0 < headers.remainingCapacity &&-              "string" !== typeof props.srcSet &&               ("high" === props.fetchPriority ||@@ -2693,9 +2650,9 @@         case "head":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble = preambleState || renderState.preamble;-            if (preamble.headChunks)-              throw Error("The `<head>` tag may only be rendered once.");-            preamble.headChunks = [];-            var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-              preamble.headChunks,+          if (+            formatContext.insertionMode < HTML_MODE &&+            null === renderState.headChunks+          ) {+            renderState.headChunks = [];+            var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+              renderState.headChunks,               props,@@ -2710,12 +2667,12 @@           return JSCompiler_inline_result$jscomp$9;-        case "body":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble$jscomp$0 = preambleState || renderState.preamble;-            if (preamble$jscomp$0.bodyChunks)-              throw Error("The `<body>` tag may only be rendered once.");-            preamble$jscomp$0.bodyChunks = [];-            var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-              preamble$jscomp$0.bodyChunks,+        case "html":+          if (+            formatContext.insertionMode === ROOT_HTML_MODE &&+            null === renderState.htmlChunks+          ) {+            renderState.htmlChunks = [doctypeChunk];+            var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+              renderState.htmlChunks,               props,-              "body"+              "html"             );@@ -2725,23 +2682,5 @@               props,-              "body"+              "html"             );           return JSCompiler_inline_result$jscomp$10;-        case "html":-          if (formatContext.insertionMode === ROOT_HTML_MODE) {-            var preamble$jscomp$1 = preambleState || renderState.preamble;-            if (preamble$jscomp$1.htmlChunks)-              throw Error("The `<html>` tag may only be rendered once.");-            preamble$jscomp$1.htmlChunks = [doctypeChunk];-            var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-              preamble$jscomp$1.htmlChunks,-              props,-              "html"-            );-          } else-            JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-              target$jscomp$0,-              props,-              "html"-            );-          return JSCompiler_inline_result$jscomp$11;         default:@@ -2812,17 +2751,2 @@     }-    function hoistPreambleState(renderState, preambleState) {-      renderState = renderState.preamble;-      null === renderState.htmlChunks &&-        preambleState.htmlChunks &&-        ((renderState.htmlChunks = preambleState.htmlChunks),-        (preambleState.contribution |= 1));-      null === renderState.headChunks &&-        preambleState.headChunks &&-        ((renderState.headChunks = preambleState.headChunks),-        (preambleState.contribution |= 4));-      null === renderState.bodyChunks &&-        preambleState.bodyChunks &&-        ((renderState.bodyChunks = preambleState.bodyChunks),-        (preambleState.contribution |= 2));-    }     function writeBootstrap(destination, renderState) {@@ -2846,9 +2770,2 @@     }-    function writePreambleContribution(destination, preambleState) {-      preambleState = preambleState.contribution;-      preambleState !== NoContribution &&-        (destination.push(boundaryPreambleContributionChunkStart),-        destination.push("" + preambleState),-        destination.push(boundaryPreambleContributionChunkEnd));-    }     function writeStartSegment(destination, renderState, formatContext, id) {@@ -2857,3 +2774,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -2922,3 +2838,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3316,3 +3231,4 @@         startInlineScript: "<script>",-        preamble: createPreambleState(),+        htmlChunks: null,+        headChunks: null,         externalRuntimeScript: null,@@ -3446,3 +3362,4 @@         startInlineScript: idPrefix.startInlineScript,-        preamble: idPrefix.preamble,+        htmlChunks: idPrefix.htmlChunks,+        headChunks: idPrefix.headChunks,         externalRuntimeScript: idPrefix.externalRuntimeScript,@@ -3497,2 +3414,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -3505,4 +3424,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -3516,4 +3433,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -4188,23 +4103,2 @@     }-    function formatOwnerStack(error) {-      var prevPrepareStackTrace = Error.prepareStackTrace;-      Error.prepareStackTrace = void 0;-      error = error.stack;-      Error.prepareStackTrace = prevPrepareStackTrace;-      error.startsWith("Error: react-stack-top-frame\n") &&-        (error = error.slice(29));-      prevPrepareStackTrace = error.indexOf("\n");-      -1 !== prevPrepareStackTrace &&-        (error = error.slice(prevPrepareStackTrace + 1));-      prevPrepareStackTrace = error.indexOf("react_stack_bottom_frame");-      -1 !== prevPrepareStackTrace &&-        (prevPrepareStackTrace = error.lastIndexOf(-          "\n",-          prevPrepareStackTrace-        ));-      if (-1 !== prevPrepareStackTrace)-        error = error.slice(0, prevPrepareStackTrace);-      else return "";-      return error;-    }     function describeComponentStackByType(type) {@@ -4213,3 +4107,3 @@         return type.prototype && type.prototype.isReactComponent-          ? describeNativeComponentFrame(type, !0)+          ? ((type = describeNativeComponentFrame(type, !0)), type)           : describeNativeComponentFrame(type, !1);@@ -4248,2 +4142,14 @@     }+    function getStackByComponentStackNode(componentStack) {+      try {+        var info = "";+        do+          (info += describeComponentStackByType(componentStack.type)),+            (componentStack = componentStack.parent);+        while (componentStack);+        return info;+      } catch (x) {
… 1719 more lines (truncated)
cjs/react-dom-server-legacy.node.production.js +263 lines
--- +++ @@ -51,6 +51,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -316,10 +316,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -342,3 +334,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -346,3 +338,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -350,3 +342,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -354,18 +346,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -793,25 +784,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(">");-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -858,3 +826,2 @@   renderState,-  preambleState,   hoistableState,@@ -1338,3 +1305,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1357,3 +1324,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1439,3 +1406,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1480,3 +1447,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1583,3 +1550,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1702,3 +1669,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -1762,9 +1728,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error("The `<head>` tag may only be rendered once.");-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -1779,12 +1742,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error("The `<body>` tag may only be rendered once.");-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = [""];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -1794,23 +1757,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error("The `<html>` tag may only be rendered once.");-        preamble$jscomp$1.htmlChunks = [""];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,-          "html"-        );-      return JSCompiler_inline_result$jscomp$11;     default:@@ -1875,17 +1820,2 @@ }-function hoistPreambleState(renderState, preambleState) {-  renderState = renderState.preamble;-  null === renderState.htmlChunks &&-    preambleState.htmlChunks &&-    ((renderState.htmlChunks = preambleState.htmlChunks),-    (preambleState.contribution |= 1));-  null === renderState.headChunks &&-    preambleState.headChunks &&-    ((renderState.headChunks = preambleState.headChunks),-    (preambleState.contribution |= 4));-  null === renderState.bodyChunks &&-    preambleState.bodyChunks &&-    ((renderState.bodyChunks = preambleState.bodyChunks),-    (preambleState.contribution |= 2));-} function writeBootstrap(destination, renderState) {@@ -1909,9 +1839,2 @@ }-function writePreambleContribution(destination, preambleState) {-  preambleState = preambleState.contribution;-  0 !== preambleState &&-    (destination.push("\x3c!--"),-    destination.push("" + preambleState),-    destination.push("--\x3e"));-} function writeStartSegment(destination, renderState, formatContext, id) {@@ -1920,3 +1843,2 @@     case 1:-    case 3:     case 2:@@ -1929,3 +1851,3 @@       );-    case 4:+    case 3:       return (@@ -1937,3 +1859,3 @@       );-    case 5:+    case 4:       return (@@ -1945,3 +1867,3 @@       );-    case 6:+    case 5:       return (@@ -1953,3 +1875,3 @@       );-    case 7:+    case 6:       return (@@ -1961,3 +1883,3 @@       );-    case 8:+    case 7:       return (@@ -1969,3 +1891,3 @@       );-    case 9:+    case 8:       return (
… 844 more lines (truncated)
cjs/react-dom-server.browser.development.js +527 lines
--- +++ @@ -856,3 +856,4 @@         startInlineScript: inlineScriptWithNonce,-        preamble: createPreambleState(),+        htmlChunks: null,+        headChunks: null,         externalRuntimeScript: null,@@ -1022,10 +1023,2 @@     }-    function createPreambleState() {-      return {-        htmlChunks: null,-        headChunks: null,-        bodyChunks: null,-        contribution: NoContribution-      };-    }     function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -1100,22 +1093,12 @@           );-        case "head":-          if (parentContext.insertionMode < HTML_MODE)-            return createFormatContext(-              HTML_HEAD_MODE,-              null,-              parentContext.tagScope-            );-          break;-        case "html":-          if (parentContext.insertionMode === ROOT_HTML_MODE)-            return createFormatContext(-              HTML_HTML_MODE,-              null,-              parentContext.tagScope-            );       }-      return parentContext.insertionMode >= HTML_TABLE_MODE ||-        parentContext.insertionMode < HTML_MODE+      return parentContext.insertionMode >= HTML_TABLE_MODE         ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-        : parentContext;+        : parentContext.insertionMode === ROOT_HTML_MODE+          ? "html" === type+            ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+            : createFormatContext(HTML_MODE, null, parentContext.tagScope)+          : parentContext.insertionMode === HTML_HTML_MODE+            ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+            : parentContext;     }@@ -1770,25 +1753,2 @@     }-    function pushStartSingletonElement(target, props, tag) {-      target.push(startChunkForTag(tag));-      var innerHTML = (tag = null),-        propKey;-      for (propKey in props)-        if (hasOwnProperty.call(props, propKey)) {-          var propValue = props[propKey];-          if (null != propValue)-            switch (propKey) {-              case "children":-                tag = propValue;-                break;-              case "dangerouslySetInnerHTML":-                innerHTML = propValue;-                break;-              default:-                pushAttribute(target, propKey, propValue);-            }-        }-      target.push(endOfStartTag);-      pushInnerHTML(target, innerHTML, tag);-      return tag;-    }     function pushStartGenericElement(target, props, tag) {@@ -1833,3 +1793,2 @@       renderState,-      preambleState,       hoistableState,@@ -2477,3 +2436,3 @@               ? console.error(-                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",                   children$jscomp$6.length@@ -2942,3 +2901,2 @@               0 < headers.remainingCapacity &&-              "string" !== typeof props.srcSet &&               ("high" === props.fetchPriority ||@@ -3003,9 +2961,9 @@         case "head":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble = preambleState || renderState.preamble;-            if (preamble.headChunks)-              throw Error("The `<head>` tag may only be rendered once.");-            preamble.headChunks = [];-            var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-              preamble.headChunks,+          if (+            formatContext.insertionMode < HTML_MODE &&+            null === renderState.headChunks+          ) {+            renderState.headChunks = [];+            var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+              renderState.headChunks,               props,@@ -3020,12 +2978,12 @@           return JSCompiler_inline_result$jscomp$9;-        case "body":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble$jscomp$0 = preambleState || renderState.preamble;-            if (preamble$jscomp$0.bodyChunks)-              throw Error("The `<body>` tag may only be rendered once.");-            preamble$jscomp$0.bodyChunks = [];-            var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-              preamble$jscomp$0.bodyChunks,+        case "html":+          if (+            formatContext.insertionMode === ROOT_HTML_MODE &&+            null === renderState.htmlChunks+          ) {+            renderState.htmlChunks = [doctypeChunk];+            var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+              renderState.htmlChunks,               props,-              "body"+              "html"             );@@ -3035,23 +2993,5 @@               props,-              "body"+              "html"             );           return JSCompiler_inline_result$jscomp$10;-        case "html":-          if (formatContext.insertionMode === ROOT_HTML_MODE) {-            var preamble$jscomp$1 = preambleState || renderState.preamble;-            if (preamble$jscomp$1.htmlChunks)-              throw Error("The `<html>` tag may only be rendered once.");-            preamble$jscomp$1.htmlChunks = [doctypeChunk];-            var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-              preamble$jscomp$1.htmlChunks,-              props,-              "html"-            );-          } else-            JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-              target$jscomp$0,-              props,-              "html"-            );-          return JSCompiler_inline_result$jscomp$11;         default:@@ -3125,17 +3065,2 @@     }-    function hoistPreambleState(renderState, preambleState) {-      renderState = renderState.preamble;-      null === renderState.htmlChunks &&-        preambleState.htmlChunks &&-        ((renderState.htmlChunks = preambleState.htmlChunks),-        (preambleState.contribution |= 1));-      null === renderState.headChunks &&-        preambleState.headChunks &&-        ((renderState.headChunks = preambleState.headChunks),-        (preambleState.contribution |= 4));-      null === renderState.bodyChunks &&-        preambleState.bodyChunks &&-        ((renderState.bodyChunks = preambleState.bodyChunks),-        (preambleState.contribution |= 2));-    }     function writeBootstrap(destination, renderState) {@@ -3160,9 +3085,2 @@     }-    function writePreambleContribution(destination, preambleState) {-      preambleState = preambleState.contribution;-      preambleState !== NoContribution &&-        (writeChunk(destination, boundaryPreambleContributionChunkStart),-        writeChunk(destination, stringToChunk("" + preambleState)),-        writeChunk(destination, boundaryPreambleContributionChunkEnd));-    }     function writeStartSegment(destination, renderState, formatContext, id) {@@ -3171,3 +3089,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3229,3 +3146,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3636,2 +3552,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -3644,4 +3562,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -3655,4 +3571,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -4327,23 +4241,2 @@     }-    function formatOwnerStack(error) {-      var prevPrepareStackTrace = Error.prepareStackTrace;-      Error.prepareStackTrace = void 0;-      error = error.stack;-      Error.prepareStackTrace = prevPrepareStackTrace;-      error.startsWith("Error: react-stack-top-frame\n") &&-        (error = error.slice(29));-      prevPrepareStackTrace = error.indexOf("\n");-      -1 !== prevPrepareStackTrace &&-        (error = error.slice(prevPrepareStackTrace + 1));-      prevPrepareStackTrace = error.indexOf("react_stack_bottom_frame");-      -1 !== prevPrepareStackTrace &&-        (prevPrepareStackTrace = error.lastIndexOf(-          "\n",-          prevPrepareStackTrace-        ));-      if (-1 !== prevPrepareStackTrace)-        error = error.slice(0, prevPrepareStackTrace);-      else return "";-      return error;-    }     function describeComponentStackByType(type) {@@ -4352,3 +4245,3 @@         return type.prototype && type.prototype.isReactComponent-          ? describeNativeComponentFrame(type, !0)+          ? ((type = describeNativeComponentFrame(type, !0)), type)           : describeNativeComponentFrame(type, !1);@@ -4387,2 +4280,14 @@     }+    function getStackByComponentStackNode(componentStack) {+      try {+        var info = "";+        do+          (info += describeComponentStackByType(componentStack.type)),+            (componentStack = componentStack.parent);+        while (componentStack);+        return info;+      } catch (x) {+        return "\nError generating stack: " + x.message + "\n" + x.stack;+      }+    }     function defaultErrorHandler(error) {@@ -4443,3 +4348,3 @@       this.pendingRootTasks = this.allPendingTasks = this.nextSegmentId = 0;
… 1741 more lines (truncated)
cjs/react-dom-server.browser.production.js +248 lines
--- +++ @@ -66,6 +66,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -440,3 +440,4 @@     startInlineScript: inlineScriptWithNonce,-    preamble: createPreambleState(),+    htmlChunks: null,+    headChunks: null,     externalRuntimeScript: null,@@ -607,10 +608,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -625,5 +618,5 @@     "http://www.w3.org/2000/svg" === namespaceURI-      ? 4+      ? 3       : "http://www.w3.org/1998/Math/MathML" === namespaceURI-        ? 5+        ? 4         : 0,@@ -644,3 +637,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -648,3 +641,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -652,3 +645,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -656,18 +649,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -1181,25 +1173,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(endOfStartTag);-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -1249,3 +1218,2 @@   renderState,-  preambleState,   hoistableState,@@ -1728,3 +1696,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1747,3 +1715,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1829,3 +1797,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1870,3 +1838,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1979,3 +1947,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -2093,3 +2061,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -2153,9 +2120,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error(formatProdErrorMessage(545, "`<head>`"));-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -2170,12 +2134,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error(formatProdErrorMessage(545, "`<body>`"));-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = [doctypeChunk];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -2185,23 +2149,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error(formatProdErrorMessage(545, "`<html>`"));-        preamble$jscomp$1.htmlChunks = [doctypeChunk];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,-          "html"-        );-      return JSCompiler_inline_result$jscomp$11;     default:@@ -2268,17 +2214,2 @@ }-function hoistPreambleState(renderState, preambleState) {-  renderState = renderState.preamble;-  null === renderState.htmlChunks &&-    preambleState.htmlChunks &&-    ((renderState.htmlChunks = preambleState.htmlChunks),-    (preambleState.contribution |= 1));-  null === renderState.headChunks &&-    preambleState.headChunks &&-    ((renderState.headChunks = preambleState.headChunks),-    (preambleState.contribution |= 4));-  null === renderState.bodyChunks &&-    preambleState.bodyChunks &&-    ((renderState.bodyChunks = preambleState.bodyChunks),-    (preambleState.contribution |= 2));-} function writeBootstrap(destination, renderState) {@@ -2319,12 +2250,2 @@   return writeChunkAndReturn(destination, startPendingSuspenseBoundary2);-}-var boundaryPreambleContributionChunkStart =-    stringToPrecomputedChunk("\x3c!--"),-  boundaryPreambleContributionChunkEnd = stringToPrecomputedChunk("--\x3e");-function writePreambleContribution(destination, preambleState) {-  preambleState = preambleState.contribution;-  0 !== preambleState &&-    (writeChunk(destination, boundaryPreambleContributionChunkStart),-    writeChunk(destination, stringToChunk("" + preambleState)),-    writeChunk(destination, boundaryPreambleContributionChunkEnd)); }@@ -2361,3 +2282,2 @@     case 1:-    case 3:     case 2:@@ -2369,3 +2289,3 @@       );-    case 4:+    case 3:       return (@@ -2376,3 +2296,3 @@       );-    case 5:+    case 4:       return (@@ -2383,3 +2303,3 @@       );-    case 6:
… 812 more lines (truncated)
cjs/react-dom-server.bun.development.js +615 lines
--- +++ @@ -27,6 +27,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -1423,12 +1423,3 @@     );-  importMap = onHeaders-    ? {-        preconnects: "",-        fontPreloads: "",-        highImagePreloads: "",-        remainingCapacity:-          2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)-      }-    : null;-  onHeaders = {+  importMap = {     placeholderPrefix: idPrefix + "P:",@@ -1437,3 +1428,4 @@     startInlineScript: inlineScriptWithNonce,-    preamble: createPreambleState(),+    htmlChunks: null,+    headChunks: null,     externalRuntimeScript: null,@@ -1442,3 +1434,11 @@     onHeaders: onHeaders,-    headers: importMap,+    headers: onHeaders+      ? {+          preconnects: "",+          fontPreloads: "",+          highImagePreloads: "",+          remainingCapacity:+            2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)+        }+      : null,     resets: {@@ -1471,4 +1471,4 @@   if (void 0 !== bootstrapScripts)-    for (importMap = 0; importMap < bootstrapScripts.length; importMap++) {-      maxHeadersLength = bootstrapScripts[importMap];+    for (onHeaders = 0; onHeaders < bootstrapScripts.length; onHeaders++) {+      maxHeadersLength = bootstrapScripts[onHeaders];       bootstrapScriptContent = idPrefix = void 0;@@ -1496,3 +1496,3 @@         resumableState,-        onHeaders,+        importMap,         inlineScriptWithNonce,@@ -1524,3 +1524,3 @@     )-      (importMap = bootstrapModules[bootstrapScripts]),+      (onHeaders = bootstrapModules[bootstrapScripts]),         (idPrefix = inlineScriptWithNonce = void 0),@@ -1531,13 +1531,13 @@         }),-        "string" === typeof importMap-          ? (bootstrapScriptContent.href = maxHeadersLength = importMap)-          : ((bootstrapScriptContent.href = maxHeadersLength = importMap.src),+        "string" === typeof onHeaders+          ? (bootstrapScriptContent.href = maxHeadersLength = onHeaders)+          : ((bootstrapScriptContent.href = maxHeadersLength = onHeaders.src),             (bootstrapScriptContent.integrity = idPrefix =-              "string" === typeof importMap.integrity-                ? importMap.integrity+              "string" === typeof onHeaders.integrity+                ? onHeaders.integrity                 : void 0),             (bootstrapScriptContent.crossOrigin = inlineScriptWithNonce =-              "string" === typeof importMap || null == importMap.crossOrigin+              "string" === typeof onHeaders || null == onHeaders.crossOrigin                 ? void 0-                : "use-credentials" === importMap.crossOrigin+                : "use-credentials" === onHeaders.crossOrigin                   ? "use-credentials"@@ -1546,3 +1546,3 @@           resumableState,-          onHeaders,+          importMap,           maxHeadersLength,@@ -1567,3 +1567,3 @@         externalRuntimeConfig.push('" async="">\x3c/script>');-  return onHeaders;+  return importMap; }@@ -1596,11 +1596,2 @@ }-var NoContribution = 0;-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: NoContribution-  };-} var ROOT_HTML_MODE = 0,@@ -1608,9 +1599,8 @@   HTML_MODE = 2,-  HTML_HEAD_MODE = 3,-  SVG_MODE = 4,-  MATHML_MODE = 5,-  HTML_TABLE_MODE = 6,-  HTML_TABLE_BODY_MODE = 7,-  HTML_TABLE_ROW_MODE = 8,-  HTML_COLGROUP_MODE = 9;+  SVG_MODE = 3,+  MATHML_MODE = 4,+  HTML_TABLE_MODE = 5,+  HTML_TABLE_BODY_MODE = 6,+  HTML_TABLE_ROW_MODE = 7,+  HTML_COLGROUP_MODE = 8; function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -1673,22 +1663,12 @@       );-    case "head":-      if (parentContext.insertionMode < HTML_MODE)-        return createFormatContext(-          HTML_HEAD_MODE,-          null,-          parentContext.tagScope-        );-      break;-    case "html":-      if (parentContext.insertionMode === ROOT_HTML_MODE)-        return createFormatContext(-          HTML_HTML_MODE,-          null,-          parentContext.tagScope-        );   }-  return parentContext.insertionMode >= HTML_TABLE_MODE ||-    parentContext.insertionMode < HTML_MODE+  return parentContext.insertionMode >= HTML_TABLE_MODE     ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-    : parentContext;+    : parentContext.insertionMode === ROOT_HTML_MODE+      ? "html" === type+        ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+        : createFormatContext(HTML_MODE, null, parentContext.tagScope)+      : parentContext.insertionMode === HTML_HTML_MODE+        ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+        : parentContext; }@@ -2344,25 +2324,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(endOfStartTag);-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -2409,3 +2366,2 @@   renderState,-  preambleState,   hoistableState,@@ -3042,3 +2998,3 @@           ? console.error(-              "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+              "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",               children$jscomp$6.length@@ -3485,3 +3441,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -3545,9 +3500,9 @@     case "head":-      if (formatContext.insertionMode < HTML_MODE) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error("The `<head>` tag may only be rendered once.");-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (+        formatContext.insertionMode < HTML_MODE &&+        null === renderState.headChunks+      ) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -3562,12 +3517,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (formatContext.insertionMode < HTML_MODE) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error("The `<body>` tag may only be rendered once.");-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        formatContext.insertionMode === ROOT_HTML_MODE &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = ["<!DOCTYPE html>"];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -3577,23 +3532,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (formatContext.insertionMode === ROOT_HTML_MODE) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error("The `<html>` tag may only be rendered once.");-        preamble$jscomp$1.htmlChunks = ["<!DOCTYPE html>"];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,
… 1902 more lines (truncated)
cjs/react-dom-server.bun.production.js +277 lines
--- +++ @@ -27,6 +27,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -254,12 +254,3 @@     bootstrapScriptContent.push("\x3c/script>"));-  importMap = onHeaders-    ? {-        preconnects: "",-        fontPreloads: "",-        highImagePreloads: "",-        remainingCapacity:-          2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)-      }-    : null;-  onHeaders = {+  importMap = {     placeholderPrefix: idPrefix + "P:",@@ -268,3 +259,4 @@     startInlineScript: inlineScriptWithNonce,-    preamble: createPreambleState(),+    htmlChunks: null,+    headChunks: null,     externalRuntimeScript: null,@@ -273,3 +265,11 @@     onHeaders: onHeaders,-    headers: importMap,+    headers: onHeaders+      ? {+          preconnects: "",+          fontPreloads: "",+          highImagePreloads: "",+          remainingCapacity:+            2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)+        }+      : null,     resets: {@@ -302,4 +302,4 @@   if (void 0 !== bootstrapScripts)-    for (importMap = 0; importMap < bootstrapScripts.length; importMap++) {-      var scriptConfig = bootstrapScripts[importMap];+    for (onHeaders = 0; onHeaders < bootstrapScripts.length; onHeaders++) {+      var scriptConfig = bootstrapScripts[onHeaders];       idPrefix = inlineScriptWithNonce = void 0;@@ -330,3 +330,3 @@       pushLinkImpl(scriptConfig, bootstrapScriptContent);-      onHeaders.bootstrapScripts.add(scriptConfig);+      importMap.bootstrapScripts.add(scriptConfig);       externalRuntimeConfig.push(@@ -363,4 +363,4 @@         "string" === typeof bootstrapScriptContent-          ? (idPrefix.href = importMap = bootstrapScriptContent)-          : ((idPrefix.href = importMap = bootstrapScriptContent.src),+          ? (idPrefix.href = onHeaders = bootstrapScriptContent)+          : ((idPrefix.href = onHeaders = bootstrapScriptContent.src),             (idPrefix.integrity = inlineScriptWithNonce =@@ -377,3 +377,3 @@         (bootstrapScriptContent = resumableState),-        (scriptConfig = importMap),+        (scriptConfig = onHeaders),         (bootstrapScriptContent.scriptResources[scriptConfig] = null),@@ -382,6 +382,6 @@         pushLinkImpl(bootstrapScriptContent, idPrefix),-        onHeaders.bootstrapScripts.add(bootstrapScriptContent),+        importMap.bootstrapScripts.add(bootstrapScriptContent),         externalRuntimeConfig.push(           '<script type="module" src="',-          escapeTextForBrowser(importMap)+          escapeTextForBrowser(onHeaders)         ),@@ -400,3 +400,3 @@         externalRuntimeConfig.push('" async="">\x3c/script>');-  return onHeaders;+  return importMap; }@@ -429,10 +429,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -447,5 +439,5 @@     "http://www.w3.org/2000/svg" === namespaceURI-      ? 4+      ? 3       : "http://www.w3.org/1998/Math/MathML" === namespaceURI-        ? 5+        ? 4         : 0,@@ -466,3 +458,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -470,3 +462,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -474,3 +466,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -478,18 +470,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -923,25 +914,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(">");-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -988,3 +956,2 @@   renderState,-  preambleState,   hoistableState,@@ -1468,3 +1435,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1487,3 +1454,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1569,3 +1536,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1610,3 +1577,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1713,3 +1680,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1832,3 +1799,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -1892,9 +1858,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error("The `<head>` tag may only be rendered once.");-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -1909,12 +1872,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error("The `<body>` tag may only be rendered once.");-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = ["<!DOCTYPE html>"];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -1924,23 +1887,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {
… 900 more lines (truncated)
cjs/react-dom-server.edge.development.js +527 lines
--- +++ @@ -852,3 +852,4 @@         startInlineScript: inlineScriptWithNonce,-        preamble: createPreambleState(),+        htmlChunks: null,+        headChunks: null,         externalRuntimeScript: null,@@ -1018,10 +1019,2 @@     }-    function createPreambleState() {-      return {-        htmlChunks: null,-        headChunks: null,-        bodyChunks: null,-        contribution: NoContribution-      };-    }     function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -1096,22 +1089,12 @@           );-        case "head":-          if (parentContext.insertionMode < HTML_MODE)-            return createFormatContext(-              HTML_HEAD_MODE,-              null,-              parentContext.tagScope-            );-          break;-        case "html":-          if (parentContext.insertionMode === ROOT_HTML_MODE)-            return createFormatContext(-              HTML_HTML_MODE,-              null,-              parentContext.tagScope-            );       }-      return parentContext.insertionMode >= HTML_TABLE_MODE ||-        parentContext.insertionMode < HTML_MODE+      return parentContext.insertionMode >= HTML_TABLE_MODE         ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-        : parentContext;+        : parentContext.insertionMode === ROOT_HTML_MODE+          ? "html" === type+            ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+            : createFormatContext(HTML_MODE, null, parentContext.tagScope)+          : parentContext.insertionMode === HTML_HTML_MODE+            ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+            : parentContext;     }@@ -1766,25 +1749,2 @@     }-    function pushStartSingletonElement(target, props, tag) {-      target.push(startChunkForTag(tag));-      var innerHTML = (tag = null),-        propKey;-      for (propKey in props)-        if (hasOwnProperty.call(props, propKey)) {-          var propValue = props[propKey];-          if (null != propValue)-            switch (propKey) {-              case "children":-                tag = propValue;-                break;-              case "dangerouslySetInnerHTML":-                innerHTML = propValue;-                break;-              default:-                pushAttribute(target, propKey, propValue);-            }-        }-      target.push(endOfStartTag);-      pushInnerHTML(target, innerHTML, tag);-      return tag;-    }     function pushStartGenericElement(target, props, tag) {@@ -1829,3 +1789,2 @@       renderState,-      preambleState,       hoistableState,@@ -2473,3 +2432,3 @@               ? console.error(-                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",                   children$jscomp$6.length@@ -2938,3 +2897,2 @@               0 < headers.remainingCapacity &&-              "string" !== typeof props.srcSet &&               ("high" === props.fetchPriority ||@@ -2999,9 +2957,9 @@         case "head":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble = preambleState || renderState.preamble;-            if (preamble.headChunks)-              throw Error("The `<head>` tag may only be rendered once.");-            preamble.headChunks = [];-            var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-              preamble.headChunks,+          if (+            formatContext.insertionMode < HTML_MODE &&+            null === renderState.headChunks+          ) {+            renderState.headChunks = [];+            var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+              renderState.headChunks,               props,@@ -3016,12 +2974,12 @@           return JSCompiler_inline_result$jscomp$9;-        case "body":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble$jscomp$0 = preambleState || renderState.preamble;-            if (preamble$jscomp$0.bodyChunks)-              throw Error("The `<body>` tag may only be rendered once.");-            preamble$jscomp$0.bodyChunks = [];-            var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-              preamble$jscomp$0.bodyChunks,+        case "html":+          if (+            formatContext.insertionMode === ROOT_HTML_MODE &&+            null === renderState.htmlChunks+          ) {+            renderState.htmlChunks = [doctypeChunk];+            var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+              renderState.htmlChunks,               props,-              "body"+              "html"             );@@ -3031,23 +2989,5 @@               props,-              "body"+              "html"             );           return JSCompiler_inline_result$jscomp$10;-        case "html":-          if (formatContext.insertionMode === ROOT_HTML_MODE) {-            var preamble$jscomp$1 = preambleState || renderState.preamble;-            if (preamble$jscomp$1.htmlChunks)-              throw Error("The `<html>` tag may only be rendered once.");-            preamble$jscomp$1.htmlChunks = [doctypeChunk];-            var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-              preamble$jscomp$1.htmlChunks,-              props,-              "html"-            );-          } else-            JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-              target$jscomp$0,-              props,-              "html"-            );-          return JSCompiler_inline_result$jscomp$11;         default:@@ -3121,17 +3061,2 @@     }-    function hoistPreambleState(renderState, preambleState) {-      renderState = renderState.preamble;-      null === renderState.htmlChunks &&-        preambleState.htmlChunks &&-        ((renderState.htmlChunks = preambleState.htmlChunks),-        (preambleState.contribution |= 1));-      null === renderState.headChunks &&-        preambleState.headChunks &&-        ((renderState.headChunks = preambleState.headChunks),-        (preambleState.contribution |= 4));-      null === renderState.bodyChunks &&-        preambleState.bodyChunks &&-        ((renderState.bodyChunks = preambleState.bodyChunks),-        (preambleState.contribution |= 2));-    }     function writeBootstrap(destination, renderState) {@@ -3156,9 +3081,2 @@     }-    function writePreambleContribution(destination, preambleState) {-      preambleState = preambleState.contribution;-      preambleState !== NoContribution &&-        (writeChunk(destination, boundaryPreambleContributionChunkStart),-        writeChunk(destination, stringToChunk("" + preambleState)),-        writeChunk(destination, boundaryPreambleContributionChunkEnd));-    }     function writeStartSegment(destination, renderState, formatContext, id) {@@ -3167,3 +3085,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3225,3 +3142,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3632,2 +3548,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -3640,4 +3558,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -3651,4 +3567,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -4329,23 +4243,2 @@     }-    function formatOwnerStack(error) {-      var prevPrepareStackTrace = Error.prepareStackTrace;-      Error.prepareStackTrace = prepareStackTrace;-      error = error.stack;-      Error.prepareStackTrace = prevPrepareStackTrace;-      error.startsWith("Error: react-stack-top-frame\n") &&-        (error = error.slice(29));-      prevPrepareStackTrace = error.indexOf("\n");-      -1 !== prevPrepareStackTrace &&-        (error = error.slice(prevPrepareStackTrace + 1));-      prevPrepareStackTrace = error.indexOf("react_stack_bottom_frame");-      -1 !== prevPrepareStackTrace &&-        (prevPrepareStackTrace = error.lastIndexOf(-          "\n",-          prevPrepareStackTrace-        ));-      if (-1 !== prevPrepareStackTrace)-        error = error.slice(0, prevPrepareStackTrace);-      else return "";-      return error;-    }     function describeComponentStackByType(type) {@@ -4354,3 +4247,3 @@         return type.prototype && type.prototype.isReactComponent-          ? describeNativeComponentFrame(type, !0)+          ? ((type = describeNativeComponentFrame(type, !0)), type)           : describeNativeComponentFrame(type, !1);@@ -4389,2 +4282,14 @@     }+    function getStackByComponentStackNode(componentStack) {+      try {+        var info = "";+        do+          (info += describeComponentStackByType(componentStack.type)),+            (componentStack = componentStack.parent);+        while (componentStack);+        return info;+      } catch (x) {+        return "\nError generating stack: " + x.message + "\n" + x.stack;+      }+    }     function defaultErrorHandler(error) {@@ -4445,3 +4350,3 @@       this.pendingRootTasks = this.allPendingTasks = this.nextSegmentId = 0;
… 1741 more lines (truncated)
cjs/react-dom-server.edge.production.js +258 lines
--- +++ @@ -51,6 +51,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -415,3 +415,4 @@     startInlineScript: inlineScriptWithNonce,-    preamble: createPreambleState(),+    htmlChunks: null,+    headChunks: null,     externalRuntimeScript: null,@@ -582,10 +583,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -600,5 +593,5 @@     "http://www.w3.org/2000/svg" === namespaceURI-      ? 4+      ? 3       : "http://www.w3.org/1998/Math/MathML" === namespaceURI-        ? 5+        ? 4         : 0,@@ -619,3 +612,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -623,3 +616,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -627,3 +620,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -631,18 +624,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -1172,25 +1164,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(endOfStartTag);-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -1239,3 +1208,2 @@   renderState,-  preambleState,   hoistableState,@@ -1727,3 +1695,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1746,3 +1714,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1828,3 +1796,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1869,3 +1837,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1978,3 +1946,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -2097,3 +2065,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -2157,9 +2124,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error("The `<head>` tag may only be rendered once.");-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -2174,12 +2138,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error("The `<body>` tag may only be rendered once.");-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = [doctypeChunk];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -2189,23 +2153,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error("The `<html>` tag may only be rendered once.");-        preamble$jscomp$1.htmlChunks = [doctypeChunk];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,-          "html"-        );-      return JSCompiler_inline_result$jscomp$11;     default:@@ -2272,17 +2218,2 @@ }-function hoistPreambleState(renderState, preambleState) {-  renderState = renderState.preamble;-  null === renderState.htmlChunks &&-    preambleState.htmlChunks &&-    ((renderState.htmlChunks = preambleState.htmlChunks),-    (preambleState.contribution |= 1));-  null === renderState.headChunks &&-    preambleState.headChunks &&-    ((renderState.headChunks = preambleState.headChunks),-    (preambleState.contribution |= 4));-  null === renderState.bodyChunks &&-    preambleState.bodyChunks &&-    ((renderState.bodyChunks = preambleState.bodyChunks),-    (preambleState.contribution |= 2));-} function writeBootstrap(destination, renderState) {@@ -2326,12 +2257,2 @@   return writeChunkAndReturn(destination, startPendingSuspenseBoundary2);-}-var boundaryPreambleContributionChunkStart =-    stringToPrecomputedChunk("\x3c!--"),-  boundaryPreambleContributionChunkEnd = stringToPrecomputedChunk("--\x3e");-function writePreambleContribution(destination, preambleState) {-  preambleState = preambleState.contribution;-  0 !== preambleState &&-    (writeChunk(destination, boundaryPreambleContributionChunkStart),-    writeChunk(destination, stringToChunk("" + preambleState)),-    writeChunk(destination, boundaryPreambleContributionChunkEnd)); }@@ -2368,3 +2289,2 @@     case 1:-    case 3:     case 2:@@ -2376,3 +2296,3 @@       );-    case 4:+    case 3:       return (@@ -2383,3 +2303,3 @@       );-    case 5:+    case 4:       return (@@ -2390,3 +2310,3 @@       );-    case 6:
… 837 more lines (truncated)
cjs/react-dom-server.node.development.js +527 lines
--- +++ @@ -794,3 +794,4 @@         startInlineScript: inlineScriptWithNonce,-        preamble: createPreambleState(),+        htmlChunks: null,+        headChunks: null,         externalRuntimeScript: null,@@ -960,10 +961,2 @@     }-    function createPreambleState() {-      return {-        htmlChunks: null,-        headChunks: null,-        bodyChunks: null,-        contribution: NoContribution-      };-    }     function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -1038,22 +1031,12 @@           );-        case "head":-          if (parentContext.insertionMode < HTML_MODE)-            return createFormatContext(-              HTML_HEAD_MODE,-              null,-              parentContext.tagScope-            );-          break;-        case "html":-          if (parentContext.insertionMode === ROOT_HTML_MODE)-            return createFormatContext(-              HTML_HTML_MODE,-              null,-              parentContext.tagScope-            );       }-      return parentContext.insertionMode >= HTML_TABLE_MODE ||-        parentContext.insertionMode < HTML_MODE+      return parentContext.insertionMode >= HTML_TABLE_MODE         ? createFormatContext(HTML_MODE, null, parentContext.tagScope)-        : parentContext;+        : parentContext.insertionMode === ROOT_HTML_MODE+          ? "html" === type+            ? createFormatContext(HTML_HTML_MODE, null, parentContext.tagScope)+            : createFormatContext(HTML_MODE, null, parentContext.tagScope)+          : parentContext.insertionMode === HTML_HTML_MODE+            ? createFormatContext(HTML_MODE, null, parentContext.tagScope)+            : parentContext;     }@@ -1693,25 +1676,2 @@     }-    function pushStartSingletonElement(target, props, tag) {-      target.push(startChunkForTag(tag));-      var innerHTML = (tag = null),-        propKey;-      for (propKey in props)-        if (hasOwnProperty.call(props, propKey)) {-          var propValue = props[propKey];-          if (null != propValue)-            switch (propKey) {-              case "children":-                tag = propValue;-                break;-              case "dangerouslySetInnerHTML":-                innerHTML = propValue;-                break;-              default:-                pushAttribute(target, propKey, propValue);-            }-        }-      target.push(endOfStartTag);-      pushInnerHTML(target, innerHTML, tag);-      return tag;-    }     function pushStartGenericElement(target, props, tag) {@@ -1756,3 +1716,2 @@       renderState,-      preambleState,       hoistableState,@@ -2392,3 +2351,3 @@               ? console.error(-                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",+                  "React expects the `children` prop of <title> tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length %s instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be commong to combine text nodes and value nodes. For example: <title>hello {nameOfUser}</title>. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: <title>{`hello ${nameOfUser}`}</title>.",                   children$jscomp$6.length@@ -2851,3 +2810,2 @@               0 < headers.remainingCapacity &&-              "string" !== typeof props.srcSet &&               ("high" === props.fetchPriority ||@@ -2912,9 +2870,9 @@         case "head":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble = preambleState || renderState.preamble;-            if (preamble.headChunks)-              throw Error("The `<head>` tag may only be rendered once.");-            preamble.headChunks = [];-            var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-              preamble.headChunks,+          if (+            formatContext.insertionMode < HTML_MODE &&+            null === renderState.headChunks+          ) {+            renderState.headChunks = [];+            var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+              renderState.headChunks,               props,@@ -2929,12 +2887,12 @@           return JSCompiler_inline_result$jscomp$9;-        case "body":-          if (formatContext.insertionMode < HTML_MODE) {-            var preamble$jscomp$0 = preambleState || renderState.preamble;-            if (preamble$jscomp$0.bodyChunks)-              throw Error("The `<body>` tag may only be rendered once.");-            preamble$jscomp$0.bodyChunks = [];-            var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-              preamble$jscomp$0.bodyChunks,+        case "html":+          if (+            formatContext.insertionMode === ROOT_HTML_MODE &&+            null === renderState.htmlChunks+          ) {+            renderState.htmlChunks = [doctypeChunk];+            var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+              renderState.htmlChunks,               props,-              "body"+              "html"             );@@ -2944,23 +2902,5 @@               props,-              "body"+              "html"             );           return JSCompiler_inline_result$jscomp$10;-        case "html":-          if (formatContext.insertionMode === ROOT_HTML_MODE) {-            var preamble$jscomp$1 = preambleState || renderState.preamble;-            if (preamble$jscomp$1.htmlChunks)-              throw Error("The `<html>` tag may only be rendered once.");-            preamble$jscomp$1.htmlChunks = [doctypeChunk];-            var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-              preamble$jscomp$1.htmlChunks,-              props,-              "html"-            );-          } else-            JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-              target$jscomp$0,-              props,-              "html"-            );-          return JSCompiler_inline_result$jscomp$11;         default:@@ -3032,17 +2972,2 @@     }-    function hoistPreambleState(renderState, preambleState) {-      renderState = renderState.preamble;-      null === renderState.htmlChunks &&-        preambleState.htmlChunks &&-        ((renderState.htmlChunks = preambleState.htmlChunks),-        (preambleState.contribution |= 1));-      null === renderState.headChunks &&-        preambleState.headChunks &&-        ((renderState.headChunks = preambleState.headChunks),-        (preambleState.contribution |= 4));-      null === renderState.bodyChunks &&-        preambleState.bodyChunks &&-        ((renderState.bodyChunks = preambleState.bodyChunks),-        (preambleState.contribution |= 2));-    }     function writeBootstrap(destination, renderState) {@@ -3067,9 +2992,2 @@     }-    function writePreambleContribution(destination, preambleState) {-      preambleState = preambleState.contribution;-      preambleState !== NoContribution &&-        (writeChunk(destination, boundaryPreambleContributionChunkStart),-        writeChunk(destination, "" + preambleState),-        writeChunk(destination, boundaryPreambleContributionChunkEnd));-    }     function writeStartSegment(destination, renderState, formatContext, id) {@@ -3078,3 +2996,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3136,3 +3053,2 @@         case HTML_HTML_MODE:-        case HTML_HEAD_MODE:         case HTML_MODE:@@ -3538,2 +3454,4 @@           return "Fragment";+        case REACT_PORTAL_TYPE:+          return "Portal";         case REACT_PROFILER_TYPE:@@ -3546,4 +3464,2 @@           return "SuspenseList";-        case REACT_ACTIVITY_TYPE:-          return "Activity";       }@@ -3557,4 +3473,2 @@         ) {-          case REACT_PORTAL_TYPE:-            return "Portal";           case REACT_CONTEXT_TYPE:@@ -4232,23 +4146,2 @@     }-    function formatOwnerStack(error) {-      var prevPrepareStackTrace = Error.prepareStackTrace;-      Error.prepareStackTrace = prepareStackTrace;-      error = error.stack;-      Error.prepareStackTrace = prevPrepareStackTrace;-      error.startsWith("Error: react-stack-top-frame\n") &&-        (error = error.slice(29));-      prevPrepareStackTrace = error.indexOf("\n");-      -1 !== prevPrepareStackTrace &&-        (error = error.slice(prevPrepareStackTrace + 1));-      prevPrepareStackTrace = error.indexOf("react_stack_bottom_frame");-      -1 !== prevPrepareStackTrace &&-        (prevPrepareStackTrace = error.lastIndexOf(-          "\n",-          prevPrepareStackTrace-        ));-      if (-1 !== prevPrepareStackTrace)-        error = error.slice(0, prevPrepareStackTrace);-      else return "";-      return error;-    }     function describeComponentStackByType(type) {@@ -4257,3 +4150,3 @@         return type.prototype && type.prototype.isReactComponent-          ? describeNativeComponentFrame(type, !0)+          ? ((type = describeNativeComponentFrame(type, !0)), type)           : describeNativeComponentFrame(type, !1);@@ -4292,2 +4185,14 @@     }+    function getStackByComponentStackNode(componentStack) {+      try {+        var info = "";+        do+          (info += describeComponentStackByType(componentStack.type)),+            (componentStack = componentStack.parent);+        while (componentStack);+        return info;+      } catch (x) {+        return "\nError generating stack: " + x.message + "\n" + x.stack;+      }+    }     function defaultErrorHandler(error) {@@ -4348,3 +4253,3 @@       this.pendingRootTasks = this.allPendingTasks = this.nextSegmentId = 0;
… 1739 more lines (truncated)
cjs/react-dom-server.node.production.js +258 lines
--- +++ @@ -31,6 +31,6 @@   REACT_SCOPE_TYPE = Symbol.for("react.scope"),-  REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),+  REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"),+  REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"),   REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"),   REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel"),-  REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"),   MAYBE_ITERATOR_SYMBOL = Symbol.iterator,@@ -363,3 +363,4 @@     startInlineScript: inlineScriptWithNonce,-    preamble: createPreambleState(),+    htmlChunks: null,+    headChunks: null,     externalRuntimeScript: null,@@ -524,10 +525,2 @@ }-function createPreambleState() {-  return {-    htmlChunks: null,-    headChunks: null,-    bodyChunks: null,-    contribution: 0-  };-} function createFormatContext(insertionMode, selectedValue, tagScope) {@@ -542,5 +535,5 @@     "http://www.w3.org/2000/svg" === namespaceURI-      ? 4+      ? 3       : "http://www.w3.org/1998/Math/MathML" === namespaceURI-        ? 5+        ? 4         : 0,@@ -561,3 +554,3 @@     case "svg":-      return createFormatContext(4, null, parentContext.tagScope);+      return createFormatContext(3, null, parentContext.tagScope);     case "picture":@@ -565,3 +558,3 @@     case "math":-      return createFormatContext(5, null, parentContext.tagScope);+      return createFormatContext(4, null, parentContext.tagScope);     case "foreignObject":@@ -569,3 +562,3 @@     case "table":-      return createFormatContext(6, null, parentContext.tagScope);+      return createFormatContext(5, null, parentContext.tagScope);     case "thead":@@ -573,18 +566,17 @@     case "tfoot":+      return createFormatContext(6, null, parentContext.tagScope);+    case "colgroup":+      return createFormatContext(8, null, parentContext.tagScope);+    case "tr":       return createFormatContext(7, null, parentContext.tagScope);-    case "colgroup":-      return createFormatContext(9, null, parentContext.tagScope);-    case "tr":-      return createFormatContext(8, null, parentContext.tagScope);-    case "head":-      if (2 > parentContext.insertionMode)-        return createFormatContext(3, null, parentContext.tagScope);-      break;-    case "html":-      if (0 === parentContext.insertionMode)-        return createFormatContext(1, null, parentContext.tagScope);   }-  return 6 <= parentContext.insertionMode || 2 > parentContext.insertionMode+  return 5 <= parentContext.insertionMode     ? createFormatContext(2, null, parentContext.tagScope)-    : parentContext;+    : 0 === parentContext.insertionMode+      ? "html" === type+        ? createFormatContext(1, null, parentContext.tagScope)+        : createFormatContext(2, null, parentContext.tagScope)+      : 1 === parentContext.insertionMode+        ? createFormatContext(2, null, parentContext.tagScope)+        : parentContext; }@@ -1098,25 +1090,2 @@ }-function pushStartSingletonElement(target, props, tag) {-  target.push(startChunkForTag(tag));-  var innerHTML = (tag = null),-    propKey;-  for (propKey in props)-    if (hasOwnProperty.call(props, propKey)) {-      var propValue = props[propKey];-      if (null != propValue)-        switch (propKey) {-          case "children":-            tag = propValue;-            break;-          case "dangerouslySetInnerHTML":-            innerHTML = propValue;-            break;-          default:-            pushAttribute(target, propKey, propValue);-        }-    }-  target.push(endOfStartTag);-  pushInnerHTML(target, innerHTML, tag);-  return tag;-} function pushStartGenericElement(target, props, tag) {@@ -1165,3 +1134,2 @@   renderState,-  preambleState,   hoistableState,@@ -1645,3 +1613,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1664,3 +1632,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1746,3 +1714,3 @@         props.onError ||-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1787,3 +1755,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -1890,3 +1858,3 @@       if (-        4 === formatContext.insertionMode ||+        3 === formatContext.insertionMode ||         formatContext.tagScope & 1 ||@@ -2009,3 +1977,2 @@           0 < headers.remainingCapacity &&-          "string" !== typeof props.srcSet &&           ("high" === props.fetchPriority ||@@ -2069,9 +2036,6 @@     case "head":-      if (2 > formatContext.insertionMode) {-        var preamble = preambleState || renderState.preamble;-        if (preamble.headChunks)-          throw Error("The `<head>` tag may only be rendered once.");-        preamble.headChunks = [];-        var JSCompiler_inline_result$jscomp$9 = pushStartSingletonElement(-          preamble.headChunks,+      if (2 > formatContext.insertionMode && null === renderState.headChunks) {+        renderState.headChunks = [];+        var JSCompiler_inline_result$jscomp$9 = pushStartGenericElement(+          renderState.headChunks,           props,@@ -2086,12 +2050,12 @@       return JSCompiler_inline_result$jscomp$9;-    case "body":-      if (2 > formatContext.insertionMode) {-        var preamble$jscomp$0 = preambleState || renderState.preamble;-        if (preamble$jscomp$0.bodyChunks)-          throw Error("The `<body>` tag may only be rendered once.");-        preamble$jscomp$0.bodyChunks = [];-        var JSCompiler_inline_result$jscomp$10 = pushStartSingletonElement(-          preamble$jscomp$0.bodyChunks,+    case "html":+      if (+        0 === formatContext.insertionMode &&+        null === renderState.htmlChunks+      ) {+        renderState.htmlChunks = [doctypeChunk];+        var JSCompiler_inline_result$jscomp$10 = pushStartGenericElement(+          renderState.htmlChunks,           props,-          "body"+          "html"         );@@ -2101,23 +2065,5 @@           props,-          "body"+          "html"         );       return JSCompiler_inline_result$jscomp$10;-    case "html":-      if (0 === formatContext.insertionMode) {-        var preamble$jscomp$1 = preambleState || renderState.preamble;-        if (preamble$jscomp$1.htmlChunks)-          throw Error("The `<html>` tag may only be rendered once.");-        preamble$jscomp$1.htmlChunks = [doctypeChunk];-        var JSCompiler_inline_result$jscomp$11 = pushStartSingletonElement(-          preamble$jscomp$1.htmlChunks,-          props,-          "html"-        );-      } else-        JSCompiler_inline_result$jscomp$11 = pushStartGenericElement(-          target$jscomp$0,-          props,-          "html"-        );-      return JSCompiler_inline_result$jscomp$11;     default:@@ -2184,17 +2130,2 @@ }-function hoistPreambleState(renderState, preambleState) {-  renderState = renderState.preamble;-  null === renderState.htmlChunks &&-    preambleState.htmlChunks &&-    ((renderState.htmlChunks = preambleState.htmlChunks),-    (preambleState.contribution |= 1));-  null === renderState.headChunks &&-    preambleState.headChunks &&-    ((renderState.headChunks = preambleState.headChunks),-    (preambleState.contribution |= 4));-  null === renderState.bodyChunks &&-    preambleState.bodyChunks &&-    ((renderState.bodyChunks = preambleState.bodyChunks),-    (preambleState.contribution |= 2));-} function writeBootstrap(destination, renderState) {@@ -2238,12 +2169,2 @@   return writeChunkAndReturn(destination, startPendingSuspenseBoundary2);-}-var boundaryPreambleContributionChunkStart =-    stringToPrecomputedChunk("\x3c!--"),-  boundaryPreambleContributionChunkEnd = stringToPrecomputedChunk("--\x3e");-function writePreambleContribution(destination, preambleState) {-  preambleState = preambleState.contribution;-  0 !== preambleState &&-    (writeChunk(destination, boundaryPreambleContributionChunkStart),-    writeChunk(destination, "" + preambleState),-    writeChunk(destination, boundaryPreambleContributionChunkEnd)); }@@ -2280,3 +2201,2 @@     case 1:-    case 3:     case 2:@@ -2288,3 +2208,3 @@       );-    case 4:+    case 3:       return (@@ -2295,3 +2215,3 @@       );-    case 5:+    case 4:       return (@@ -2302,3 +2222,3 @@       );-    case 6:
… 837 more lines (truncated)
cjs/react-dom.development.js +1 lines
--- +++ @@ -418,3 +418,3 @@     };-    exports.version = "19.1.9";+    exports.version = "19.0.8";     "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
cjs/react-dom.production.js +1 lines
--- +++ @@ -209,2 +209,2 @@ };-exports.version = "19.1.9";+exports.version = "19.0.8";
cjs/react-dom.react-server.development.js +1 lines
--- +++ @@ -338,3 +338,3 @@     };-    exports.version = "19.1.9";+    exports.version = "19.0.8";   })();
cjs/react-dom.react-server.production.js +1 lines
--- +++ @@ -151,2 +151,2 @@ };-exports.version = "19.1.9";+exports.version = "19.0.8";
package.json +3 lines
--- +++ @@ -2,3 +2,3 @@   "name": "react-dom",-  "version": "19.1.9",+  "version": "19.0.8",   "description": "React package for working with the DOM.",@@ -19,6 +19,6 @@   "dependencies": {-    "scheduler": "^0.26.0"+    "scheduler": "^0.25.0"   },   "peerDependencies": {-    "react": "^19.1.9"+    "react": "^19.0.8"   },
rollup npm
4.62.5 1d ago nominal
BURST ×38
latest 4.62.5 versions 942 maintainers 5
4.60.1
4.60.2
4.60.3
4.60.4
4.61.0
4.61.1
4.62.0
4.62.1
4.62.2
4.62.3
4.62.4
4.62.5
BURST
2 releases in 9m: 0.2.0, 0.2.1
info · registry-verified · 2015-05-17 · 11y ago
BURST
3 releases in 34m: 0.6.0, 0.6.1, 0.6.2
info · registry-verified · 2015-05-26 · 11y ago
BURST
2 releases in 5m: 0.6.3, 0.6.4
info · registry-verified · 2015-05-26 · 11y ago
BURST
2 releases in 53m: 0.7.4, 0.7.5
info · registry-verified · 2015-06-06 · 11y ago
BURST
2 releases in 41m: 0.9.0, 0.9.1
info · registry-verified · 2015-07-10 · 11y ago
BURST
3 releases in 39m: 0.17.1, 0.17.2, 0.17.3
info · registry-verified · 2015-09-30 · 10y ago
BURST
2 releases in 29m: 0.23.0, 0.23.1
info · registry-verified · 2015-12-30 · 10y ago
BURST
2 releases in 3m: 0.34.6, 0.34.7
info · registry-verified · 2016-08-07 · 10y ago
BURST
2 releases in 5m: 0.35.1, 0.35.2
info · registry-verified · 2016-09-10 · 9y ago
BURST
2 releases in 16m: 0.35.5, 0.35.6
info · registry-verified · 2016-09-10 · 9y ago
BURST
2 releases in 43m: 0.36.2, 0.36.3
info · registry-verified · 2016-10-09 · 9y ago
BURST
2 releases in 57m: 0.39.1, 0.39.2
info · registry-verified · 2016-12-30 · 9y ago
BURST
2 releases in 30m: 0.44.0, 0.45.0
info · registry-verified · 2017-07-10 · 9y ago
BURST
2 releases in 10m: 0.47.1, 0.47.2
info · registry-verified · 2017-08-12 · 9y ago
BURST
2 releases in 54m: 0.47.3, 0.47.4
info · registry-verified · 2017-08-13 · 9y ago
BURST
2 releases in 41m: 0.48.1, 0.48.2
info · registry-verified · 2017-08-20 · 9y ago
BURST
2 releases in 8m: 0.51.4, 0.51.5
info · registry-verified · 2017-11-11 · 8y ago
BURST
2 releases in 45m: 0.60.3, 0.60.4
info · registry-verified · 2018-06-13 · 8y ago
BURST
2 releases in 54m: 0.60.6, 0.60.7
info · registry-verified · 2018-06-14 · 8y ago
BURST
2 releases in 4m: 0.63.1, 0.63.2
info · registry-verified · 2018-07-18 · 8y ago
BURST
2 releases in 48m: 0.67.2, 0.67.3
info · registry-verified · 2018-11-17 · 7y ago
BURST
2 releases in 26m: 1.2.5, 1.3.0
info · registry-verified · 2019-02-26 · 7y ago
BURST
2 releases in 44m: 1.4.2, 1.5.0
info · registry-verified · 2019-03-07 · 7y ago
BURST
2 releases in 39m: 1.7.1, 1.7.2
info · registry-verified · 2019-03-24 · 7y ago
BURST
2 releases in 38m: 1.9.2, 1.9.3
info · registry-verified · 2019-04-10 · 7y ago
BURST
2 releases in 59m: 1.19.0, 1.19.1
info · registry-verified · 2019-08-05 · 7y ago
BURST
2 releases in 37m: 1.26.1, 1.26.2
info · registry-verified · 2019-10-31 · 6y ago
BURST
2 releases in 34m: 2.3.5, 2.4.0
info · registry-verified · 2020-04-09 · 6y ago
BURST
2 releases in 10m: 2.5.0, 2.6.0
info · registry-verified · 2020-04-10 · 6y ago
BURST
2 releases in 57m: 2.7.4, 2.7.5
info · registry-verified · 2020-04-29 · 6y ago
BURST
2 releases in 34m: 2.10.6, 2.10.7
info · registry-verified · 2020-05-22 · 6y ago
BURST
2 releases in 29m: 2.11.1, 2.11.2
info · registry-verified · 2020-05-28 · 6y ago
BURST
2 releases in 48m: 2.26.1, 2.26.2
info · registry-verified · 2020-08-16 · 6y ago
BURST
2 releases in 38m: 2.52.5, 2.52.6
info · registry-verified · 2021-07-01 · 5y ago
BURST
2 releases in 15m: 2.58.2, 2.58.3
info · registry-verified · 2021-10-25 · 4y ago
BURST
2 releases in 48m: 2.75.2, 2.75.3
info · registry-verified · 2022-05-29 · 4y ago
BURST
2 releases in 19m: 4.22.4, 3.29.5
info · registry-verified · 2024-09-21 · 1y ago
BURST
2 releases in 34m: 2.80.0, 3.30.0
info · registry-verified · 2026-02-22 · 6mo ago
release diff 4.62.4 → 4.62.5
+0 added · -0 removed · ~19 modified
dist/es/getLogFilter.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/es/parseAst.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/es/rollup.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/es/shared/node-entry.js +17 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb @@ -29,3 +29,3 @@ -var version = "4.62.4";+var version = "4.62.5"; const pkg = {@@ -6693,2 +6693,3 @@         const declarationStart = getDeclarationStart(code.original, this.start);+        let needsTrailingSemicolon = false;         if (this.declaration instanceof FunctionDeclaration) {@@ -6709,3 +6710,3 @@         else if (this.variable.included) {-            this.renderVariableDeclaration(code, declarationStart, options);+            needsTrailingSemicolon = this.renderVariableDeclaration(code, declarationStart, options);         }@@ -6722,2 +6723,8 @@         this.declaration.render(code, options);+        if (needsTrailingSemicolon) {+            // This needs to happen after the declaration was rendered as rendering can+            // replace the entire declaration, which would drop anything appended to the+            // left of its end.+            code.appendLeft(this.end, ';');+        }     }@@ -6737,2 +6744,4 @@     }+    // Returns whether a semicolon still needs to be appended after the declaration+    // was rendered.     renderVariableDeclaration(code, declarationStart, { format, exportNamesByVariable, snippets: { cnst, getPropertyAccess } }) {@@ -6743,9 +6752,6 @@             code.appendRight(hasTrailingSemicolon ? this.end - 1 : this.end, ')' + (hasTrailingSemicolon ? '' : ';'));-        }-        else {-            code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);-            if (!hasTrailingSemicolon) {-                code.appendLeft(this.end, ';');-            }-        }+            return false;+        }+        code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);+        return !hasTrailingSemicolon;     }
dist/es/shared/parseAst.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/es/shared/watch.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/getLogFilter.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/loadConfigFile.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/parseAst.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/rollup.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/fsevents-importer.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/index.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/loadConfigFile.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/parseAst.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/rollup.js +17 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb @@ -44,3 +44,3 @@ -var version = "4.62.4";+var version = "4.62.5"; const package_ = {@@ -10832,2 +10832,3 @@         const declarationStart = getDeclarationStart(code.original, this.start);+        let needsTrailingSemicolon = false;         if (this.declaration instanceof FunctionDeclaration) {@@ -10848,3 +10849,3 @@         else if (this.variable.included) {-            this.renderVariableDeclaration(code, declarationStart, options);+            needsTrailingSemicolon = this.renderVariableDeclaration(code, declarationStart, options);         }@@ -10861,2 +10862,8 @@         this.declaration.render(code, options);+        if (needsTrailingSemicolon) {+            // This needs to happen after the declaration was rendered as rendering can+            // replace the entire declaration, which would drop anything appended to the+            // left of its end.+            code.appendLeft(this.end, ';');+        }     }@@ -10876,2 +10883,4 @@     }+    // Returns whether a semicolon still needs to be appended after the declaration+    // was rendered.     renderVariableDeclaration(code, declarationStart, { format, exportNamesByVariable, snippets: { cnst, getPropertyAccess } }) {@@ -10882,9 +10891,6 @@             code.appendRight(hasTrailingSemicolon ? this.end - 1 : this.end, ')' + (hasTrailingSemicolon ? '' : ';'));-        }-        else {-            code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);-            if (!hasTrailingSemicolon) {-                code.appendLeft(this.end, ';');-            }-        }+            return false;+        }+        code.overwrite(this.start, declarationStart, `${cnst} ${this.variable.getName(getPropertyAccess)} = `);+        return !hasTrailingSemicolon;     }
dist/shared/watch-cli.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
dist/shared/watch.js +2 lines
--- +++ @@ -2,4 +2,4 @@   @license-	Rollup.js v4.62.4-	Sat, 01 Aug 2026 05:20:25 GMT - commit ddc4ffab628944e45dbb8d66d58aae818015440f+	Rollup.js v4.62.5+	Thu, 20 Aug 2026 16:59:36 GMT - commit c20402e2d4498a5861a4f49e00b2e7446c9900bb 
package.json +43 lines
--- +++ @@ -2,3 +2,3 @@   "name": "rollup",-  "version": "4.62.4",+  "version": "4.62.5",   "description": "Next-generation ES module bundler",@@ -117,27 +117,27 @@     "fsevents": "~2.3.2",-    "@rollup/rollup-darwin-arm64": "4.62.4",-    "@rollup/rollup-android-arm64": "4.62.4",-    "@rollup/rollup-win32-arm64-msvc": "4.62.4",-    "@rollup/rollup-freebsd-arm64": "4.62.4",-    "@rollup/rollup-linux-arm64-gnu": "4.62.4",-    "@rollup/rollup-linux-arm64-musl": "4.62.4",-    "@rollup/rollup-android-arm-eabi": "4.62.4",-    "@rollup/rollup-linux-arm-gnueabihf": "4.62.4",-    "@rollup/rollup-linux-arm-musleabihf": "4.62.4",-    "@rollup/rollup-win32-ia32-msvc": "4.62.4",-    "@rollup/rollup-linux-loong64-gnu": "4.62.4",-    "@rollup/rollup-linux-loong64-musl": "4.62.4",-    "@rollup/rollup-linux-riscv64-gnu": "4.62.4",-    "@rollup/rollup-linux-riscv64-musl": "4.62.4",-    "@rollup/rollup-linux-ppc64-gnu": "4.62.4",-    "@rollup/rollup-linux-ppc64-musl": "4.62.4",-    "@rollup/rollup-linux-s390x-gnu": "4.62.4",-    "@rollup/rollup-darwin-x64": "4.62.4",-    "@rollup/rollup-win32-x64-gnu": "4.62.4",-    "@rollup/rollup-win32-x64-msvc": "4.62.4",-    "@rollup/rollup-freebsd-x64": "4.62.4",-    "@rollup/rollup-linux-x64-gnu": "4.62.4",-    "@rollup/rollup-linux-x64-musl": "4.62.4",-    "@rollup/rollup-openbsd-x64": "4.62.4",-    "@rollup/rollup-openharmony-arm64": "4.62.4"+    "@rollup/rollup-darwin-arm64": "4.62.5",+    "@rollup/rollup-android-arm64": "4.62.5",+    "@rollup/rollup-win32-arm64-msvc": "4.62.5",+    "@rollup/rollup-freebsd-arm64": "4.62.5",+    "@rollup/rollup-linux-arm64-gnu": "4.62.5",+    "@rollup/rollup-linux-arm64-musl": "4.62.5",+    "@rollup/rollup-android-arm-eabi": "4.62.5",+    "@rollup/rollup-linux-arm-gnueabihf": "4.62.5",+    "@rollup/rollup-linux-arm-musleabihf": "4.62.5",+    "@rollup/rollup-win32-ia32-msvc": "4.62.5",+    "@rollup/rollup-linux-loong64-gnu": "4.62.5",+    "@rollup/rollup-linux-loong64-musl": "4.62.5",+    "@rollup/rollup-linux-riscv64-gnu": "4.62.5",+    "@rollup/rollup-linux-riscv64-musl": "4.62.5",+    "@rollup/rollup-linux-ppc64-gnu": "4.62.5",+    "@rollup/rollup-linux-ppc64-musl": "4.62.5",+    "@rollup/rollup-linux-s390x-gnu": "4.62.5",+    "@rollup/rollup-darwin-x64": "4.62.5",+    "@rollup/rollup-win32-x64-gnu": "4.62.5",+    "@rollup/rollup-win32-x64-msvc": "4.62.5",+    "@rollup/rollup-freebsd-x64": "4.62.5",+    "@rollup/rollup-linux-x64-gnu": "4.62.5",+    "@rollup/rollup-linux-x64-musl": "4.62.5",+    "@rollup/rollup-openbsd-x64": "4.62.5",+    "@rollup/rollup-openharmony-arm64": "4.62.5"   },@@ -155,3 +155,3 @@     "@codemirror/state": "^6.7.1",-    "@codemirror/view": "^6.43.7",+    "@codemirror/view": "^6.43.8",     "@emnapi/core": "^1.11.3",@@ -172,3 +172,3 @@     "@rollup/pluginutils": "^5.4.0",-    "@shikijs/vitepress-twoslash": "^4.3.1",+    "@shikijs/vitepress-twoslash": "^4.4.3",     "@types/mocha": "^10.0.10",@@ -176,6 +176,6 @@     "@types/picomatch": "^4.0.3",-    "@types/semver": "^7.7.1",+    "@types/semver": "^7.8.0",     "@types/yargs-parser": "^21.0.3",-    "@vue/language-server": "^3.3.8",-    "acorn": "^8.17.0",+    "@vue/language-server": "^3.3.9",+    "acorn": "^8.18.0",     "acorn-import-assertions": "^1.9.0",@@ -191,6 +191,6 @@     "es6-shim": "^0.35.8",-    "eslint": "^10.8.0",+    "eslint": "^10.8.1",     "eslint-config-prettier": "^10.1.8",     "eslint-plugin-prettier": "^5.5.6",-    "eslint-plugin-unicorn": "^72.0.0",+    "eslint-plugin-unicorn": "^73.0.0",     "eslint-plugin-vue": "^10.10.0",@@ -200,10 +200,10 @@     "github-api": "^3.4.0",-    "globals": "^17.8.0",+    "globals": "^17.9.0",     "husky": "^9.1.7",     "is-reference": "^3.0.3",-    "lint-staged": "^17.2.0",+    "lint-staged": "^17.3.0",     "locate-character": "^3.0.0",     "magic-string": "^1.1.0",-    "memfs": "^4.64.0",-    "mocha": "11.7.6",+    "memfs": "^4.68.1",+    "mocha": "11.8.0",     "nodemon": "^3.1.14",@@ -220,3 +220,3 @@     "requirejs": "^2.3.8",-    "rollup": "^4.62.3",+    "rollup": "^4.62.4",     "rollup-plugin-license": "^3.7.1",@@ -228,11 +228,11 @@     "systemjs": "^6.15.1",-    "terser": "^5.49.0",+    "terser": "^5.49.2",     "tslib": "^2.8.1",     "typescript": "^5.9.3",-    "typescript-eslint": "^8.65.0",+    "typescript-eslint": "^8.67.0",     "vite": "^7.3.6",     "vitepress": "^1.6.4",-    "vue": "^3.5.40",+    "vue": "^3.5.41",     "vue-eslint-parser": "^10.4.1",-    "vue-tsc": "^3.3.8",+    "vue-tsc": "^3.3.9",     "wasm-pack": "^0.15.0",@@ -241,3 +241,3 @@   "overrides": {-    "axios": "^1.18.1",+    "axios": "^1.19.0",     "esbuild": ">0.24.2",
@types/jest npm
30.0.0 1y ago nominal
BURST ×12
latest 30.0.0 versions 210 maintainers 1
16.0.12
29.5.7
29.5.8
16.0.13
29.5.9
16.0.14
29.5.10
29.5.11
29.5.12
29.5.13
29.5.14
30.0.0
BURST
2 releases in 0m: 18.0.0, 16.0.6
info · registry-verified · 2017-01-30 · 9y ago
BURST
2 releases in 4m: 16.0.8, 21.1.10
info · registry-verified · 2017-12-28 · 8y ago
BURST
2 releases in 6m: 23.3.14, 24.0.0
info · registry-verified · 2019-02-05 · 7y ago
BURST
2 releases in 38m: 24.0.7, 24.0.8
info · registry-verified · 2019-02-25 · 7y ago
BURST
2 releases in 0m: 24.0.14, 16.0.9
info · registry-verified · 2019-06-13 · 7y ago
BURST
2 releases in 26m: 25.2.0, 25.2.1
info · registry-verified · 2020-04-03 · 6y ago
BURST
2 releases in 13m: 26.0.11, 26.0.12
info · registry-verified · 2020-08-31 · 5y ago
BURST
2 releases in 0m: 26.0.24, 16.0.10
info · registry-verified · 2021-07-06 · 5y ago
BURST
2 releases in 0m: 29.5.5, 16.0.11
info · registry-verified · 2023-09-15 · 2y ago
BURST
2 releases in 0m: 29.5.6, 16.0.12
info · registry-verified · 2023-10-18 · 2y ago
BURST
2 releases in 0m: 29.5.8, 16.0.13
info · registry-verified · 2023-11-07 · 2y ago
BURST
2 releases in 0m: 29.5.9, 16.0.14
info · registry-verified · 2023-11-21 · 2y ago
release diff 29.5.14 → 30.0.0
+0 added · -0 removed · ~3 modified
index.d.ts +73 lines
--- +++ @@ -115,2 +115,37 @@     /**+     * Advances all timers by `msToRun` milliseconds. All pending macro-tasks that have been+     * queued by `setTimeout()`, `setInterval()` and `setImmediate()`, and would be executed+     * within this time frame will be executed.+     */+    function advanceTimersByTime(msToRun: number): void;+    /**+     * Asynchronous equivalent of `jest.advanceTimersByTime()`. It also yields to the event loop,+     * allowing any scheduled promise callbacks to execute _before_ running the timers.+     *+     * @remarks+     * Not available when using legacy fake timers implementation.+     */+    function advanceTimersByTimeAsync(msToRun: number): Promise<void>;+    /**+     * Advances all timers by the needed milliseconds to execute callbacks currently scheduled with `requestAnimationFrame`.+     * `advanceTimersToNextFrame()` is a helpful way to execute code that is scheduled using `requestAnimationFrame`.+     *+     * @remarks+     * Not available when using legacy fake timers implementation.+     */+    function advanceTimersToNextFrame(): void;+    /**+     * Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run.+     * Optionally, you can provide steps, so it will run steps amount of next timeouts/intervals.+     */+    function advanceTimersToNextTimer(step?: number): void;+    /**+     * Asynchronous equivalent of `jest.advanceTimersToNextTimer()`. It also yields to the event loop,+     * allowing any scheduled promise callbacks to execute _before_ running the timers.+     *+     * @remarks+     * Not available when using legacy fake timers implementation.+     */+    function advanceTimersToNextTimerAsync(steps?: number): Promise<void>;+    /**      * Disables automatic mocking in the module loader.@@ -217,8 +252,2 @@     /**-     * (renamed to `createMockFromModule` in Jest 26.0.0+)-     * Use the automatic mocking system to generate a mocked version of the given module.-     */-    // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-    function genMockFromModule<T>(moduleName: string): T;-    /**      * Returns `true` if test environment has been torn down.@@ -253,2 +282,12 @@     /**+     * Registers a callback function that is invoked whenever a mock is generated for a module.+     * This callback is passed the module path and the newly created mock object, and must return+     * the (potentially modified) mock object.+     *+     * If multiple callbacks are registered, they will be called in the order they were added.+     * Each callback receives the result of the previous callback as the `moduleMock` parameter,+     * making it possible to apply sequential transformations.+     */+    function onGenerateMock<T>(cb: (modulePath: string, moduleMock: T) => T): typeof jest;+    /**      * Returns the actual module instead of a mock, bypassing all checks on@@ -283,3 +322,6 @@      */-    function retryTimes(numRetries: number, options?: { logErrorsBeforeRetry?: boolean }): typeof jest;+    function retryTimes(+        numRetries: number,+        options?: { logErrorsBeforeRetry?: boolean; waitBeforeRetry?: number; retryImmediately?: boolean },+    ): typeof jest;     /**@@ -330,28 +372,7 @@     /**-     * Advances all timers by `msToRun` milliseconds. All pending macro-tasks that have been-     * queued by `setTimeout()`, `setInterval()` and `setImmediate()`, and would be executed-     * within this time frame will be executed.-     */-    function advanceTimersByTime(msToRun: number): void;-    /**-     * Asynchronous equivalent of `jest.advanceTimersByTime()`. It also yields to the event loop,-     * allowing any scheduled promise callbacks to execute _before_ running the timers.-     *-     * @remarks-     * Not available when using legacy fake timers implementation.-     */-    function advanceTimersByTimeAsync(msToRun: number): Promise<void>;-    /**-     * Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run.-     * Optionally, you can provide steps, so it will run steps amount of next timeouts/intervals.-     */-    function advanceTimersToNextTimer(step?: number): void;-    /**-     * Asynchronous equivalent of `jest.advanceTimersToNextTimer()`. It also yields to the event loop,-     * allowing any scheduled promise callbacks to execute _before_ running the timers.-     *-     * @remarks-     * Not available when using legacy fake timers implementation.-     */-    function advanceTimersToNextTimerAsync(steps?: number): Promise<void>;+     * Indicates that the module system should never return a mocked version of+     * the specified module when it is being imported (e.g. that it should always+     * return the real module).+     */+    function unstable_unmockModule(moduleName: string): typeof jest;     /**@@ -653,2 +674,8 @@         /**+         * Validate every element of an array against a condition or type It is the+         * inverse of `expect.arrayOf`.+         */+        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics+        arrayOf<E = any>(arr: E): any;+        /**          * `expect.not.objectContaining(object)` matches any received object@@ -691,3 +718,3 @@         /**-         * Matches anything but null or undefined. You can use it inside `toEqual` or `toBeCalledWith` instead+         * Matches anything but null or undefined. You can use it inside `toEqual` or `toHaveBeenCalledWith` instead          * of a literal value. For example, if you want to check that a mock function is called with a@@ -700,3 +727,3 @@          *   [1].map(x => mock(x));-         *   expect(mock).toBeCalledWith(expect.anything());+         *   expect(mock).toHaveBeenCalledWith(expect.anything());          * });@@ -706,3 +733,3 @@          * Matches anything that was created with the given constructor.-         * You can use it inside `toEqual` or `toBeCalledWith` instead of a literal value.+         * You can use it inside `toEqual` or `toHaveBeenCalledWith` instead of a literal value.          *@@ -717,3 +744,3 @@          *   randocall(mock);-         *   expect(mock).toBeCalledWith(expect.any(Number));+         *   expect(mock).toHaveBeenCalledWith(expect.any(Number));          * });@@ -723,3 +750,3 @@          * Matches any array made up entirely of elements in the provided array.-         * You can use it inside `toEqual` or `toBeCalledWith` instead of a literal value.+         * You can use it inside `toEqual` or `toHaveBeenCalledWith` instead of a literal value.          *@@ -729,2 +756,7 @@         arrayContaining<E = any>(arr: readonly E[]): any;+        /**+         * Validate every element of an array against a condition or type+         */+        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics+        arrayOf<E = any>(arr: E): any;         /**@@ -802,13 +834,4 @@         /**-         * Ensures the last call to a mock function was provided specific args.-         *-         * Optionally, you can provide a type for the expected arguments via a generic.-         * Note that the type must be either an array or a tuple.-         *-         * @deprecated in favor of `toHaveBeenLastCalledWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        lastCalledWith<E extends any[]>(...args: E): R;-        /**-         * Ensure that the last call to a mock function has returned a specified value.+         * Checks that a value is what you expect. It uses `Object.is` to check strict equality.+         * Don't use `toBe` with floating-point numbers.          *@@ -816,33 +839,2 @@          * This is particularly useful for ensuring expected objects have the right structure.-         *-         * @deprecated in favor of `toHaveLastReturnedWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        lastReturnedWith<E = any>(expected?: E): R;-        /**-         * Ensure that a mock function is called with specific arguments on an Nth call.-         *-         * Optionally, you can provide a type for the expected arguments via a generic.-         * Note that the type must be either an array or a tuple.-         *-         * @deprecated in favor of `toHaveBeenNthCalledWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        nthCalledWith<E extends any[]>(nthCall: number, ...params: E): R;-        /**-         * Ensure that the nth call to a mock function has returned a specified value.-         *-         * Optionally, you can provide a type for the expected value via a generic.-         * This is particularly useful for ensuring expected objects have the right structure.-         *-         * @deprecated in favor of `toHaveNthReturnedWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        nthReturnedWith<E = any>(n: number, expected?: E): R;-        /**-         * Checks that a value is what you expect. It uses `Object.is` to check strict equality.-         * Don't use `toBe` with floating-point numbers.-         *-         * Optionally, you can provide a type for the expected value via a generic.-         * This is particularly useful for ensuring expected objects have the right structure.          */@@ -850,24 +842,2 @@         toBe<E = any>(expected: E): R;-        /**-         * Ensures that a mock function is called.-         *-         * @deprecated in favor of `toHaveBeenCalled`-         */-        toBeCalled(): R;-        /**-         * Ensures that a mock function is called an exact number of times.-         *-         * @deprecated in favor of `toHaveBeenCalledTimes`-         */-        toBeCalledTimes(expected: number): R;-        /**-         * Ensure that a mock function is called with specific arguments.-         *-         * Optionally, you can provide a type for the expected arguments via a generic.-         * Note that the type must be either an array or a tuple.-         *-         * @deprecated in favor of `toHaveBeenCalledWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        toBeCalledWith<E extends any[]>(...args: E): R;         /**@@ -1101,15 +1071,3 @@         /**-         * Ensure that a mock function has returned (as opposed to thrown) at least once.-         *-         * @deprecated in favor of `toHaveReturned`-         */-        toReturn(): R;-        /**-         * Ensure that a mock function has returned (as opposed to thrown) a specified number of times.-         *-         * @deprecated in favor of `toHaveReturnedTimes`-         */-        toReturnTimes(count: number): R;-        /**-         * Ensure that a mock function has returned a specified value at least once.+         * Use to test that objects have the same types as well as structure.          *@@ -1117,12 +1075,2 @@          * This is particularly useful for ensuring expected objects have the right structure.-         *-         * @deprecated in favor of `toHaveReturnedWith`-         */-        // eslint-disable-next-line @definitelytyped/no-unnecessary-generics-        toReturnWith<E = any>(value?: E): R;-        /**-         * Use to test that objects have the same types as well as structure.-         *-         * Optionally, you can provide a type for the expected value via a generic.-         * This is particularly useful for ensuring expected objects have the right structure.
… 10 more lines (truncated)
package.json +5 lines
--- +++ @@ -2,3 +2,3 @@     "name": "@types/jest",-    "version": "29.5.14",+    "version": "30.0.0",     "description": "TypeScript definitions for jest",@@ -131,7 +131,2 @@             "url": "https://github.com/domdomegg"-        },-        {-            "name": "Tom Mrazauskas",-            "githubUsername": "mrazauskas",-            "url": "https://github.com/mrazauskas"         }@@ -140,8 +135,2 @@     "types": "index.d.ts",-    "exports": {-        ".": {-            "types": "./index.d.ts"-        },-        "./package.json": "./package.json"-    },     "repository": {@@ -153,8 +142,8 @@     "dependencies": {-        "expect": "^29.0.0",-        "pretty-format": "^29.0.0"+        "expect": "^30.0.0",+        "pretty-format": "^30.0.0"     },     "peerDependencies": {},-    "typesPublisherContentHash": "03b921cd51b4ea0ab99ff3733f9e799bed833eccc13adaa2aaeb088345807f4d",-    "typeScriptVersion": "4.8"+    "typesPublisherContentHash": "0fa4b32f7923c817b941e83858439e9ac13f522d9363e704f6140143388fc42e",+    "typeScriptVersion": "5.1" }
@types/node npm
26.2.0 14d ago nominal
critical-tier BURST ×555
latest 26.2.0 versions 2356 maintainers 1 critical-tier (snapshotted)
20.19.43
26.0.0
25.9.4
22.20.0
26.0.1
26.1.0
26.1.1
25.9.5
24.13.3
22.20.1
26.1.2
26.2.0
BURST
2 releases in 4m: 6.0.44, 6.0.45
info · registry-verified · 2016-10-06 · 9y ago
BURST
2 releases in 0m: 4.2.0, 0.12.0
info · registry-verified · 2017-01-10 · 9y ago
BURST
2 releases in 0m: 7.0.0, 6.0.60
info · registry-verified · 2017-01-11 · 9y ago
BURST
2 releases in 8m: 6.0.61, 7.0.2
info · registry-verified · 2017-01-23 · 9y ago
BURST
2 releases in 0m: 4.2.1, 6.0.62
info · registry-verified · 2017-01-25 · 9y ago
BURST
3 releases in 0m: 0.12.1, 4.2.3, 6.0.64
info · registry-verified · 2017-02-28 · 9y ago
BURST
2 releases in 6m: 6.0.65, 7.0.7
info · registry-verified · 2017-03-09 · 9y ago
BURST
5 releases in 47m: 4.2.4, 0.12.2, 6.0.66, 7.0.9, 7.0.10
info · registry-verified · 2017-03-22 · 9y ago
BURST
2 releases in 8m: 6.0.68, 7.0.12
info · registry-verified · 2017-03-27 · 9y ago
BURST
3 releases in 1m: 4.2.5, 0.12.3, 6.0.69
info · registry-verified · 2017-04-17 · 9y ago
BURST
4 releases in 3m: 0.12.4, 4.2.6, 6.0.70, 7.0.13
info · registry-verified · 2017-04-18 · 9y ago
BURST
3 releases in 41m: 4.2.7, 6.0.72, 7.0.16
info · registry-verified · 2017-05-03 · 9y ago
BURST
2 releases in 12m: 7.0.17, 7.0.18
info · registry-verified · 2017-05-05 · 9y ago
BURST
2 releases in 0m: 4.2.8, 6.0.73
info · registry-verified · 2017-05-05 · 9y ago
BURST
3 releases in 21m: 7.0.19, 7.0.20, 7.0.21
info · registry-verified · 2017-05-19 · 9y ago
BURST
2 releases in 23m: 6.0.74, 7.0.23
info · registry-verified · 2017-06-01 · 9y ago
BURST
2 releases in 0m: 7.0.24, 6.0.75
info · registry-verified · 2017-06-02 · 9y ago
BURST
4 releases in 39m: 4.2.9, 6.0.76, 7.0.25, 7.0.26
info · registry-verified · 2017-06-02 · 9y ago
BURST
4 releases in 2m: 0.12.5, 4.2.10, 6.0.77, 7.0.27
info · registry-verified · 2017-06-02 · 9y ago
BURST
4 releases in 0m: 0.12.6, 7.0.28, 4.2.11, 6.0.78
info · registry-verified · 2017-06-06 · 9y ago
BURST
2 releases in 0m: 7.0.32, 8.0.0
info · registry-verified · 2017-06-19 · 9y ago
BURST
4 releases in 36m: 6.0.79, 7.0.33, 4.2.12, 8.0.6
info · registry-verified · 2017-06-29 · 9y ago
BURST
3 releases in 2m: 7.0.34, 8.0.10, 6.0.80
info · registry-verified · 2017-07-10 · 9y ago
BURST
3 releases in 1m: 4.2.13, 7.0.35, 8.0.11
info · registry-verified · 2017-07-12 · 9y ago
BURST
3 releases in 1m: 6.0.82, 7.0.36, 8.0.12
info · registry-verified · 2017-07-13 · 9y ago
BURST
4 releases in 1m: 6.0.83, 7.0.37, 8.0.13, 4.2.14
info · registry-verified · 2017-07-14 · 9y ago
BURST
5 releases in 1m: 4.2.15, 0.12.7, 6.0.84, 8.0.14, 7.0.38
info · registry-verified · 2017-07-17 · 9y ago
BURST
5 releases in 6m: 0.12.8, 4.2.16, 6.0.85, 7.0.39, 8.0.15
info · registry-verified · 2017-07-22 · 9y ago
BURST
7 releases in 51m: 4.2.17, 6.0.86, 7.0.40, 8.0.21, 4.2.18, 7.0.41, 8.0.22
info · registry-verified · 2017-08-14 · 9y ago
BURST
5 releases in 2m: 6.0.87, 0.12.9, 4.2.19, 8.0.23, 7.0.42
info · registry-verified · 2017-08-16 · 9y ago
BURST
5 releases in 2m: 6.0.88, 8.0.25, 0.12.10, 7.0.43, 4.2.20
info · registry-verified · 2017-08-24 · 8y ago
BURST
2 releases in 10m: 8.0.35, 8.0.36
info · registry-verified · 2017-10-16 · 8y ago
BURST
2 releases in 21m: 7.0.44, 8.0.37
info · registry-verified · 2017-10-16 · 8y ago
BURST
3 releases in 34m: 8.0.38, 8.0.39, 8.0.40
info · registry-verified · 2017-10-16 · 8y ago
BURST
3 releases in 60m: 8.0.42, 8.0.43, 8.0.44
info · registry-verified · 2017-10-17 · 8y ago
BURST
5 releases in 10m: 0.12.11, 6.0.90, 4.2.21, 8.0.45, 7.0.45
info · registry-verified · 2017-10-18 · 8y ago
BURST
4 releases in 28m: 6.0.91, 4.2.22, 8.0.52, 7.0.47
info · registry-verified · 2017-11-14 · 8y ago
BURST
2 releases in 11m: 7.0.48, 8.0.53
info · registry-verified · 2017-11-15 · 8y ago
BURST
2 releases in 1m: 4.0.31, 8.0.56
info · registry-verified · 2017-12-06 · 8y ago
BURST
4 releases in 2m: 6.0.93, 4.0.32, 7.0.49, 8.0.58
info · registry-verified · 2017-12-11 · 8y ago
BURST
5 releases in 36m: 0.12.12, 7.0.50, 8.5.1, 6.0.94, 4.0.33
info · registry-verified · 2017-12-13 · 8y ago
BURST
5 releases in 3m: 0.12.13, 8.5.2, 4.0.34, 7.0.51, 6.0.95
info · registry-verified · 2017-12-20 · 8y ago
BURST
2 releases in 36m: 8.5.3, 8.5.4
info · registry-verified · 2018-01-03 · 8y ago
BURST
2 releases in 30m: 7.0.52, 4.0.35
info · registry-verified · 2018-01-05 · 8y ago
BURST
2 releases in 0m: 8.5.6, 6.0.96
info · registry-verified · 2018-01-05 · 8y ago
BURST
2 releases in 45m: 8.5.8, 9.3.0
info · registry-verified · 2018-01-08 · 8y ago
BURST
4 releases in 3m: 6.0.97, 8.5.10, 9.4.1, 7.0.53
info · registry-verified · 2018-02-06 · 8y ago
BURST
3 releases in 30m: 8.9.0, 9.4.2, 6.0.98
info · registry-verified · 2018-02-07 · 8y ago
BURST
3 releases in 1m: 9.4.3, 6.0.99, 8.9.1
info · registry-verified · 2018-02-08 · 8y ago
BURST
2 releases in 4m: 7.0.54, 4.0.36
info · registry-verified · 2018-02-09 · 8y ago
BURST
3 releases in 0m: 9.4.4, 6.0.100, 8.9.2
info · registry-verified · 2018-02-09 · 8y ago
BURST
2 releases in 0m: 9.4.5, 8.9.3
info · registry-verified · 2018-02-10 · 8y ago
BURST
6 releases in 2m: 4.0.37, 7.0.55, 0.12.15, 8.9.4, 6.0.101, 9.4.6
info · registry-verified · 2018-02-13 · 8y ago
BURST
4 releases in 34m: 6.0.102, 7.0.56, 9.4.7, 8.9.5
info · registry-verified · 2018-03-08 · 8y ago
BURST
2 releases in 2m: 4.0.38, 8.10.0
info · registry-verified · 2018-03-22 · 8y ago
BURST
3 releases in 1m: 6.0.103, 7.0.57, 9.6.0
info · registry-verified · 2018-03-22 · 8y ago
BURST
3 releases in 45m: 7.0.58, 9.6.1, 8.10.1
info · registry-verified · 2018-03-28 · 8y ago
BURST
3 releases in 55m: 4.0.39, 6.0.104, 0.12.16
info · registry-verified · 2018-04-03 · 8y ago
BURST
3 releases in 22m: 7.0.59, 9.6.2, 8.10.2
info · registry-verified · 2018-04-03 · 8y ago
BURST
3 releases in 29m: 8.10.5, 8.10.6, 9.6.3
info · registry-verified · 2018-04-10 · 8y ago
BURST
5 releases in 34m: 7.0.61, 9.6.5, 8.10.8, 4.0.40, 6.0.106
info · registry-verified · 2018-04-13 · 8y ago
BURST
2 releases in 0m: 10.0.0, 9.6.7
info · registry-verified · 2018-04-26 · 8y ago
BURST
2 releases in 51m: 7.0.62, 6.0.107
info · registry-verified · 2018-04-30 · 8y ago
BURST
2 releases in 25m: 4.0.41, 9.6.8
info · registry-verified · 2018-04-30 · 8y ago
BURST
2 releases in 0m: 10.0.3, 9.6.9
info · registry-verified · 2018-05-02 · 8y ago
BURST
4 releases in 59m: 0.12.17, 7.0.63, 9.6.10, 4.0.42
info · registry-verified · 2018-05-03 · 8y ago
BURST
2 releases in 27m: 6.0.108, 8.10.12
info · registry-verified · 2018-05-03 · 8y ago
BURST
2 releases in 1m: 9.6.12, 10.0.4
info · registry-verified · 2018-05-04 · 8y ago
BURST
5 releases in 3m: 9.6.13, 6.0.109, 10.0.5, 8.10.13, 7.0.64
info · registry-verified · 2018-05-08 · 8y ago
BURST
2 releases in 3m: 9.6.14, 10.0.6
info · registry-verified · 2018-05-08 · 8y ago
BURST
3 releases in 1m: 9.6.15, 10.0.8, 8.10.14
info · registry-verified · 2018-05-10 · 8y ago
BURST
3 releases in 0m: 10.0.9, 9.6.16, 8.10.15
info · registry-verified · 2018-05-14 · 8y ago
BURST
3 releases in 2m: 8.10.16, 9.6.17, 10.1.1
info · registry-verified · 2018-05-17 · 8y ago
BURST
7 releases in 2m: 7.0.65, 0.12.18, 8.10.17, 6.0.111, 4.0.43, 9.6.18, 10.1.2
info · registry-verified · 2018-05-18 · 8y ago
BURST
2 releases in 2m: 9.6.19, 10.1.4
info · registry-verified · 2018-05-30 · 8y ago
BURST
4 releases in 2m: 6.0.112, 8.10.18, 9.6.20, 10.3.0
info · registry-verified · 2018-05-31 · 8y ago
BURST
3 releases in 56m: 8.10.19, 9.6.21, 10.3.2
info · registry-verified · 2018-06-07 · 8y ago
BURST
5 releases in 2m: 4.0.44, 6.0.113, 7.0.66, 8.10.20, 10.3.3
info · registry-verified · 2018-06-13 · 8y ago
BURST
7 releases in 5m: 0.12.19, 4.0.45, 6.0.114, 8.10.21, 7.0.67, 9.6.23, 10.5.2
info · registry-verified · 2018-07-06 · 8y ago
BURST
3 releases in 0m: 8.10.22, 9.6.24, 10.5.4
info · registry-verified · 2018-07-28 · 8y ago
BURST
5 releases in 2m: 6.0.115, 7.0.68, 8.10.23, 9.6.25, 10.5.5
info · registry-verified · 2018-08-01 · 8y ago
BURST
6 releases in 6m: 0.12.20, 4.0.46, 6.0.116, 7.0.69, 8.10.24, 10.5.7
info · registry-verified · 2018-08-06 · 8y ago
BURST
3 releases in 0m: 8.10.25, 9.6.27, 10.5.8
info · registry-verified · 2018-08-11 · 8y ago
BURST
3 releases in 1m: 8.10.26, 9.6.28, 10.7.1
info · registry-verified · 2018-08-15 · 8y ago
BURST
2 releases in 23m: 10.7.2, 10.9.0
info · registry-verified · 2018-08-23 · 8y ago
BURST
3 releases in 0m: 8.10.27, 9.6.29, 10.9.1
info · registry-verified · 2018-08-24 · 8y ago
BURST
3 releases in 0m: 8.10.28, 9.6.30, 10.9.2
info · registry-verified · 2018-08-25 · 7y ago
BURST
6 releases in 0m: 4.0.47, 6.0.117, 7.0.70, 8.10.29, 9.6.31, 10.9.4
info · registry-verified · 2018-08-30 · 7y ago
BURST
2 releases in 0m: 8.10.30, 10.10.2
info · registry-verified · 2018-09-21 · 7y ago
BURST
2 releases in 0m: 9.6.32, 10.10.3
info · registry-verified · 2018-09-22 · 7y ago
BURST
8 releases in 59m: 8.10.33, 9.6.33, 10.11.4, 4.0.48, 6.0.118, 7.0.71, 8.10.34, 9.6.34
info · registry-verified · 2018-10-03 · 7y ago
BURST
2 releases in 0m: 8.10.35, 10.11.5
info · registry-verified · 2018-10-08 · 7y ago
BURST
7 releases in 1m: 0.12.21, 4.9.0, 6.14.0, 7.10.0, 8.10.36, 9.6.35, 10.11.6
info · registry-verified · 2018-10-09 · 7y ago
BURST
7 releases in 1m: 0.12.22, 4.9.1, 6.14.1, 7.10.1, 8.10.37, 9.6.36, 10.12.2
info · registry-verified · 2018-11-01 · 7y ago
BURST
2 releases in 0m: 9.6.37, 10.12.6
info · registry-verified · 2018-11-12 · 7y ago
BURST
2 releases in 3m: 6.14.2, 7.10.2
info · registry-verified · 2018-11-15 · 7y ago
BURST
3 releases in 19m: 8.10.38, 9.6.38, 10.12.8
info · registry-verified · 2018-11-15 · 7y ago
BURST
2 releases in 31m: 9.6.39, 10.12.9
info · registry-verified · 2018-11-15 · 7y ago
BURST
2 releases in 17m: 9.6.40, 10.12.11
info · registry-verified · 2018-11-29 · 7y ago
BURST
4 releases in 35m: 10.12.16, 8.10.39, 9.6.41, 10.12.17
info · registry-verified · 2018-12-18 · 7y ago
BURST
6 releases in 5m: 10.12.24, 9.6.42, 8.10.40, 7.10.3, 6.14.3, 4.9.2
info · registry-verified · 2019-02-08 · 7y ago
BURST
2 releases in 1m: 11.9.0, 10.12.25
info · registry-verified · 2019-02-12 · 7y ago
BURST
2 releases in 1m: 11.9.3, 10.12.26
info · registry-verified · 2019-02-12 · 7y ago
BURST
2 releases in 1m: 11.9.5, 10.12.27
info · registry-verified · 2019-02-22 · 7y ago
BURST
15 releases in 40m: 11.10.1, 10.12.28, 9.6.43, 8.10.41, 7.10.4, 6.14.4, 4.9.3, 0.12.23, 11.10.2, 11.10.3, 11.10.4, 10.12.29, 9.6.44, 8.10.42, 7.10.5
info · registry-verified · 2019-03-02 · 7y ago
BURST
4 releases in 1m: 11.10.5, 10.12.30, 9.6.45, 8.10.43
info · registry-verified · 2019-03-06 · 7y ago
BURST
2 releases in 5m: 11.10.6, 11.11.0
info · registry-verified · 2019-03-08 · 7y ago
BURST
2 releases in 13m: 11.11.2, 10.14.0
info · registry-verified · 2019-03-12 · 7y ago
BURST
4 releases in 1m: 11.11.3, 10.14.1, 9.6.46, 8.10.44
info · registry-verified · 2019-03-12 · 7y ago
BURST
2 releases in 1m: 11.11.5, 10.14.2
info · registry-verified · 2019-03-21 · 7y ago
BURST
4 releases in 4m: 11.11.6, 10.14.3, 9.6.47, 8.10.45
info · registry-verified · 2019-03-22 · 7y ago
BURST
2 releases in 1m: 11.11.7, 10.14.4
info · registry-verified · 2019-03-25 · 7y ago
BURST
3 releases in 15m: 11.12.3, 11.12.4, 11.13.0
info · registry-verified · 2019-04-01 · 7y ago
BURST
2 releases in 19m: 11.13.3, 11.13.4
info · registry-verified · 2019-04-10 · 7y ago
BURST
4 releases in 4m: 11.13.6, 10.14.5, 8.10.46, 6.14.5
info · registry-verified · 2019-04-19 · 7y ago
BURST
3 releases in 1m: 11.13.8, 10.14.6, 8.10.47
info · registry-verified · 2019-04-26 · 7y ago
BURST
4 releases in 1m: 9.6.48, 8.10.48, 7.10.6, 6.14.6
info · registry-verified · 2019-04-29 · 7y ago
BURST
2 releases in 1m: 12.0.0, 11.13.10
info · registry-verified · 2019-05-03 · 7y ago
BURST
2 releases in 0m: 11.13.11, 10.14.7
info · registry-verified · 2019-05-17 · 7y ago
BURST
2 releases in 1m: 12.0.3, 11.13.12
info · registry-verified · 2019-05-28 · 7y ago
BURST
5 releases in 2m: 12.0.4, 11.13.13, 10.14.8, 9.6.49, 8.10.49
info · registry-verified · 2019-05-30 · 7y ago
BURST
3 releases in 1m: 12.0.8, 11.13.14, 10.14.9
info · registry-verified · 2019-06-11 · 7y ago
BURST
4 releases in 5m: 12.0.9, 12.0.10, 11.13.15, 10.14.10
info · registry-verified · 2019-06-21 · 7y ago
BURST
7 releases in 42m: 12.0.11, 11.13.16, 10.14.11, 8.10.50, 12.0.12, 11.13.17, 10.14.12
info · registry-verified · 2019-07-03 · 7y ago
BURST
8 releases in 38m: 12.6.7, 11.13.18, 10.14.13, 9.6.50, 8.10.51, 7.10.7, 6.14.7, 12.6.8
info · registry-verified · 2019-07-17 · 7y ago
BURST
3 releases in 9m: 12.7.1, 11.13.19, 10.14.15
info · registry-verified · 2019-08-07 · 7y ago
BURST
3 releases in 0m: 10.14.16, 9.6.51, 8.10.52
info · registry-verified · 2019-08-20 · 7y ago
BURST
4 releases in 1m: 12.7.3, 11.13.20, 10.14.17, 8.10.53
info · registry-verified · 2019-08-30 · 6y ago
BURST
4 releases in 1m: 12.7.5, 10.14.18, 9.6.52, 8.10.54
info · registry-verified · 2019-09-11 · 6y ago
BURST
3 releases in 1m: 12.7.6, 11.13.21, 10.14.19
info · registry-verified · 2019-09-24 · 6y ago
BURST
3 releases in 1m: 12.7.10, 11.13.22, 10.14.20
info · registry-verified · 2019-10-03 · 6y ago
BURST
2 releases in 1m: 12.7.12, 10.14.21
info · registry-verified · 2019-10-08 · 6y ago
BURST
3 releases in 1m: 12.11.1, 10.14.22, 8.10.55
info · registry-verified · 2019-10-15 · 6y ago
BURST
3 releases in 37m: 12.11.3, 12.11.4, 12.11.5
info · registry-verified · 2019-10-22 · 6y ago
BURST
2 releases in 1m: 12.11.6, 11.13.23
info · registry-verified · 2019-10-23 · 6y ago
BURST
9 releases in 7m: 12.11.7, 11.15.0, 10.17.0, 9.6.53, 8.10.56, 7.10.8, 6.14.8, 4.9.4, 0.12.24
info · registry-verified · 2019-10-24 · 6y ago
BURST
12 releases in 29m: 12.12.2, 11.15.1, 10.17.1, 9.6.54, 8.10.57, 7.10.9, 6.14.9, 12.12.3, 11.15.2, 10.17.2, 9.6.55, 8.10.58
info · registry-verified · 2019-10-30 · 6y ago
BURST
2 releases in 1m: 12.12.4, 10.17.3
info · registry-verified · 2019-11-01 · 6y ago
BURST
2 releases in 1m: 12.12.6, 10.17.4
info · registry-verified · 2019-11-05 · 6y ago
BURST
3 releases in 1m: 12.12.7, 10.17.5, 8.10.59
info · registry-verified · 2019-11-08 · 6y ago
BURST
2 releases in 33m: 12.12.10, 12.12.11
info · registry-verified · 2019-11-19 · 6y ago
BURST
4 releases in 53m: 12.12.13, 11.15.3, 10.17.6, 12.12.14
info · registry-verified · 2019-11-25 · 6y ago
BURST
2 releases in 1m: 12.12.15, 10.17.7
info · registry-verified · 2019-12-09 · 6y ago
BURST
2 releases in 1m: 12.12.16, 10.17.8
info · registry-verified · 2019-12-09 · 6y ago
BURST
2 releases in 1m: 12.12.17, 10.17.9
info · registry-verified · 2019-12-10 · 6y ago
BURST
2 releases in 1m: 12.12.19, 10.17.10
info · registry-verified · 2019-12-17 · 6y ago
BURST
2 releases in 1m: 12.12.20, 10.17.11
info · registry-verified · 2019-12-17 · 6y ago
BURST
3 releases in 5m: 13.1.0, 12.12.22, 10.17.12
info · registry-verified · 2019-12-23 · 6y ago
BURST
2 releases in 1m: 13.1.1, 10.17.13
info · registry-verified · 2019-12-26 · 6y ago
BURST
4 releases in 6m: 13.1.3, 13.1.4, 12.12.24, 11.15.4
info · registry-verified · 2020-01-03 · 6y ago
BURST
2 releases in 1m: 13.1.8, 12.12.25
info · registry-verified · 2020-01-17 · 6y ago
BURST
4 releases in 2m: 13.5.1, 12.12.26, 11.15.5, 10.17.14
info · registry-verified · 2020-01-28 · 6y ago
BURST
4 releases in 2m: 13.7.1, 12.12.27, 11.15.6, 10.17.15
info · registry-verified · 2020-02-11 · 6y ago
BURST
5 releases in 11m: 13.7.3, 13.7.4, 12.12.28, 11.15.7, 10.17.16
info · registry-verified · 2020-02-19 · 6y ago
BURST
3 releases in 1m: 13.7.7, 12.12.29, 10.17.17
info · registry-verified · 2020-02-28 · 6y ago
BURST
2 releases in 5m: 13.9.1, 12.12.30
info · registry-verified · 2020-03-13 · 6y ago
BURST
2 releases in 34m: 13.9.4, 12.12.31
info · registry-verified · 2020-03-25 · 6y ago
BURST
3 releases in 1m: 13.9.5, 12.12.32, 11.15.8
info · registry-verified · 2020-03-27 · 6y ago
BURST
3 releases in 1m: 13.9.6, 12.12.33, 11.15.9
info · registry-verified · 2020-03-30 · 6y ago
BURST
4 releases in 29m: 13.9.7, 12.12.34, 10.17.18, 13.9.8
info · registry-verified · 2020-03-30 · 6y ago
BURST
4 releases in 1m: 13.11.1, 12.12.35, 11.15.10, 10.17.19
info · registry-verified · 2020-04-08 · 6y ago
BURST
3 releases in 1m: 8.10.60, 7.10.10, 6.14.10
info · registry-verified · 2020-04-13 · 6y ago
BURST
4 releases in 2m: 13.13.0, 12.12.36, 11.15.11, 10.17.20
info · registry-verified · 2020-04-17 · 6y ago
BURST
4 releases in 2m: 13.13.2, 12.12.37, 11.15.12, 10.17.21
info · registry-verified · 2020-04-22 · 6y ago
BURST
2 releases in 1m: 13.13.5, 12.12.38
info · registry-verified · 2020-05-05 · 6y ago
BURST
4 releases in 39m: 14.0.0, 13.13.6, 14.0.1, 12.12.39
info · registry-verified · 2020-05-12 · 6y ago
BURST
10 releases in 48m: 14.0.2, 10.17.22, 14.0.3, 12.12.40, 11.15.13, 10.17.23, 9.6.56, 8.10.61, 7.10.11, 13.13.7
info · registry-verified · 2020-05-19 · 6y ago
BURST
5 releases in 2m: 14.0.4, 13.13.8, 12.12.41, 11.15.14, 10.17.24
info · registry-verified · 2020-05-19 · 6y ago
BURST
3 releases in 1m: 14.0.5, 13.13.9, 12.12.42
info · registry-verified · 2020-05-21 · 6y ago
BURST
4 releases in 57m: 14.0.7, 14.0.8, 12.12.43, 14.0.9
info · registry-verified · 2020-06-01 · 6y ago
BURST
3 releases in 1m: 14.0.11, 13.13.10, 12.12.44
info · registry-verified · 2020-06-04 · 6y ago
BURST
5 releases in 2m: 14.0.12, 13.13.11, 12.12.45, 11.15.15, 10.17.25
info · registry-verified · 2020-06-08 · 6y ago
BURST
5 releases in 2m: 14.0.13, 13.13.12, 12.12.47, 11.15.16, 10.17.26
info · registry-verified · 2020-06-09 · 6y ago
BURST
7 releases in 14m: 14.0.15, 14.0.16, 13.13.13, 14.0.17, 12.12.48, 11.15.17, 14.0.18
info · registry-verified · 2020-07-06 · 6y ago
BURST
5 releases in 2m: 14.0.21, 13.13.14, 12.12.49, 11.15.18, 10.17.27
info · registry-verified · 2020-07-10 · 6y ago
BURST
2 releases in 1m: 14.0.24, 12.12.51
info · registry-verified · 2020-07-20 · 6y ago
BURST
7 releases in 3m: 14.0.25, 13.13.15, 12.12.52, 11.15.19, 10.17.28, 9.6.57, 8.10.62
info · registry-verified · 2020-07-23 · 6y ago
BURST
2 releases in 0m: 12.12.53, 11.15.20
info · registry-verified · 2020-07-24 · 6y ago
BURST
9 releases in 4m: 14.6.3, 13.13.16, 12.12.55, 11.15.21, 10.17.29, 9.6.58, 8.10.63, 7.10.12, 6.14.11
info · registry-verified · 2020-09-02 · 5y ago
BURST
4 releases in 1m: 13.13.17, 12.12.56, 11.15.22, 10.17.30
info · registry-verified · 2020-09-08 · 5y ago
BURST
5 releases in 2m: 14.10.0, 13.13.18, 12.12.57, 11.15.23, 10.17.31
info · registry-verified · 2020-09-10 · 5y ago
BURST
5 releases in 2m: 14.10.1, 13.13.19, 12.12.58, 11.15.24, 10.17.32
info · registry-verified · 2020-09-11 · 5y ago
BURST
6 releases in 49m: 10.17.33, 14.10.2, 13.13.20, 12.12.59, 11.15.25, 10.17.34
info · registry-verified · 2020-09-15 · 5y ago
BURST
9 releases in 4m: 14.10.3, 13.13.21, 12.12.60, 11.15.26, 10.17.35, 9.6.59, 8.10.64, 7.10.13, 6.14.12
info · registry-verified · 2020-09-16 · 5y ago
BURST
2 releases in 0m: 12.12.61, 11.15.27
info · registry-verified · 2020-09-16 · 5y ago
BURST
3 releases in 35m: 14.11.0, 12.12.62, 14.11.1
info · registry-verified · 2020-09-17 · 5y ago
BURST
5 releases in 2m: 14.11.4, 13.13.22, 12.12.63, 11.15.28, 10.17.36
info · registry-verified · 2020-10-06 · 5y ago
BURST
5 releases in 2m: 14.11.5, 13.13.23, 12.12.64, 11.15.29, 10.17.37
info · registry-verified · 2020-10-06 · 5y ago
BURST
5 releases in 2m: 14.11.6, 13.13.24, 12.12.65, 11.15.30, 10.17.38
info · registry-verified · 2020-10-08 · 5y ago
BURST
2 releases in 1m: 14.11.7, 12.12.66
info · registry-verified · 2020-10-08 · 5y ago
BURST
5 releases in 2m: 14.11.8, 13.13.25, 12.12.67, 11.15.31, 10.17.39
info · registry-verified · 2020-10-09 · 5y ago
BURST
11 releases in 4m: 14.11.9, 13.13.26, 12.12.68, 11.15.32, 10.17.40, 9.6.60, 8.10.65, 7.10.14, 6.14.13, 4.9.5, 0.12.25
info · registry-verified · 2020-10-16 · 5y ago
BURST
3 releases in 1m: 14.14.0, 13.13.27, 12.12.69
info · registry-verified · 2020-10-20 · 5y ago
BURST
3 releases in 1m: 14.14.1, 12.12.70, 10.17.41
info · registry-verified · 2020-10-21 · 5y ago
BURST
5 releases in 2m: 14.14.2, 13.13.28, 12.19.0, 11.15.33, 10.17.42
info · registry-verified · 2020-10-21 · 5y ago
BURST
6 releases in 10m: 14.14.4, 14.14.5, 13.13.29, 12.19.2, 11.15.34, 10.17.43
info · registry-verified · 2020-10-26 · 5y ago
BURST
7 releases in 3m: 14.14.6, 13.13.30, 12.19.3, 11.15.35, 10.17.44, 9.6.61, 8.10.66
info · registry-verified · 2020-10-28 · 5y ago
BURST
2 releases in 1m: 14.14.7, 12.19.4
info · registry-verified · 2020-11-09 · 5y ago
BURST
5 releases in 2m: 14.14.8, 13.13.31, 12.19.5, 11.15.36, 10.17.45
info · registry-verified · 2020-11-17 · 5y ago
BURST
5 releases in 2m: 14.14.9, 13.13.32, 12.19.6, 11.15.37, 10.17.46
info · registry-verified · 2020-11-19 · 5y ago
BURST
5 releases in 2m: 14.14.10, 13.13.33, 12.19.7, 11.15.38, 10.17.47
info · registry-verified · 2020-11-25 · 5y ago
BURST
4 releases in 1m: 13.13.34, 12.19.8, 11.15.39, 10.17.48
info · registry-verified · 2020-11-30 · 5y ago
BURST
2 releases in 1m: 14.14.11, 13.13.35
info · registry-verified · 2020-12-08 · 5y ago
BURST
5 releases in 2m: 14.14.13, 13.13.36, 12.19.9, 11.15.40, 10.17.49
info · registry-verified · 2020-12-12 · 5y ago
BURST
9 releases in 13m: 14.14.15, 13.13.37, 12.19.10, 11.15.41, 14.14.16, 13.13.38, 12.19.11, 11.15.42, 10.17.50
info · registry-verified · 2020-12-23 · 5y ago
BURST
2 releases in 33m: 14.14.18, 14.14.19
info · registry-verified · 2021-01-01 · 5y ago
BURST
4 releases in 2m: 14.14.20, 13.13.39, 12.19.12, 11.15.43
info · registry-verified · 2021-01-04 · 5y ago
BURST
5 releases in 2m: 14.14.21, 13.13.40, 12.19.14, 11.15.44, 10.17.51
info · registry-verified · 2021-01-14 · 5y ago
BURST
3 releases in 50m: 14.14.23, 13.13.41, 14.14.24
info · registry-verified · 2021-02-03 · 5y ago
BURST
2 releases in 1m: 14.14.25, 12.19.16
info · registry-verified · 2021-02-04 · 5y ago
BURST
2 releases in 1m: 14.14.27, 12.20.0
info · registry-verified · 2021-02-12 · 5y ago
BURST
5 releases in 2m: 14.14.28, 13.13.42, 12.20.1, 11.15.45, 10.17.52
info · registry-verified · 2021-02-14 · 5y ago
BURST
5 releases in 2m: 14.14.29, 13.13.43, 12.20.2, 11.15.46, 10.17.53
info · registry-verified · 2021-02-18 · 5y ago
BURST
3 releases in 1m: 14.14.30, 13.13.44, 12.20.3
info · registry-verified · 2021-02-19 · 5y ago
BURST
5 releases in 2m: 14.14.31, 13.13.45, 12.20.4, 11.15.47, 10.17.54
info · registry-verified · 2021-02-19 · 5y ago
BURST
2 releases in 0m: 11.15.48, 10.17.55
info · registry-verified · 2021-03-07 · 5y ago
BURST
3 releases in 2m: 14.14.33, 13.13.46, 12.20.5
info · registry-verified · 2021-03-09 · 5y ago
BURST
4 releases in 2m: 14.14.35, 13.13.47, 12.20.6, 11.15.49
info · registry-verified · 2021-03-15 · 5y ago
BURST
5 releases in 2m: 14.14.37, 13.13.48, 12.20.7, 11.15.50, 10.17.56
info · registry-verified · 2021-03-27 · 5y ago
BURST
6 releases in 32m: 14.14.38, 14.14.39, 13.13.49, 12.20.8, 11.15.51, 10.17.57
info · registry-verified · 2021-04-14 · 5y ago
BURST
5 releases in 2m: 14.14.41, 13.13.50, 12.20.9, 11.15.52, 10.17.58
info · registry-verified · 2021-04-15 · 5y ago
BURST
2 releases in 1m: 15.0.0, 14.14.42
info · registry-verified · 2021-04-26 · 5y ago
BURST
6 releases in 2m: 15.0.1, 14.14.43, 13.13.51, 12.20.11, 11.15.53, 10.17.59
info · registry-verified · 2021-04-27 · 5y ago
BURST
3 releases in 1m: 15.0.2, 14.14.44, 12.20.12
info · registry-verified · 2021-05-04 · 5y ago
BURST
6 releases in 2m: 15.0.3, 14.14.45, 13.13.52, 12.20.13, 11.15.54, 10.17.60
info · registry-verified · 2021-05-12 · 5y ago
BURST
2 releases in 1m: 15.6.1, 14.17.1
info · registry-verified · 2021-05-25 · 5y ago
BURST
3 releases in 1m: 15.6.2, 14.17.2, 12.20.14
info · registry-verified · 2021-06-02 · 5y ago
BURST
3 releases in 1m: 15.12.2, 14.17.3, 12.20.15
info · registry-verified · 2021-06-07 · 5y ago
BURST
2 releases in 1m: 16.0.0, 15.14.1
info · registry-verified · 2021-07-03 · 5y ago
BURST
3 releases in 1m: 16.0.1, 14.17.5, 12.20.16
info · registry-verified · 2021-07-07 · 5y ago
BURST
2 releases in 1m: 16.3.1, 15.14.2
info · registry-verified · 2021-07-09 · 5y ago
BURST
4 releases in 1m: 16.4.2, 15.14.3, 14.17.6, 12.20.17
info · registry-verified · 2021-07-24 · 5y ago
BURST
2 releases in 1m: 16.4.6, 15.14.4
info · registry-verified · 2021-07-28 · 5y ago
BURST
4 releases in 1m: 16.4.10, 15.14.5, 14.17.7, 12.20.18
info · registry-verified · 2021-08-01 · 5y ago
BURST
3 releases in 1m: 16.4.11, 15.14.6, 14.17.8
info · registry-verified · 2021-08-04 · 5y ago
BURST
4 releases in 2m: 16.4.12, 15.14.7, 14.17.9, 12.20.19
info · registry-verified · 2021-08-04 · 5y ago
BURST
3 releases in 1m: 16.6.2, 15.14.8, 14.17.10
info · registry-verified · 2021-08-18 · 5y ago
BURST
4 releases in 1m: 16.7.1, 15.14.9, 14.17.11, 12.20.20
info · registry-verified · 2021-08-21 · 5y ago
BURST
3 releases in 1m: 16.7.2, 14.17.12, 12.20.21
info · registry-verified · 2021-08-26 · 4y ago
BURST
3 releases in 1m: 16.7.9, 14.17.13, 12.20.22
info · registry-verified · 2021-08-31 · 4y ago
BURST
3 releases in 1m: 16.7.10, 14.17.14, 12.20.23
info · registry-verified · 2021-08-31 · 4y ago
BURST
3 releases in 1m: 16.7.13, 14.17.15, 12.20.24
info · registry-verified · 2021-09-07 · 4y ago
BURST
2 releases in 0m: 14.17.16, 12.20.25
info · registry-verified · 2021-09-14 · 4y ago
BURST
2 releases in 1m: 16.9.2, 14.17.17
info · registry-verified · 2021-09-16 · 4y ago
BURST
4 releases in 29m: 16.9.5, 14.17.18, 12.20.26, 16.9.6
info · registry-verified · 2021-09-21 · 4y ago
BURST
3 releases in 1m: 16.10.1, 14.17.19, 12.20.27
info · registry-verified · 2021-09-25 · 4y ago
BURST
2 releases in 1m: 16.10.2, 14.17.20
info · registry-verified · 2021-09-29 · 4y ago
BURST
3 releases in 1m: 16.10.3, 14.17.21, 12.20.28
info · registry-verified · 2021-10-05 · 4y ago
BURST
3 releases in 1m: 16.10.4, 14.17.22, 12.20.29
info · registry-verified · 2021-10-12 · 4y ago
BURST
4 releases in 60m: 16.10.6, 14.17.23, 12.20.30, 16.10.7
info · registry-verified · 2021-10-13 · 4y ago
BURST
3 releases in 60m: 14.17.24, 12.20.31, 16.10.8
info · registry-verified · 2021-10-13 · 4y ago
BURST
2 releases in 0m: 14.17.25, 12.20.32
info · registry-verified · 2021-10-13 · 4y ago
BURST
3 releases in 1m: 16.10.9, 14.17.26, 12.20.33
info · registry-verified · 2021-10-13 · 4y ago
BURST
2 releases in 1m: 16.11.0, 14.17.27
info · registry-verified · 2021-10-14 · 4y ago
BURST
2 releases in 1m: 16.11.3, 14.17.28
info · registry-verified · 2021-10-22 · 4y ago
BURST
3 releases in 1m: 16.11.4, 14.17.29, 12.20.34
info · registry-verified · 2021-10-22 · 4y ago
BURST
3 releases in 1m: 16.11.5, 14.17.30, 12.20.35
info · registry-verified · 2021-10-25 · 4y ago
BURST
3 releases in 1m: 16.11.6, 14.17.32, 12.20.36
info · registry-verified · 2021-10-25 · 4y ago
BURST
3 releases in 1m: 16.11.7, 14.17.33, 12.20.37
info · registry-verified · 2021-11-08 · 4y ago
BURST
2 releases in 1m: 16.11.8, 14.17.34
info · registry-verified · 2021-11-18 · 4y ago
BURST
2 releases in 1m: 17.0.0, 16.11.14
info · registry-verified · 2021-12-15 · 4y ago
BURST
4 releases in 2m: 17.0.2, 16.11.15, 14.18.2, 12.20.38
info · registry-verified · 2021-12-20 · 4y ago
BURST
2 releases in 1m: 17.0.3, 16.11.16
info · registry-verified · 2021-12-23 · 4y ago
BURST
2 releases in 1m: 17.0.4, 16.11.17
info · registry-verified · 2021-12-23 · 4y ago
BURST
3 releases in 1m: 17.0.5, 14.18.3, 12.20.39
info · registry-verified · 2021-12-26 · 4y ago
BURST
3 releases in 1m: 17.0.6, 14.18.4, 12.20.40
info · registry-verified · 2022-01-01 · 4y ago
BURST
2 releases in 1m: 17.0.7, 16.11.18
info · registry-verified · 2022-01-03 · 4y ago
BURST
4 releases in 2m: 17.0.8, 16.11.19, 14.18.5, 12.20.41
info · registry-verified · 2022-01-04 · 4y ago
BURST
4 releases in 2m: 17.0.9, 16.11.20, 14.18.6, 12.20.42
info · registry-verified · 2022-01-17 · 4y ago
BURST
3 releases in 1m: 17.0.10, 16.11.21, 14.18.8
info · registry-verified · 2022-01-18 · 4y ago
BURST
4 releases in 1m: 17.0.14, 16.11.22, 14.18.10, 12.20.43
info · registry-verified · 2022-02-01 · 4y ago
BURST
4 releases in 2m: 17.0.17, 16.11.23, 14.18.11, 12.20.44
info · registry-verified · 2022-02-10 · 4y ago
BURST
4 releases in 2m: 17.0.18, 16.11.25, 14.18.12, 12.20.46
info · registry-verified · 2022-02-14 · 4y ago
BURST
4 releases in 1m: 17.0.24, 16.11.27, 14.18.13, 12.20.48
info · registry-verified · 2022-04-14 · 4y ago
BURST
4 releases in 1m: 17.0.26, 16.11.28, 14.18.14, 12.20.49
info · registry-verified · 2022-04-24 · 4y ago
BURST
3 releases in 1m: 17.0.27, 16.11.29, 14.18.15
info · registry-verified · 2022-04-25 · 4y ago
BURST
2 releases in 1m: 17.0.28, 16.11.30
info · registry-verified · 2022-04-26 · 4y ago
BURST
4 releases in 1m: 17.0.29, 16.11.31, 14.18.16, 12.20.50
info · registry-verified · 2022-04-26 · 4y ago
BURST
2 releases in 1m: 17.0.30, 16.11.32
info · registry-verified · 2022-04-28 · 4y ago
BURST
2 releases in 1m: 17.0.31, 16.11.33
info · registry-verified · 2022-05-01 · 4y ago
BURST
4 releases in 1m: 17.0.32, 16.11.34, 14.18.17, 12.20.51
info · registry-verified · 2022-05-10 · 4y ago
BURST
4 releases in 1m: 17.0.33, 16.11.35, 14.18.18, 12.20.52
info · registry-verified · 2022-05-12 · 4y ago
BURST
2 releases in 1m: 17.0.34, 16.11.36
info · registry-verified · 2022-05-16 · 4y ago
BURST
4 releases in 1m: 17.0.37, 16.11.37, 14.18.19, 12.20.53
info · registry-verified · 2022-05-31 · 4y ago
BURST
4 releases in 1m: 17.0.38, 16.11.38, 14.18.20, 12.20.54
info · registry-verified · 2022-05-31 · 4y ago
BURST
4 releases in 1m: 17.0.41, 16.11.39, 14.18.21, 12.20.55
info · registry-verified · 2022-06-07 · 4y ago
BURST
2 releases in 1m: 17.0.43, 16.11.40
info · registry-verified · 2022-06-14 · 4y ago
BURST
2 releases in 1m: 17.0.44, 16.11.41
info · registry-verified · 2022-06-15 · 4y ago
BURST
2 releases in 1m: 18.0.0, 17.0.45
info · registry-verified · 2022-06-15 · 4y ago
BURST
2 releases in 1m: 18.0.1, 16.11.43
info · registry-verified · 2022-07-03 · 4y ago
BURST
3 releases in 1m: 18.0.4, 16.11.44, 14.18.22
info · registry-verified · 2022-07-13 · 4y ago
BURST
2 releases in 1m: 18.0.5, 16.11.45
info · registry-verified · 2022-07-15 · 4y ago
BURST
2 releases in 1m: 18.6.2, 16.11.46
info · registry-verified · 2022-07-28 · 4y ago
BURST
3 releases in 1m: 18.6.3, 16.11.47, 14.18.23
info · registry-verified · 2022-07-30 · 4y ago
BURST
2 releases in 30m: 18.7.0, 18.7.1
info · registry-verified · 2022-08-10 · 4y ago
BURST
2 releases in 1m: 18.7.2, 16.11.48
info · registry-verified · 2022-08-12 · 4y ago
BURST
3 releases in 1m: 18.7.5, 16.11.49, 14.18.24
info · registry-verified · 2022-08-15 · 4y ago
BURST
2 releases in 1m: 18.7.7, 16.11.50
info · registry-verified · 2022-08-19 · 4y ago
BURST
2 releases in 1m: 18.7.8, 16.11.51
info · registry-verified · 2022-08-19 · 4y ago
BURST
3 releases in 1m: 18.7.9, 16.11.52, 14.18.25
info · registry-verified · 2022-08-21 · 4y ago
BURST
2 releases in 1m: 18.7.10, 16.11.53
info · registry-verified · 2022-08-22 · 4y ago
BURST
3 releases in 1m: 18.7.11, 16.11.54, 14.18.26
info · registry-verified · 2022-08-23 · 4y ago
BURST
2 releases in 1m: 18.7.12, 16.11.56
info · registry-verified · 2022-08-24 · 3y ago
BURST
3 releases in 1m: 18.7.15, 16.11.57, 14.18.27
info · registry-verified · 2022-09-05 · 3y ago
BURST
3 releases in 1m: 18.7.16, 16.11.58, 14.18.28
info · registry-verified · 2022-09-07 · 3y ago
BURST
3 releases in 1m: 18.7.18, 16.11.59, 14.18.29
info · registry-verified · 2022-09-13 · 3y ago
BURST
3 releases in 1m: 18.7.19, 16.11.60, 14.18.30
info · registry-verified · 2022-09-23 · 3y ago
BURST
2 releases in 1m: 18.7.22, 16.11.61
info · registry-verified · 2022-09-26 · 3y ago
BURST
3 releases in 1m: 18.7.23, 16.11.62, 14.18.31
info · registry-verified · 2022-09-26 · 3y ago
BURST
2 releases in 1m: 18.8.0, 16.11.63
info · registry-verified · 2022-10-02 · 3y ago
BURST
2 releases in 1m: 18.8.1, 16.11.64
info · registry-verified · 2022-10-03 · 3y ago
BURST
3 releases in 1m: 18.8.4, 16.11.65, 14.18.32
info · registry-verified · 2022-10-10 · 3y ago
BURST
3 releases in 60m: 18.11.1, 16.11.67, 18.11.2
info · registry-verified · 2022-10-18 · 3y ago
BURST
2 releases in 1m: 18.11.4, 16.18.0
info · registry-verified · 2022-10-23 · 3y ago
BURST
2 releases in 1m: 18.11.6, 16.18.1
info · registry-verified · 2022-10-26 · 3y ago
BURST
3 releases in 1m: 18.11.7, 16.18.2, 14.18.33
info · registry-verified · 2022-10-26 · 3y ago
BURST
2 releases in 1m: 18.11.8, 16.18.3
info · registry-verified · 2022-10-30 · 3y ago
BURST
3 releases in 1m: 18.11.10, 16.18.4, 14.18.34
info · registry-verified · 2022-11-30 · 3y ago
BURST
3 releases in 31m: 16.18.5, 18.11.11, 16.18.6
info · registry-verified · 2022-12-05 · 3y ago
BURST
2 releases in 1m: 18.11.12, 16.18.7
info · registry-verified · 2022-12-08 · 3y ago
BURST
2 releases in 1m: 18.11.13, 16.18.8
info · registry-verified · 2022-12-10 · 3y ago
BURST
2 releases in 1m: 18.11.15, 16.18.9
info · registry-verified · 2022-12-13 · 3y ago
BURST
3 releases in 2m: 18.11.16, 16.18.10, 14.18.35
info · registry-verified · 2022-12-16 · 3y ago
BURST
3 releases in 1m: 18.11.18, 16.18.11, 14.18.36
info · registry-verified · 2022-12-26 · 3y ago
BURST
2 releases in 1m: 18.11.19, 16.18.12
info · registry-verified · 2023-02-04 · 3y ago
BURST
2 releases in 1m: 18.14.2, 16.18.13
info · registry-verified · 2023-02-26 · 3y ago
BURST
3 releases in 1m: 18.14.3, 16.18.14, 14.18.37
info · registry-verified · 2023-03-02 · 3y ago
BURST
2 releases in 1m: 18.15.2, 16.18.15
info · registry-verified · 2023-03-13 · 3y ago
BURST
3 releases in 1m: 18.15.3, 16.18.16, 14.18.38
info · registry-verified · 2023-03-14 · 3y ago
BURST
6 releases in 31m: 18.15.4, 16.18.17, 14.18.39, 18.15.5, 16.18.18, 14.18.40
info · registry-verified · 2023-03-20 · 3y ago
BURST
2 releases in 1m: 18.15.6, 16.18.19
info · registry-verified · 2023-03-23 · 3y ago
BURST
2 releases in 1m: 18.15.8, 16.18.20
info · registry-verified · 2023-03-24 · 3y ago
BURST
3 releases in 1m: 18.15.10, 16.18.21, 14.18.41
info · registry-verified · 2023-03-25 · 3y ago
BURST
3 releases in 1m: 18.15.11, 16.18.22, 14.18.42
info · registry-verified · 2023-03-28 · 3y ago
BURST
2 releases in 1m: 18.15.12, 16.18.24
info · registry-verified · 2023-04-19 · 3y ago
BURST
3 releases in 1m: 18.16.1, 16.18.25, 14.18.43
info · registry-verified · 2023-04-25 · 3y ago
BURST
2 releases in 1m: 20.0.0, 18.16.4
info · registry-verified · 2023-05-05 · 3y ago
BURST
4 releases in 1m: 20.1.0, 18.16.5, 16.18.26, 14.18.45
info · registry-verified · 2023-05-05 · 3y ago
BURST
4 releases in 1m: 20.1.1, 18.16.6, 16.18.27, 14.18.46
info · registry-verified · 2023-05-08 · 3y ago
BURST
3 releases in 2m: 20.1.2, 18.16.7, 16.18.28
info · registry-verified · 2023-05-10 · 3y ago
BURST
3 releases in 1m: 20.1.3, 18.16.8, 16.18.29
info · registry-verified · 2023-05-11 · 3y ago
BURST
4 releases in 1m: 20.1.4, 18.16.9, 16.18.30, 14.18.47
info · registry-verified · 2023-05-13 · 3y ago
BURST
2 releases in 1m: 20.1.5, 18.16.10
info · registry-verified · 2023-05-16 · 3y ago
BURST
2 releases in 2m: 20.1.6, 18.16.11
info · registry-verified · 2023-05-16 · 3y ago
BURST
3 releases in 1m: 20.1.7, 18.16.12, 16.18.31
info · registry-verified · 2023-05-16 · 3y ago
BURST
2 releases in 2m: 20.2.1, 18.16.13
info · registry-verified · 2023-05-18 · 3y ago
BURST
3 releases in 1m: 20.2.2, 18.16.14, 16.18.32
info · registry-verified · 2023-05-21 · 3y ago
BURST
4 releases in 2m: 20.2.4, 18.16.15, 16.18.33, 14.18.48
info · registry-verified · 2023-05-25 · 3y ago
BURST
3 releases in 1m: 20.2.5, 18.16.16, 16.18.34
info · registry-verified · 2023-05-26 · 3y ago
BURST
4 releases in 1m: 20.2.6, 18.16.17, 16.18.35, 14.18.49
info · registry-verified · 2023-06-10 · 3y ago
BURST
4 releases in 2m: 20.3.1, 18.16.18, 16.18.36, 14.18.51
info · registry-verified · 2023-06-13 · 3y ago
BURST
2 releases in 0m: 16.18.37, 14.18.52
info · registry-verified · 2023-06-26 · 3y ago
BURST
4 releases in 1m: 20.3.3, 18.16.19, 16.18.38, 14.18.53
info · registry-verified · 2023-06-30 · 3y ago
BURST
4 releases in 1m: 20.4.3, 18.16.20, 16.18.39, 14.18.54
info · registry-verified · 2023-07-21 · 3y ago
BURST
2 releases in 1m: 20.4.4, 18.17.0
info · registry-verified · 2023-07-22 · 3y ago
BURST
2 releases in 2m: 20.4.5, 18.17.1
info · registry-verified · 2023-07-25 · 3y ago
BURST
2 releases in 2m: 20.4.7, 18.17.2
info · registry-verified · 2023-08-04 · 3y ago
BURST
2 releases in 1m: 20.4.8, 18.17.3
info · registry-verified · 2023-08-05 · 3y ago
BURST
3 releases in 1m: 20.4.9, 18.17.4, 16.18.40
info · registry-verified · 2023-08-08 · 3y ago
BURST
2 releases in 2m: 20.4.10, 18.17.5
info · registry-verified · 2023-08-11 · 3y ago
BURST
2 releases in 30m: 18.17.6, 20.5.1
info · registry-verified · 2023-08-18 · 3y ago
BURST
3 releases in 2m: 20.5.2, 18.17.7, 16.18.42
info · registry-verified · 2023-08-22 · 3y ago
BURST
4 releases in 2m: 20.5.3, 18.17.8, 16.18.43, 14.18.55
info · registry-verified · 2023-08-22 · 3y ago
BURST
4 releases in 6m: 20.5.4, 18.17.9, 16.18.44, 14.18.56
info · registry-verified · 2023-08-23 · 2y ago
BURST
6 releases in 31m: 20.5.5, 18.17.10, 16.18.45, 20.5.6, 18.17.11, 16.18.46
info · registry-verified · 2023-08-24 · 2y ago
BURST
2 releases in 1m: 20.5.7, 18.17.12
info · registry-verified · 2023-08-28 · 2y ago
BURST
4 releases in 1m: 20.5.8, 18.17.13, 16.18.47, 14.18.57
info · registry-verified · 2023-09-01 · 2y ago
BURST
4 releases in 2m: 20.5.9, 18.17.14, 16.18.48, 14.18.58
info · registry-verified · 2023-09-02 · 2y ago
BURST
2 releases in 0m: 16.18.49, 14.18.59
info · registry-verified · 2023-09-08 · 2y ago
BURST
3 releases in 1m: 20.6.0, 18.17.15, 16.18.50
info · registry-verified · 2023-09-08 · 2y ago
BURST
4 releases in 1m: 20.6.1, 18.17.16, 16.18.51, 14.18.60
info · registry-verified · 2023-09-15 · 2y ago
BURST
4 releases in 1m: 20.6.2, 18.17.17, 16.18.52, 14.18.61
info · registry-verified · 2023-09-16 · 2y ago
BURST
4 releases in 2m: 20.6.3, 18.17.18, 16.18.53, 14.18.62
info · registry-verified · 2023-09-20 · 2y ago
BURST
4 releases in 1m: 20.6.4, 18.17.19, 16.18.54, 14.18.63
info · registry-verified · 2023-09-23 · 2y ago
BURST
2 releases in 1m: 20.7.0, 18.18.0
info · registry-verified · 2023-09-25 · 2y ago
BURST
3 releases in 1m: 20.7.2, 18.18.1, 16.18.55
info · registry-verified · 2023-09-29 · 2y ago
BURST
3 releases in 2m: 20.8.1, 18.18.2, 16.18.56
info · registry-verified · 2023-10-02 · 2y ago
BURST
3 releases in 2m: 20.8.2, 18.18.3, 16.18.57
info · registry-verified · 2023-10-02 · 2y ago
BURST
3 releases in 1m: 20.8.3, 18.18.4, 16.18.58
info · registry-verified · 2023-10-06 · 2y ago
BURST
2 releases in 1m: 20.8.5, 18.18.5
info · registry-verified · 2023-10-12 · 2y ago
BURST
3 releases in 1m: 20.8.7, 18.18.6, 16.18.59
info · registry-verified · 2023-10-18 · 2y ago
BURST
2 releases in 2m: 20.8.9, 18.18.7
info · registry-verified · 2023-10-25 · 2y ago
BURST
3 releases in 1m: 20.8.10, 18.18.8, 16.18.60
info · registry-verified · 2023-10-31 · 2y ago
BURST
3 releases in 1m: 20.9.0, 18.18.9, 16.18.61
info · registry-verified · 2023-11-07 · 2y ago
BURST
3 releases in 1m: 20.9.2, 18.18.10, 16.18.62
info · registry-verified · 2023-11-18 · 2y ago
BURST
3 releases in 1m: 20.9.3, 18.18.11, 16.18.63
info · registry-verified · 2023-11-21 · 2y ago
BURST
3 releases in 1m: 20.9.4, 18.18.12, 16.18.64
info · registry-verified · 2023-11-22 · 2y ago
BURST
3 releases in 1m: 20.9.5, 18.18.13, 16.18.65
info · registry-verified · 2023-11-23 · 2y ago
BURST
3 releases in 1m: 20.10.1, 18.18.14, 16.18.66
info · registry-verified · 2023-11-29 · 2y ago
BURST
2 releases in 1m: 20.10.2, 18.19.1
info · registry-verified · 2023-12-01 · 2y ago
BURST
3 releases in 1m: 20.10.3, 18.19.2, 16.18.67
info · registry-verified · 2023-12-03 · 2y ago
BURST
3 releases in 2m: 20.10.4, 18.19.3, 16.18.68
info · registry-verified · 2023-12-07 · 2y ago
BURST
3 releases in 2m: 20.10.6, 18.19.4, 16.18.69
info · registry-verified · 2023-12-30 · 2y ago
BURST
3 releases in 1m: 20.10.7, 18.19.5, 16.18.70
info · registry-verified · 2024-01-07 · 2y ago
BURST
2 releases in 5m: 20.10.8, 18.19.6
info · registry-verified · 2024-01-09 · 2y ago
BURST
3 releases in 2m: 20.11.1, 18.19.7, 16.18.71
info · registry-verified · 2024-01-15 · 2y ago
BURST
2 releases in 1m: 20.11.5, 18.19.8
info · registry-verified · 2024-01-17 · 2y ago
BURST
3 releases in 1m: 20.11.6, 18.19.9, 16.18.75
info · registry-verified · 2024-01-24 · 2y ago
BURST
3 releases in 1m: 20.11.7, 18.19.10, 16.18.76
info · registry-verified · 2024-01-26 · 2y ago
BURST
3 releases in 1m: 20.11.12, 18.19.11, 16.18.77
info · registry-verified · 2024-01-30 · 2y ago
BURST
3 releases in 2m: 20.11.14, 18.19.12, 16.18.78
info · registry-verified · 2024-01-31 · 2y ago
BURST
2 releases in 1m: 20.11.15, 18.19.13
info · registry-verified · 2024-02-01 · 2y ago
BURST
3 releases in 1m: 20.11.16, 18.19.14, 16.18.79
info · registry-verified · 2024-02-01 · 2y ago
BURST
3 releases in 2m: 20.11.17, 18.19.15, 16.18.80
info · registry-verified · 2024-02-08 · 2y ago
BURST
3 releases in 2m: 20.11.18, 18.19.16, 16.18.81
info · registry-verified · 2024-02-15 · 2y ago
BURST
3 releases in 2m: 20.11.19, 18.19.17, 16.18.82
info · registry-verified · 2024-02-15 · 2y ago
BURST
3 releases in 2m: 20.11.20, 18.19.18, 16.18.83
info · registry-verified · 2024-02-22 · 2y ago
BURST
3 releases in 2m: 20.11.21, 18.19.19, 16.18.84
info · registry-verified · 2024-02-27 · 2y ago
BURST
3 releases in 2m: 20.11.22, 18.19.20, 16.18.85
info · registry-verified · 2024-02-28 · 2y ago
BURST
3 releases in 2m: 20.11.23, 18.19.21, 16.18.86
info · registry-verified · 2024-02-29 · 2y ago
BURST
3 releases in 2m: 20.11.25, 18.19.22, 16.18.87
info · registry-verified · 2024-03-06 · 2y ago
BURST
3 releases in 2m: 20.11.26, 18.19.23, 16.18.88
info · registry-verified · 2024-03-11 · 2y ago
BURST
3 releases in 2m: 20.11.27, 18.19.24, 16.18.89
info · registry-verified · 2024-03-13 · 2y ago
BURST
3 releases in 2m: 20.11.29, 18.19.25, 16.18.90
info · registry-verified · 2024-03-18 · 2y ago
BURST
3 releases in 2m: 20.11.30, 18.19.26, 16.18.91
info · registry-verified · 2024-03-19 · 2y ago
BURST
7 releases in 60m: 20.12.0, 18.19.27, 16.18.92, 20.12.1, 18.19.28, 16.18.93, 20.12.2
info · registry-verified · 2024-03-30 · 2y ago
BURST
3 releases in 2m: 20.12.3, 18.19.29, 16.18.94
info · registry-verified · 2024-04-02 · 2y ago
BURST
3 releases in 1m: 20.12.5, 18.19.30, 16.18.95
info · registry-verified · 2024-04-05 · 2y ago
BURST
3 releases in 2m: 20.12.6, 18.19.31, 16.18.96
info · registry-verified · 2024-04-09 · 2y ago
BURST
3 releases in 2m: 20.12.10, 18.19.32, 16.18.97
info · registry-verified · 2024-05-06 · 2y ago
BURST
2 releases in 2m: 20.12.11, 18.19.33
info · registry-verified · 2024-05-08 · 2y ago
BURST
2 releases in 36m: 20.12.14, 20.13.0
info · registry-verified · 2024-05-31 · 2y ago
BURST
3 releases in 2m: 20.14.1, 18.19.34, 16.18.98
info · registry-verified · 2024-06-03 · 2y ago
BURST
2 releases in 0m: 20.14.3, 18.19.35
info · registry-verified · 2024-06-17 · 2y ago
BURST
3 releases in 0m: 20.14.4, 18.19.36, 16.18.99
info · registry-verified · 2024-06-17 · 2y ago
BURST
3 releases in 1m: 20.14.6, 18.19.37, 16.18.100
info · registry-verified · 2024-06-19 · 2y ago
BURST
3 releases in 1m: 20.14.7, 18.19.38, 16.18.101
info · registry-verified · 2024-06-20 · 2y ago
BURST
2 releases in 0m: 20.14.8, 18.19.39
info · registry-verified · 2024-06-22 · 2y ago
BURST
3 releases in 1m: 20.14.11, 18.19.40, 16.18.102
info · registry-verified · 2024-07-16 · 2y ago
BURST
2 releases in 0m: 18.19.41, 16.18.103
info · registry-verified · 2024-07-18 · 2y ago
BURST
3 releases in 0m: 20.14.12, 18.19.42, 16.18.104
info · registry-verified · 2024-07-23 · 2y ago
BURST
2 releases in 0m: 22.0.0, 20.14.13
info · registry-verified · 2024-07-28 · 2y ago
BURST
3 releases in 0m: 22.0.3, 20.14.14, 18.19.43
info · registry-verified · 2024-08-02 · 2y ago
BURST
4 releases in 1m: 22.2.0, 20.14.15, 18.19.44, 16.18.105
info · registry-verified · 2024-08-09 · 2y ago
BURST
2 releases in 0m: 22.4.0, 20.15.0
info · registry-verified · 2024-08-16 · 2y ago
BURST
3 releases in 0m: 22.4.1, 20.16.1, 18.19.45
info · registry-verified · 2024-08-19 · 2y ago
BURST
2 releases in 0m: 18.19.46, 16.18.106
info · registry-verified · 2024-08-26 · 1y ago
BURST
3 releases in 0m: 22.5.1, 20.16.2, 18.19.47
info · registry-verified · 2024-08-28 · 1y ago
BURST
3 releases in 1m: 22.5.2, 20.16.3, 18.19.48
info · registry-verified · 2024-09-01 · 1y ago
BURST
4 releases in 1m: 22.5.3, 20.16.4, 18.19.49, 16.18.107
info · registry-verified · 2024-09-04 · 1y ago
BURST
4 releases in 1m: 22.5.4, 20.16.5, 18.19.50, 16.18.108
info · registry-verified · 2024-09-04 · 1y ago
BURST
2 releases in 0m: 22.6.1, 20.16.6
info · registry-verified · 2024-09-23 · 1y ago
BURST
5 releases in 26m: 22.6.2, 20.16.7, 18.19.51, 16.18.109, 22.7.0
info · registry-verified · 2024-09-25 · 1y ago
BURST
4 releases in 1m: 22.7.1, 20.16.8, 18.19.52, 16.18.110
info · registry-verified · 2024-09-25 · 1y ago
BURST
4 releases in 1m: 22.7.2, 20.16.9, 18.19.53, 16.18.111
info · registry-verified · 2024-09-25 · 1y ago
BURST
4 releases in 1m: 22.7.4, 20.16.10, 18.19.54, 16.18.112
info · registry-verified · 2024-09-27 · 1y ago
BURST
4 releases in 1m: 22.7.5, 20.16.11, 18.19.55, 16.18.113
info · registry-verified · 2024-10-07 · 1y ago
BURST
4 releases in 1m: 22.7.6, 20.16.12, 18.19.56, 16.18.114
info · registry-verified · 2024-10-16 · 1y ago
BURST
3 releases in 1m: 22.7.7, 20.16.13, 18.19.57
info · registry-verified · 2024-10-19 · 1y ago
BURST
3 releases in 1m: 22.7.8, 20.16.14, 18.19.58
info · registry-verified · 2024-10-22 · 1y ago
BURST
4 releases in 1m: 22.7.9, 20.16.15, 18.19.59, 16.18.115
info · registry-verified · 2024-10-23 · 1y ago
BURST
2 releases in 0m: 22.8.0, 20.17.1
info · registry-verified · 2024-10-25 · 1y ago
BURST
3 releases in 1m: 22.8.2, 20.17.2, 18.19.60
info · registry-verified · 2024-10-28 · 1y ago
BURST
5 releases in 25m: 22.8.3, 22.8.4, 20.17.3, 18.19.61, 16.18.116
info · registry-verified · 2024-10-29 · 1y ago
BURST
4 releases in 1m: 22.8.5, 20.17.4, 18.19.62, 16.18.117
info · registry-verified · 2024-10-31 · 1y ago
BURST
4 releases in 1m: 22.8.6, 20.17.5, 18.19.63, 16.18.118
info · registry-verified · 2024-10-31 · 1y ago
BURST
4 releases in 1m: 22.8.7, 20.17.6, 18.19.64, 16.18.119
info · registry-verified · 2024-11-03 · 1y ago
BURST
3 releases in 1m: 22.9.3, 20.17.7, 18.19.65
info · registry-verified · 2024-11-23 · 1y ago
BURST
4 releases in 1m: 22.9.4, 20.17.8, 18.19.66, 16.18.120
info · registry-verified · 2024-11-25 · 1y ago
BURST
4 releases in 1m: 22.10.1, 20.17.9, 18.19.67, 16.18.121
info · registry-verified · 2024-11-28 · 1y ago
BURST
4 releases in 1m: 22.10.2, 20.17.10, 18.19.68, 16.18.122
info · registry-verified · 2024-12-11 · 1y ago
BURST
4 releases in 1m: 22.10.3, 20.17.11, 18.19.69, 16.18.123
info · registry-verified · 2025-01-01 · 1y ago
BURST
2 releases in 0m: 20.17.12, 18.19.70
info · registry-verified · 2025-01-06 · 1y ago
BURST
4 releases in 1m: 22.10.7, 20.17.14, 18.19.71, 16.18.124
info · registry-verified · 2025-01-16 · 1y ago
BURST
4 releases in 1m: 22.10.8, 20.17.15, 18.19.73, 16.18.125
info · registry-verified · 2025-01-23 · 1y ago
BURST
3 releases in 1m: 22.10.9, 20.17.16, 18.19.74
info · registry-verified · 2025-01-23 · 1y ago
BURST
4 releases in 1m: 22.13.1, 20.17.17, 18.19.75, 16.18.126
info · registry-verified · 2025-02-04 · 1y ago
BURST
2 releases in 0m: 22.13.2, 20.17.18
info · registry-verified · 2025-02-13 · 1y ago
BURST
4 releases in 33m: 22.13.3, 22.13.4, 20.17.19, 18.19.76
info · registry-verified · 2025-02-13 · 1y ago
BURST
4 releases in 60m: 22.13.6, 20.17.20, 18.19.77, 22.13.7
info · registry-verified · 2025-02-28 · 1y ago
BURST
2 releases in 0m: 20.17.21, 18.19.78
info · registry-verified · 2025-02-28 · 1y ago
BURST
2 releases in 0m: 22.13.8, 20.17.22
info · registry-verified · 2025-03-01 · 1y ago
BURST
3 releases in 1m: 22.13.9, 20.17.23, 18.19.79
info · registry-verified · 2025-03-03 · 1y ago
BURST
3 releases in 1m: 22.13.10, 20.17.24, 18.19.80
info · registry-verified · 2025-03-08 · 1y ago
BURST
3 releases in 1m: 22.13.11, 20.17.25, 18.19.81
info · registry-verified · 2025-03-21 · 1y ago
BURST
3 releases in 1m: 22.13.12, 20.17.26, 18.19.82
info · registry-verified · 2025-03-24 · 1y ago
BURST
3 releases in 1m: 22.13.13, 20.17.27, 18.19.83
info · registry-verified · 2025-03-24 · 1y ago
BURST
3 releases in 1m: 22.13.14, 20.17.28, 18.19.84
info · registry-verified · 2025-03-27 · 1y ago
BURST
3 releases in 1m: 22.13.15, 20.17.29, 18.19.85
info · registry-verified · 2025-04-01 · 1y ago
BURST
3 releases in 0m: 22.13.17, 20.17.30, 18.19.86
info · registry-verified · 2025-04-01 · 1y ago
BURST
3 releases in 0m: 22.15.2, 20.17.31, 18.19.87
info · registry-verified · 2025-04-25 · 1y ago
BURST
2 releases in 0m: 22.15.3, 20.17.32
info · registry-verified · 2025-04-28 · 1y ago
BURST
6 releases in 30m: 22.15.4, 20.17.33, 18.19.88, 22.15.5, 20.17.34, 18.19.89
info · registry-verified · 2025-05-05 · 1y ago
BURST
9 releases in 59m: 22.15.6, 20.17.35, 18.19.90, 22.15.7, 20.17.36, 18.19.91, 22.15.8, 20.17.37, 18.19.92
info · registry-verified · 2025-05-05 · 1y ago
BURST
3 releases in 1m: 22.15.9, 20.17.38, 18.19.93
info · registry-verified · 2025-05-05 · 1y ago
BURST
6 releases in 45m: 22.15.10, 20.17.39, 18.19.94, 22.15.11, 20.17.40, 18.19.95
info · registry-verified · 2025-05-06 · 1y ago
BURST
3 releases in 0m: 22.15.12, 20.17.41, 18.19.96
info · registry-verified · 2025-05-06 · 1y ago
BURST
2 releases in 0m: 22.15.13, 20.17.42
info · registry-verified · 2025-05-06 · 1y ago
BURST
3 releases in 1m: 22.15.14, 20.17.43, 18.19.97
info · registry-verified · 2025-05-06 · 1y ago
BURST
3 releases in 1m: 22.15.15, 20.17.44, 18.19.98
info · registry-verified · 2025-05-07 · 1y ago
BURST
3 releases in 0m: 22.15.16, 20.17.45, 18.19.99
info · registry-verified · 2025-05-08 · 1y ago
BURST
3 releases in 0m: 22.15.17, 20.17.46, 18.19.100
info · registry-verified · 2025-05-08 · 1y ago
BURST
2 releases in 0m: 22.15.18, 20.17.47
info · registry-verified · 2025-05-14 · 1y ago
BURST
3 releases in 0m: 22.15.19, 20.17.48, 18.19.101
info · registry-verified · 2025-05-19 · 1y ago
BURST
3 releases in 0m: 22.15.20, 20.17.49, 18.19.102
info · registry-verified · 2025-05-20 · 1y ago
BURST
3 releases in 0m: 22.15.21, 20.17.50, 18.19.103
info · registry-verified · 2025-05-20 · 1y ago
BURST
3 releases in 0m: 22.15.22, 20.17.51, 18.19.104
info · registry-verified · 2025-05-27 · 1y ago
BURST
3 releases in 1m: 22.15.24, 20.17.52, 18.19.105
info · registry-verified · 2025-05-28 · 1y ago
BURST
6 releases in 26m: 22.15.25, 20.17.53, 18.19.106, 22.15.26, 20.17.54, 18.19.107
info · registry-verified · 2025-05-29 · 1y ago
BURST
3 releases in 0m: 22.15.27, 20.17.55, 18.19.108
info · registry-verified · 2025-05-30 · 1y ago
BURST
3 releases in 0m: 22.15.28, 20.17.56, 18.19.109
info · registry-verified · 2025-05-30 · 1y ago
BURST
3 releases in 0m: 22.15.29, 20.17.57, 18.19.110
info · registry-verified · 2025-05-30 · 1y ago
BURST
3 releases in 1m: 22.15.30, 20.17.58, 18.19.111
info · registry-verified · 2025-06-05 · 1y ago
BURST
2 releases in 0m: 24.0.0, 22.15.31
info · registry-verified · 2025-06-10 · 1y ago
BURST
2 releases in 0m: 24.0.2, 22.15.32
info · registry-verified · 2025-06-16 · 1y ago
BURST
3 releases in 1m: 24.0.3, 20.19.1, 18.19.112
info · registry-verified · 2025-06-16 · 1y ago
BURST
2 releases in 0m: 24.0.4, 22.15.33
info · registry-verified · 2025-06-24 · 1y ago
BURST
4 releases in 0m: 24.0.7, 22.15.34, 20.19.2, 18.19.113
info · registry-verified · 2025-06-28 · 1y ago
BURST
4 releases in 1m: 24.0.9, 22.15.35, 20.19.3, 18.19.114
info · registry-verified · 2025-07-01 · 1y ago
BURST
4 releases in 0m: 24.0.10, 22.16.0, 20.19.4, 18.19.115
info · registry-verified · 2025-07-01 · 1y ago
BURST
4 releases in 0m: 24.0.11, 22.16.1, 20.19.5, 18.19.116
info · registry-verified · 2025-07-08 · 1y ago
BURST
4 releases in 1m: 24.0.12, 22.16.2, 20.19.6, 18.19.117
info · registry-verified · 2025-07-09 · 1y ago
BURST
4 releases in 0m: 24.0.13, 22.16.3, 20.19.7, 18.19.118
info · registry-verified · 2025-07-10 · 1y ago
BURST
4 releases in 0m: 24.0.14, 22.16.4, 20.19.8, 18.19.119
info · registry-verified · 2025-07-15 · 1y ago
BURST
4 releases in 0m: 24.0.15, 22.16.5, 20.19.9, 18.19.120
info · registry-verified · 2025-07-19 · 1y ago
BURST
4 releases in 1m: 24.2.1, 22.17.1, 20.19.10, 18.19.122
info · registry-verified · 2025-08-08 · 1y ago
BURST
4 releases in 0m: 24.3.0, 22.17.2, 20.19.11, 18.19.123
info · registry-verified · 2025-08-15 · 1y ago
BURST
4 releases in 0m: 24.3.1, 22.18.1, 20.19.13, 18.19.124
info · registry-verified · 2025-09-04 · 11mo ago
BURST
2 releases in 0m: 24.3.2, 22.18.2
info · registry-verified · 2025-09-12 · 11mo ago
BURST
3 releases in 0m: 24.3.3, 22.18.3, 20.19.14
info · registry-verified · 2025-09-13 · 11mo ago
BURST
4 releases in 1m: 24.5.0, 22.18.4, 20.19.15, 18.19.125
info · registry-verified · 2025-09-15 · 11mo ago
BURST
4 releases in 0m: 24.5.1, 22.18.5, 20.19.16, 18.19.126
info · registry-verified · 2025-09-16 · 11mo ago
BURST
4 releases in 0m: 24.5.2, 22.18.6, 20.19.17, 18.19.127
info · registry-verified · 2025-09-18 · 11mo ago
BURST
4 releases in 0m: 24.6.0, 22.18.7, 20.19.18, 18.19.128
info · registry-verified · 2025-09-29 · 10mo ago
BURST
4 releases in 0m: 24.6.1, 22.18.8, 20.19.19, 18.19.129
info · registry-verified · 2025-09-30 · 10mo ago
BURST
4 releases in 0m: 24.7.1, 22.18.9, 20.19.20, 18.19.130
info · registry-verified · 2025-10-09 · 10mo ago
BURST
3 releases in 0m: 24.7.2, 22.18.10, 20.19.21
info · registry-verified · 2025-10-11 · 10mo ago
BURST
3 releases in 0m: 24.8.1, 22.18.11, 20.19.22
info · registry-verified · 2025-10-17 · 10mo ago
BURST
3 releases in 0m: 24.9.1, 22.18.12, 20.19.23
info · registry-verified · 2025-10-21 · 10mo ago
BURST
3 releases in 0m: 24.9.2, 22.18.13, 20.19.24
info · registry-verified · 2025-10-28 · 9mo ago
BURST
2 releases in 0m: 24.10.0, 22.19.0
info · registry-verified · 2025-11-03 · 9mo ago
BURST
3 releases in 0m: 24.10.1, 22.19.1, 20.19.25
info · registry-verified · 2025-11-11 · 9mo ago
BURST
3 releases in 0m: 24.10.2, 22.19.2, 20.19.26
info · registry-verified · 2025-12-08 · 8mo ago
BURST
2 releases in 0m: 25.0.0, 24.10.3
info · registry-verified · 2025-12-10 · 8mo ago
BURST
4 releases in 0m: 25.0.2, 24.10.4, 22.19.3, 20.19.27
info · registry-verified · 2025-12-14 · 8mo ago
BURST
7 releases in 43m: 25.0.4, 24.10.5, 22.19.4, 20.19.28, 25.0.5, 24.10.6, 22.19.5
info · registry-verified · 2026-01-10 · 7mo ago
BURST
2 releases in 0m: 25.0.6, 24.10.7
info · registry-verified · 2026-01-10 · 7mo ago
BURST
4 releases in 1m: 25.0.8, 24.10.8, 22.19.6, 20.19.29
info · registry-verified · 2026-01-13 · 7mo ago
BURST
4 releases in 33m: 25.0.9, 24.10.9, 22.19.7, 20.19.30
info · registry-verified · 2026-01-15 · 7mo ago
BURST
3 releases in 0m: 24.10.10, 22.19.8, 20.19.31
info · registry-verified · 2026-02-03 · 6mo ago
BURST
4 releases in 0m: 25.2.1, 24.10.11, 22.19.9, 20.19.32
info · registry-verified · 2026-02-05 · 6mo ago
BURST
4 releases in 1m: 25.2.2, 24.10.12, 22.19.10, 20.19.33
info · registry-verified · 2026-02-08 · 6mo ago
BURST
3 releases in 0m: 25.2.3, 24.10.13, 22.19.11
info · registry-verified · 2026-02-10 · 6mo ago
BURST
4 releases in 1m: 25.3.1, 24.10.14, 22.19.12, 20.19.34
info · registry-verified · 2026-02-26 · 5mo ago
BURST
4 releases in 1m: 25.3.2, 24.10.15, 22.19.13, 20.19.35
info · registry-verified · 2026-02-26 · 5mo ago
BURST
4 releases in 1m: 25.3.4, 24.11.1, 22.19.14, 20.19.36
info · registry-verified · 2026-03-05 · 5mo ago
BURST
4 releases in 1m: 25.3.5, 24.11.2, 22.19.15, 20.19.37
info · registry-verified · 2026-03-06 · 5mo ago
BURST
4 releases in 0m: 25.5.1, 24.12.1, 22.19.16, 20.19.38
info · registry-verified · 2026-04-03 · 4mo ago
BURST
4 releases in 0m: 25.5.2, 24.12.2, 22.19.17, 20.19.39
info · registry-verified · 2026-04-03 · 4mo ago
BURST
4 releases in 0m: 25.6.2, 24.12.3, 22.19.18, 20.19.40
info · registry-verified · 2026-05-07 · 3mo ago
BURST
3 releases in 0m: 24.12.4, 22.19.19, 20.19.41
info · registry-verified · 2026-05-11 · 3mo ago
BURST
4 releases in 0m: 25.9.2, 24.13.1, 22.19.20, 20.19.42
info · registry-verified · 2026-06-05 · 2mo ago
BURST
4 releases in 0m: 25.9.3, 24.13.2, 22.19.21, 20.19.43
info · registry-verified · 2026-06-10 · 2mo ago
BURST
2 releases in 0m: 26.0.0, 25.9.4
info · registry-verified · 2026-06-19 · 2mo ago
BURST
4 releases in 0m: 26.1.1, 25.9.5, 24.13.3, 22.20.1 · ACTIVE
info · registry-verified · 2026-07-08 · 1mo ago
release diff 26.1.2 → 26.2.0
+0 added · -0 removed · ~17 modified
http.d.ts +30 lines · 1 flagged
--- +++ @@ -925,2 +925,32 @@         /**+         * Sends an arbitrary HTTP/1.1 1xx informational response to the client. This+         * is a generic equivalent of `response.writeContinue()`,+         * `response.writeProcessing()` and `response.writeEarlyHints()`, and+         * can be called multiple times before the final response. After the final+         * response headers have been sent (via `response.writeHead()` or an+         * implicit header), calling this method throws `ERR_HTTP_HEADERS_SENT`.+         *+         * Clients receive these responses via the [`'information'`](https://nodejs.org/docs/latest-v26.x/api/http.html#event-information)+         * event on `http.ClientRequest`.+         *+         * ```js+         * response.writeInformation(110, { 'X-Progress': '50%' });+         * ```+         * @since v26.2.0+         * @param statusCode An HTTP 1xx informational status code, between `100`+         * and `199` inclusive, excluding `101` (Switching Protocols) which is only+         * available through the [`'upgrade'`](https://nodejs.org/docs/latest-v26.x/api/http.html#event-upgrade) event.+         * @param headers An optional set of headers to send with the+         * informational response. Accepts the same shapes as+         * `response.writeHead()`.+         * @param callback Optional, called once the message has been written+         * to the socket.+         */+        writeInformation(+            statusCode: number,+            headers?: OutgoingHttpHeaders | readonly string[],+            callback?: () => void,+        ): void;+        writeInformation(statusCode: number, callback: () => void): void;+        /**          * Sends a HTTP/1.1 102 Processing message to the client, indicating that
quic.d.ts +1072 lines · 1 flagged
--- +++ @@ -1,5 +1,8 @@ declare module "node:quic" {-    import { KeyObject, webcrypto } from "node:crypto";+    import { NonSharedBuffer } from "node:buffer";+    import { KeyObject } from "node:crypto";+    import { FileHandle } from "node:fs/promises";     import { SocketAddress } from "node:net";-    import { ReadableStream } from "node:stream/web";+    import { Writer } from "node:stream/iter";+    import { EphemeralKeyInfo, PeerCertificate } from "node:tls";     /**@@ -15,3 +18,3 @@      */-    type OnDatagramCallback = (this: QuicSession, datagram: Uint8Array, early: boolean) => void;+    type OnDatagramCallback = (this: QuicSession, datagram: NodeJS.NonSharedUint8Array, early: boolean) => void;     /**@@ -19,3 +22,7 @@      */-    type OnDatagramStatusCallback = (this: QuicSession, id: bigint, status: "lost" | "acknowledged") => void;+    type OnDatagramStatusCallback = (+        this: QuicSession,+        id: bigint,+        status: "acknowledged" | "lost" | "abandoned",+    ) => void;     /**@@ -28,4 +35,4 @@         newRemoteAddress: SocketAddress,-        oldLocalAddress: SocketAddress,-        oldRemoteAddress: SocketAddress,+        oldLocalAddress: SocketAddress | null,+        oldRemoteAddress: SocketAddress | null,         preferredAddress: boolean,@@ -48,12 +55,28 @@      */-    type OnHandshakeCallback = (-        this: QuicSession,-        sni: string,-        alpn: string,-        cipher: string,-        cipherVersion: string,-        validationErrorReason: string,-        validationErrorCode: number,-        earlyDataAccepted: boolean,-    ) => void;+    type OnHandshakeCallback = (this: QuicSession, info: SessionHandshakeInfo) => void;+    /**+     * @since v26.2.0+     */+    type OnNewTokenCallback = (this: QuicSession, token: NonSharedBuffer, address: SocketAddress) => void;+    /**+     * @since v26.2.0+     */+    type OnOriginCallback = (this: QuicSession, origins: string[]) => void;+    /**+     * Called when TLS key material is available. Only fires when+     * `sessionOptions.keylog` is `true`. Multiple lines are emitted during the+     * TLS 1.3 handshake, each containing a secret label, the client random, and+     * the secret value.+     * @since v26.2.0+     */+    type OnKeylogCallback = (this: QuicSession, line: string) => void;+    /**+     * Called when qlog diagnostic data is available. Only fires when+     * `sessionOptions.qlog` is `true`. The `data` chunks should be+     * concatenated in order to produce the complete qlog output. When `fin` is+     * `true`, no more chunks will be emitted and the concatenated result is a+     * complete JSON-SEQ document.+     * @since v26.2.0+     */+    type OnQlogCallback = (this: QuicSession, data: string, fin: boolean) => void;     /**@@ -67,2 +90,20 @@     /**+     * Called when initial request or response headers are received. For HTTP/3,+     * this delivers request pseudo-headers on the server and response headers+     * on the client.+     * @since v26.2.0+     */+    type OnHeadersCallback = (this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void;+    /**+     * Called when trailing headers are received from the peer.+     * @since v26.2.0+     */+    type OnTrailersCallback = (this: QuicStream, trailers: NodeJS.Dict<string | string[]>) => void;+    /**+     * Called when informational (1xx) headers are received from the server+     * (e.g., 103 Early Hints).+     * @since v26.2.0+     */+    type OnInfoCallback = (this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void;+    /**      * @since v23.8.0@@ -71,3 +112,3 @@         /**-         * The preferred IPv4 address to advertise.+         * The preferred IPv4 address to advertise (only used by servers).          * @since v23.8.0@@ -76,3 +117,3 @@         /**-         * The preferred IPv6 address to advertise.+         * The preferred IPv6 address to advertise (only used by servers)          * @since v23.8.0@@ -121,2 +162,7 @@         /**+         * The maximum size in bytes of a DATAGRAM frame payload that this endpoint+         * is willing to receive. Set to `0` to disable datagram support. The peer+         * will not send datagrams larger than this value. The actual maximum size of+         * a datagram that can be _sent_ is determined by the peer's+         * `maxDatagramFrameSize`, not this endpoint's value.          * @since v23.8.0@@ -126,7 +172,60 @@     interface SNIEntry {+        /**+         * The TLS private keys. **Required.**+         */         keys: KeyObject | readonly KeyObject[];+        /**+         * The TLS certificates. **Required.**+         */         certs: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView>;-        ca?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView> | undefined;-        crl?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView> | undefined;+        /**+         * Verify the private key. Default: `false`.+         */         verifyPrivateKey?: boolean | undefined;+        /**+         * The port to advertise in ORIGIN frames (RFC 9412) for this host name. **Default:** `443`. Only used for HTTP/3 sessions.+         */+        port?: number | undefined;+        /**+         * Whether to include this host name in ORIGIN frames. **Default:** `true`. Set to `false` to exclude a host name+         * from ORIGIN advertisements. Wildcard (`'*'`) entries are always excluded regardless of this setting.+         */+        authoritative?: boolean | undefined;+    }+    interface ApplicationOptions {+        /**+         * Maximum number of header name-value pairs accepted per header block. Headers beyond this limit are silently+         * dropped. **Default:** `128`+         */+        maxHeaderPairs?: number | undefined;+        /**+         * Maximum total byte length of all header names and values combined per header block. Headers that would push+         * the total over this limit are silently dropped. **Default:** `8192`+         */+        maxHeaderLength?: number | undefined;+        /**+         * Maximum size of a compressed header field section (QPACK). `0` means unlimited. **Default:** `0`+         */+        maxFieldSectionSize?: number | undefined;+        /**+         * QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic table. **Default:** `4096`+         */+        qpackMaxDTableCapacity?: number | undefined;+        /**+         * QPACK encoder maximum dynamic table capacity. **Default:** `4096`+         */+        qpackEncoderMaxDTableCapacity?: number | undefined;+        /**+         * Maximum number of streams that can be blocked waiting for QPACK dynamic table updates.+         * **Default:** `100`+         */+        qpackBlockedStreams?: number | undefined;+        /**+         * Enable the extended CONNECT protocol (RFC 9220). **Default:** `false`+         */+        enableConnectProtocol?: boolean | undefined;+        /**+         * Enable HTTP/3 datagrams (RFC 9297). **Default:** `false`+         */+        enableDatagrams?: boolean | undefined;     }@@ -159,2 +258,8 @@         /**+         * HTTP/3 application-specific options. These only apply when the negotiated+         * ALPN selects the HTTP/3 application (`'h3'`).+         * @since v26.2.0+         */+        application?: ApplicationOptions | undefined;+        /**          * The CA certificates to use for client sessions. For server sessions, CA@@ -190,3 +295,11 @@         /**-         * The list of support TLS 1.3 cipher groups.+         * When `true`, enables TLS 0-RTT early data for this session. Early data+         * allows the client to send application data before the TLS handshake+         * completes, reducing latency on reconnection when a valid session ticket+         * is available. Set to `false` to disable early data support.+         * @since v26.2.0+         */+        enableEarlyData?: boolean | undefined;+        /**+         * The list of supported TLS 1.3 cipher groups.          * @since v23.8.0@@ -195,3 +308,6 @@         /**-         * True to enable TLS keylogging output.+         * When `true`, enables TLS key logging for the session. Key material is+         * delivered to the `session.onkeylog` callback in [NSS Key Log Format](https://udn.realityripple.com/docs/Mozilla/Projects/NSS/Key_Log_Format).+         * Each callback invocation receives a single line of key material. The output+         * can be used with tools such as Wireshark to decrypt captured QUIC traffic.          * @since v23.8.0@@ -233,3 +349,6 @@         /**-         * True if qlog output should be enabled.+         * When `true`, enables [qlog](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) diagnostic output for the session. Qlog data+         * is delivered to the `session.onqlog` callback as chunks of [JSON-SEQ](https://www.rfc-editor.org/rfc/rfc7464)+         * formatted text. The output can be analyzed with qlog visualization tools+         * such as [qvis](https://qvis.quictools.info/).          * @since v23.8.0@@ -243,4 +362,36 @@         /**-         * Specifies the maximum number of milliseconds a TLS handshake is permitted to take-         * to complete before timing out.+         * Controls which datagram to drop when the pending datagram queue+         * (sized by `session.maxPendingDatagrams`) is full. Must be one of+         * `'drop-oldest'` (discard the oldest queued datagram to make room) or+         * `'drop-newest'` (reject the incoming datagram). Dropped datagrams are+         * reported as lost via the `ondatagramstatus` callback.+         *+         * This option is immutable after session creation.+         * @since v26.2.0+         */+        datagramDropPolicy?: "drop-oldest" | "drop-newest" | undefined;+        /**+         * The maximum number of `SendPendingData` cycles a datagram can survive+         * without being sent before it is abandoned. When a datagram cannot be+         * sent due to congestion control or packet size constraints, it remains+         * in the queue and the attempt counter increments. Once the limit is+         * reached, the datagram is dropped and reported as `'abandoned'` via the+         * `ondatagramstatus` callback. Valid range: `1` to `255`.+         * @since v26.2.0+         */+        maxDatagramSendAttempts?: number | undefined;+        /**+         * A multiplier applied to the Probe Timeout (PTO) to compute the draining+         * period duration after receiving a `CONNECTION_CLOSE` frame from the peer.+         * RFC 9000 Section 10.2 requires the draining period to persist for at least+         * three times the current PTO. The valid range is `3` to `255`. Values below+         * `3` are clamped to `3`.+         * @since v26.2.0+         */+        drainingPeriodMultiplier?: number | undefined;+        /**+         * Specifies the keep-alive timeout in milliseconds. When set to a non-zero+         * value, PING frames will be sent automatically to keep the connection alive+         * before the idle timeout fires. The value should be less than the effective
… 1066 more lines (truncated)
child_process.d.ts +0 lines
--- +++ @@ -229,3 +229,2 @@          * ```js-         * 'use strict';          * import { spawn } from 'node:child_process';
crypto.d.ts +6 lines
--- +++ @@ -2700,3 +2700,3 @@         algorithm: string | null | undefined,-        data: ArrayBufferLike | NodeJS.ArrayBufferView,+        data: BinaryLike,         key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,@@ -2705,3 +2705,3 @@         algorithm: string | null | undefined,-        data: ArrayBufferLike | NodeJS.ArrayBufferView,+        data: BinaryLike,         key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,@@ -2731,5 +2731,5 @@         algorithm: string | null | undefined,-        data: ArrayBufferLike | NodeJS.ArrayBufferView,+        data: BinaryLike,         key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,-        signature: ArrayBufferLike | NodeJS.ArrayBufferView,+        signature: BinaryLike,     ): boolean;@@ -2737,5 +2737,5 @@         algorithm: string | null | undefined,-        data: ArrayBufferLike | NodeJS.ArrayBufferView,+        data: BinaryLike,         key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,-        signature: ArrayBufferLike | NodeJS.ArrayBufferView,+        signature: BinaryLike,         callback: (error: Error | null, result: boolean) => void,
dns.d.ts +5 lines
--- +++ @@ -492,3 +492,3 @@      *   order: 30,-     *   preference: 100+     *   preference: 100,      * }@@ -549,3 +549,3 @@      *   expire: 604800,-     *   minttl: 3600+     *   minttl: 3600,      * }@@ -575,3 +575,3 @@      *   port: 21223,-     *   name: 'service.example.com'+     *   name: 'service.example.com',      * }@@ -602,3 +602,3 @@      *   match: 1,-     *   data: [ArrayBuffer]+     *   data: [ArrayBuffer],      * }@@ -652,3 +652,3 @@      *     expire: 1800,-     *     minttl: 60 } ]+     *     minttl: 60 } ];      * ```
dns/promises.d.ts +5 lines
--- +++ @@ -185,3 +185,3 @@      *     expire: 1800,-     *     minttl: 60 } ]+     *     minttl: 60 } ];      * ```@@ -228,3 +228,3 @@      *   order: 30,-     *   preference: 100+     *   preference: 100,      * }@@ -267,3 +267,3 @@      *   expire: 604800,-     *   minttl: 3600+     *   minttl: 3600,      * }@@ -287,3 +287,3 @@      *   port: 21223,-     *   name: 'service.example.com'+     *   name: 'service.example.com',      * }@@ -308,3 +308,3 @@      *   match: 1,-     *   data: [ArrayBuffer]+     *   data: [ArrayBuffer],      * }
fs.d.ts +7 lines
--- +++ @@ -50,2 +50,9 @@         birthtime: Date;+        // Deliberately not defining a type alias here... it'd be exported, and something in the ecosystem would inevitably start using it.+        // TODO: replace with Temporal builtins once @types/node no longer supports TS <6.0.+        atimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;+        mtimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;+        ctimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;+        birthtimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T+            : unknown;     }
http2.d.ts +4 lines
--- +++ @@ -61,3 +61,3 @@         "timeout": [];-        "trailers": [trailers: IncomingHttpHeaders, flags: number];+        "trailers": [headers: IncomingHttpHeaders, flags: number, rawHeaders: string[]];         "wantTrailers": [];@@ -247,3 +247,3 @@         "headers": [headers: IncomingHttpHeaders & IncomingHttpStatusHeader, flags: number, rawHeaders: string[]];-        "push": [headers: IncomingHttpHeaders, flags: number];+        "push": [headers: IncomingHttpHeaders, flags: number, rawHeaders: string[]];         "response": [headers: IncomingHttpHeaders & IncomingHttpStatusHeader, flags: number, rawHeaders: string[]];@@ -1646,4 +1646,4 @@          *-         * ```js-         * '/status?name=ryan'+         * ```json+         * "/status?name=ryan"          * ```
os.d.ts +30 lines
--- +++ @@ -124,3 +124,3 @@      *   },-     * ]+     * ];      * ```@@ -169,40 +169,40 @@      *-     * ```js+     * ```json      * {-     *   lo: [+     *   "lo": [      *     {-     *       address: '127.0.0.1',-     *       netmask: '255.0.0.0',-     *       family: 'IPv4',-     *       mac: '00:00:00:00:00:00',-     *       internal: true,-     *       cidr: '127.0.0.1/8'+     *       "address:": "127.0.0.1",+     *       "netmask:": "255.0.0.0",+     *       "family:": "IPv4",+     *       "mac:": "00:00:00:00:00:00",+     *       "internal:": true,+     *       "cidr:": "127.0.0.1/8"      *     },      *     {-     *       address: '::1',-     *       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',-     *       family: 'IPv6',-     *       mac: '00:00:00:00:00:00',-     *       scopeid: 0,-     *       internal: true,-     *       cidr: '::1/128'+     *       "address:": "::1",+     *       "netmask:": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",+     *       "family:": "IPv6",+     *       "mac:": "00:00:00:00:00:00",+     *       "scopeid:": 0,+     *       "internal:": true,+     *       "cidr:": "::1/128"      *     }      *   ],-     *   eth0: [+     *   "eth0": [      *     {-     *       address: '192.168.1.108',-     *       netmask: '255.255.255.0',-     *       family: 'IPv4',-     *       mac: '01:02:03:0a:0b:0c',-     *       internal: false,-     *       cidr: '192.168.1.108/24'+     *       "address:": "192.168.1.108",+     *       "netmask:": "255.255.255.0",+     *       "family:": "IPv4",+     *       "mac:": "01:02:03:0a:0b:0c",+     *       "internal:": false,+     *       "cidr:": "192.168.1.108/24"      *     },      *     {-     *       address: 'fe80::a00:27ff:fe4e:66a1',-     *       netmask: 'ffff:ffff:ffff:ffff::',-     *       family: 'IPv6',-     *       mac: '01:02:03:0a:0b:0c',-     *       scopeid: 1,-     *       internal: false,-     *       cidr: 'fe80::a00:27ff:fe4e:66a1/64'+     *       "address:": "fe80::a00:27ff:fe4e:66a1",+     *       "netmask:": "ffff:ffff:ffff:ffff::",+     *       "family:": "IPv6",+     *       "mac:": "01:02:03:0a:0b:0c",+     *       "scopeid:": 1,+     *       "internal:": false,+     *       "cidr:": "fe80::a00:27ff:fe4e:66a1/64"      *     }
package.json +2 lines
--- +++ @@ -2,3 +2,3 @@     "name": "@types/node",-    "version": "26.1.2",+    "version": "26.2.0",     "description": "TypeScript definitions for node",@@ -152,3 +152,3 @@     "peerDependencies": {},-    "typesPublisherContentHash": "359a01a58cecf5a30fb7b7a7b10c4f5c332339421ef5cbc9932fc492f472a5b4",+    "typesPublisherContentHash": "e8c7e12bafdd8ff8648e4d416be7af2d4373bffe17a7498d815e251898739e7c",     "typeScriptVersion": "5.6"
perf_hooks.d.ts +2 lines
--- +++ @@ -13,2 +13,3 @@         | "node" // Node.js only+        | "quic" // Node.js only         | "resource"; // available on the Web@@ -216,3 +217,3 @@         readonly detail: any;-        readonly entryType: "dns" | "function" | "gc" | "http2" | "http" | "net" | "node";+        readonly entryType: "dns" | "function" | "gc" | "http2" | "http" | "net" | "node" | "quic";     }
process.d.ts +42 lines
--- +++ @@ -793,3 +793,3 @@                  *-                 * ```js+                 * ```json                  * ["--icu-data-dir=./foo", "--require", "./bar.js"]@@ -799,4 +799,4 @@                  *-                 * ```js-                 * ['/usr/local/bin/node', 'script.js', '--version']+                 * ```json+                 * ["/usr/local/bin/node", "script.js", "--version"]                  * ```@@ -812,4 +812,4 @@                  *-                 * ```js-                 * '/usr/local/bin/node'+                 * ```json+                 * "/usr/local/bin/node"                  * ```@@ -996,14 +996,14 @@                  *-                 * ```js+                 * ```json                  * {-                 *   TERM: 'xterm-256color',-                 *   SHELL: '/usr/local/bin/bash',-                 *   USER: 'maciej',-                 *   PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',-                 *   PWD: '/Users/maciej',-                 *   EDITOR: 'vim',-                 *   SHLVL: '1',-                 *   HOME: '/Users/maciej',-                 *   LOGNAME: 'maciej',-                 *   _: '/usr/local/bin/node'+                 *   "TERM": "xterm-256color",+                 *   "SHELL": "/usr/local/bin/bash",+                 *   "USER": "maciej",+                 *   "PATH": "~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin",+                 *   "PWD": "/Users/maciej",+                 *   "EDITOR": "vim",+                 *   "SHLVL": "1",+                 *   "HOME": "/Users/maciej",+                 *   "LOGNAME": "maciej",+                 *   "_": "/usr/local/bin/node"                  * }@@ -1542,25 +1542,24 @@                  *-                 * ```js+                 * ```json                  * {-                 *   target_defaults:-                 *    { cflags: [],-                 *      default_configuration: 'Release',-                 *      defines: [],-                 *      include_dirs: [],-                 *      libraries: [] },-                 *   variables:+                 *   "target_defaults":+                 *    { "cflags": [],+                 *      "default_configuration": "Release",+                 *      "defines": [],+                 *      "include_dirs": [],+                 *      "libraries": [] },+                 *   "variables":                  *    {-                 *      host_arch: 'x64',-                 *      napi_build_version: 5,-                 *      node_install_npm: 'true',-                 *      node_prefix: '',-                 *      node_shared_cares: 'false',-                 *      node_shared_http_parser: 'false',-                 *      node_shared_libuv: 'false',-                 *      node_shared_zlib: 'false',-                 *      node_use_openssl: 'true',-                 *      node_shared_openssl: 'false',-                 *      strict_aliasing: 'true',-                 *      target_arch: 'x64',-                 *      v8_use_snapshot: 1+                 *      "host_arch": "x64",+                 *      "napi_build_version": 5,+                 *      "node_install_npm": "true",+                 *      "node_prefix": "",+                 *      "node_shared_cares": "false",+                 *      "node_shared_http_parser": "false",+                 *      "node_shared_libuv": "false",+                 *      "node_shared_zlib": "false",+                 *      "node_use_openssl": "true",+                 *      "node_shared_openssl": "false",+                 *      "target_arch": "x64",+                 *      "v8_use_snapshot": 1                  *    }@@ -1878,9 +1877,9 @@                  *-                 * ```js+                 * ```json                  * {-                 *   name: 'node',-                 *   lts: 'Hydrogen',-                 *   sourceUrl: 'https://nodejs.org/download/release/v18.12.0/node-v18.12.0.tar.gz',-                 *   headersUrl: 'https://nodejs.org/download/release/v18.12.0/node-v18.12.0-headers.tar.gz',-                 *   libUrl: 'https://nodejs.org/download/release/v18.12.0/win-x64/node.lib'+                 *   "name": "node",+                 *   "lts": "Hydrogen",+                 *   "sourceUrl": "https://nodejs.org/download/release/v18.12.0/node-v18.12.0.tar.gz",+                 *   "headersUrl": "https://nodejs.org/download/release/v18.12.0/node-v18.12.0-headers.tar.gz",+                 *   "libUrl": "https://nodejs.org/download/release/v18.12.0/win-x64/node.lib"                  * }
sqlite.d.ts +15 lines
--- +++ @@ -300,6 +300,19 @@          * `allowExtension` option when constructing the `DatabaseSync` instance.+         *+         * ```js+         * import { DatabaseSync } from 'node:sqlite';+         * const database = new DatabaseSync(':memory:', { allowExtension: true });+         *+         * // Load using the entry point derived from the filename.+         * database.loadExtension('./decimal.dylib');+         *+         * // Override the entry point when the derived name does not match.+         * database.loadExtension('./base64.dylib', 'sqlite3_base64_init');          * @since v22.13.0          * @param path The path to the shared library to load.-         */-        loadExtension(path: string): void;+         * @param entryPoint The name of the extension's entry-point function. When+         * omitted, SQLite derives the entry point from the shared library's filename;+         * pass this argument explicitly when the derived name does not match.+         */+        loadExtension(path: string, entryPoint?: string): void;         /**
stream/iter.d.ts +3 lines
--- +++ @@ -313,4 +313,5 @@      *-     * The result is cached per instance -- calling `fromWritable()` twice with the-     * same stream returns the same Writer.+     * The result is cached per instance and backpressure policy -- calling+     * `fromWritable()` twice with the same stream and `backpressure` option returns+     * the same Writer.      *
test.d.ts +61 lines
--- +++ @@ -266,2 +266,11 @@             testSkipPatterns?: string | RegExp | ReadonlyArray<string | RegExp> | undefined;+            /**+             * A tag name, or an array of tag names,+             * used to filter tests by their declared tags. Tests must contain every+             * listed tag to run. Equivalent to passing `--experimental-test-tag-filter`+             * on the command line. See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+             * @default undefined+             * @since v26.2.0+             */+            testTagFilters?: string | readonly string[] | undefined;             /**@@ -671,2 +680,8 @@                 /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];+                /**                  * A numeric identifier for this test instance, unique@@ -699,2 +714,8 @@                 /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];+                /**                  * A numeric identifier for this test instance, unique@@ -719,2 +740,8 @@                 nesting: number;+                /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];                 /**@@ -764,2 +791,8 @@                 nesting: number;+                /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];                 /**@@ -826,2 +859,8 @@                 /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];+                /**                  * A numeric identifier for this test instance, unique@@ -863,2 +902,8 @@                 nesting: number;+                /**+                 * The flattened lowercased tags declared on the test+                 * and its ancestor suites, in declaration order. Empty for untagged tests.+                 * See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+                 */+                tags: string[];                 /**@@ -1085,2 +1130,9 @@             /**+             * A frozen array of the test's flattened lowercased tags, in declaration+             * order, including any tags inherited from ancestor suites. Empty when the+             * test has no tags. See [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+             * @since v26.2.0+             */+            readonly tags: readonly string[];+            /**              * The unique identifier of the worker running the current test file. This value is@@ -1445,2 +1497,11 @@             skip?: boolean | string | undefined;+            /**+             * An array of string labels associated with the test.+             * Used together with `--experimental-test-tag-filter` to filter which+             * tests run. Tags inherit from suites to nested tests by union. See+             * [Test tags](https://nodejs.org/docs/latest-v26.x/api/test.html#test-tags).+             * @default []+             * @since v26.2.0+             */+            tags?: readonly string[] | undefined;             /**
v8.d.ts +20 lines
--- +++ @@ -91,19 +91,18 @@      *-     * ```js+     * ```json      * {-     *   total_heap_size: 7326976,-     *   total_heap_size_executable: 4194304,-     *   total_physical_size: 7326976,-     *   total_available_size: 1152656,-     *   used_heap_size: 3476208,-     *   heap_size_limit: 1535115264,-     *   malloced_memory: 16384,-     *   peak_malloced_memory: 1127496,-     *   does_zap_garbage: 0,-     *   number_of_native_contexts: 1,-     *   number_of_detached_contexts: 0,-     *   total_global_handles_size: 8192,-     *   used_global_handles_size: 3296,-     *   external_memory: 318824,-     *   total_allocated_bytes: 45224088+     *   "total_heap_size": 7326976,+     *   "total_heap_size_executable": 4194304,+     *   "total_physical_size": 7326976,+     *   "total_available_size": 1152656,+     *   "used_heap_size": 3476208,+     *   "heap_size_limit": 1535115264,+     *   "malloced_memory": 16384,+     *   "peak_malloced_memory": 1127496,+     *   "does_zap_garbage": 0,+     *   "number_of_native_contexts": 1,+     *   "number_of_detached_contexts": 0,+     *   "total_global_handles_size": 8192,+     *   "used_global_handles_size": 3296,+     *   "external_memory": 318824      * }@@ -388,8 +387,8 @@      *-     * ```js+     * ```json      * {-     *   code_and_metadata_size: 212208,-     *   bytecode_and_metadata_size: 161368,-     *   external_script_source_size: 1410794,-     *   cpu_profiler_metadata_size: 0,+     *   "code_and_metadata_size": 212208,+     *   "bytecode_and_metadata_size": 161368,+     *   "external_script_source_size": 1410794,+     *   "cpu_profiler_metadata_size": 0      * }@@ -965,4 +964,2 @@      * ```js-     * 'use strict';-     *      * import fs from 'node:fs';
@types/react npm
19.2.18 22d ago nominal
BURST ×109
latest 19.2.18 versions 706 maintainers 1
19.2.14
19.2.15
18.3.29
17.0.92
16.14.70
15.7.37
19.2.16
18.3.30
17.0.93
19.2.17
18.3.31
19.2.18
BURST
2 releases in 28m: 15.0.19, 15.0.20
info · registry-verified · 2017-03-24 · 9y ago
BURST
2 releases in 0m: 16.0.0, 15.6.1
info · registry-verified · 2017-08-01 · 9y ago
BURST
2 releases in 0m: 16.0.6, 15.6.3
info · registry-verified · 2017-09-25 · 8y ago
BURST
2 releases in 6m: 15.6.4, 16.0.7
info · registry-verified · 2017-09-25 · 8y ago
BURST
2 releases in 0m: 16.0.17, 15.6.5
info · registry-verified · 2017-10-22 · 8y ago
BURST
2 releases in 0m: 16.0.23, 15.6.7
info · registry-verified · 2017-11-15 · 8y ago
BURST
2 releases in 23m: 15.6.9, 16.0.30
info · registry-verified · 2017-12-13 · 8y ago
BURST
2 releases in 0m: 16.0.34, 15.6.11
info · registry-verified · 2018-01-03 · 8y ago
BURST
2 releases in 1m: 15.6.12, 16.0.35
info · registry-verified · 2018-01-24 · 8y ago
BURST
2 releases in 0m: 16.0.37, 15.6.13
info · registry-verified · 2018-02-12 · 8y ago
BURST
2 releases in 1m: 15.6.14, 16.0.38
info · registry-verified · 2018-02-13 · 8y ago
BURST
2 releases in 0m: 16.1.0, 15.6.15
info · registry-verified · 2018-03-27 · 8y ago
BURST
2 releases in 10m: 15.6.16, 16.3.15
info · registry-verified · 2018-05-31 · 8y ago
BURST
2 releases in 12m: 15.6.17, 16.4.1
info · registry-verified · 2018-06-20 · 8y ago
BURST
2 releases in 0m: 15.6.18, 16.4.4
info · registry-verified · 2018-06-28 · 8y ago
BURST
2 releases in 0m: 15.6.19, 16.4.8
info · registry-verified · 2018-08-06 · 8y ago
BURST
2 releases in 40m: 16.7.0, 16.7.1
info · registry-verified · 2018-11-09 · 7y ago
BURST
2 releases in 0m: 15.6.20, 16.7.3
info · registry-verified · 2018-11-11 · 7y ago
BURST
2 releases in 2m: 15.6.21, 16.7.8
info · registry-verified · 2018-11-28 · 7y ago
BURST
2 releases in 0m: 16.8.3, 15.6.22
info · registry-verified · 2019-02-13 · 7y ago
BURST
2 releases in 0m: 16.8.14, 15.6.24
info · registry-verified · 2019-04-19 · 7y ago
BURST
2 releases in 0m: 16.8.19, 15.6.25
info · registry-verified · 2019-05-28 · 7y ago
BURST
2 releases in 0m: 16.8.20, 15.6.26
info · registry-verified · 2019-06-13 · 7y ago
BURST
2 releases in 0m: 16.8.24, 15.6.27
info · registry-verified · 2019-07-31 · 7y ago
BURST
3 releases in 42m: 16.9.8, 15.6.28, 16.9.9
info · registry-verified · 2019-10-16 · 6y ago
BURST
2 releases in 37m: 16.9.28, 16.9.29
info · registry-verified · 2020-03-31 · 6y ago
BURST
2 releases in 46m: 16.9.40, 16.9.41
info · registry-verified · 2020-06-24 · 6y ago
BURST
2 releases in 0m: 16.9.51, 15.6.30
info · registry-verified · 2020-10-05 · 5y ago
BURST
2 releases in 0m: 16.9.55, 15.6.31
info · registry-verified · 2020-10-28 · 5y ago
BURST
2 releases in 1m: 16.14.0, 15.7.0
info · registry-verified · 2020-11-20 · 5y ago
BURST
2 releases in 0m: 17.0.0, 16.14.1
info · registry-verified · 2020-11-20 · 5y ago
BURST
2 releases in 0m: 17.0.1, 16.14.3
info · registry-verified · 2021-02-02 · 5y ago
BURST
2 releases in 0m: 17.0.2, 16.14.4
info · registry-verified · 2021-02-12 · 5y ago
BURST
2 releases in 0m: 17.0.3, 16.14.5
info · registry-verified · 2021-03-07 · 5y ago
BURST
2 releases in 0m: 17.0.5, 16.14.6
info · registry-verified · 2021-05-04 · 5y ago
BURST
2 releases in 0m: 17.0.8, 16.14.8
info · registry-verified · 2021-05-26 · 5y ago
BURST
2 releases in 0m: 17.0.12, 16.14.9
info · registry-verified · 2021-07-01 · 5y ago
BURST
3 releases in 0m: 17.0.13, 16.14.10, 15.7.1
info · registry-verified · 2021-07-01 · 5y ago
BURST
3 releases in 0m: 17.0.14, 16.14.11, 15.7.2
info · registry-verified · 2021-07-07 · 5y ago
BURST
3 releases in 1m: 17.0.16, 16.14.12, 15.7.3
info · registry-verified · 2021-08-06 · 5y ago
BURST
2 releases in 0m: 17.0.17, 16.14.13
info · registry-verified · 2021-08-11 · 5y ago
BURST
2 releases in 0m: 17.0.19, 16.14.14
info · registry-verified · 2021-08-19 · 5y ago
BURST
2 releases in 0m: 17.0.20, 16.14.15
info · registry-verified · 2021-09-05 · 4y ago
BURST
2 releases in 33m: 17.0.23, 17.0.24
info · registry-verified · 2021-09-21 · 4y ago
BURST
2 releases in 0m: 17.0.25, 15.7.4
info · registry-verified · 2021-09-29 · 4y ago
BURST
2 releases in 0m: 17.0.27, 16.14.16
info · registry-verified · 2021-10-03 · 4y ago
BURST
3 releases in 0m: 17.0.29, 16.14.17, 15.7.5
info · registry-verified · 2021-10-12 · 4y ago
BURST
2 releases in 0m: 17.0.31, 16.14.18
info · registry-verified · 2021-10-21 · 4y ago
BURST
2 releases in 0m: 16.14.19, 15.7.6
info · registry-verified · 2021-10-23 · 4y ago
BURST
2 releases in 0m: 17.0.33, 16.14.20
info · registry-verified · 2021-10-25 · 4y ago
BURST
2 releases in 0m: 17.0.35, 16.14.21
info · registry-verified · 2021-11-15 · 4y ago
BURST
2 releases in 0m: 17.0.39, 16.14.23
info · registry-verified · 2022-02-03 · 4y ago
BURST
3 releases in 0m: 17.0.40, 16.14.24, 15.7.7
info · registry-verified · 2022-03-10 · 4y ago
BURST
2 releases in 0m: 18.0.0, 17.0.44
info · registry-verified · 2022-04-07 · 4y ago
BURST
2 releases in 0m: 18.0.5, 16.14.25
info · registry-verified · 2022-04-14 · 4y ago
BURST
3 releases in 1m: 18.0.9, 17.0.45, 16.14.26
info · registry-verified · 2022-05-06 · 4y ago
BURST
3 releases in 0m: 18.0.13, 17.0.46, 16.14.27
info · registry-verified · 2022-06-16 · 4y ago
BURST
3 releases in 0m: 18.0.14, 17.0.47, 16.14.28
info · registry-verified · 2022-06-16 · 4y ago
BURST
3 releases in 0m: 17.0.48, 16.14.29, 15.7.8
info · registry-verified · 2022-07-27 · 4y ago
BURST
3 releases in 0m: 18.0.16, 16.14.30, 15.7.9
info · registry-verified · 2022-08-07 · 4y ago
BURST
3 releases in 0m: 18.0.18, 17.0.49, 16.14.31
info · registry-verified · 2022-08-30 · 3y ago
BURST
4 releases in 0m: 18.0.20, 17.0.50, 16.14.32, 15.7.10
info · registry-verified · 2022-09-13 · 3y ago
BURST
3 releases in 1m: 18.0.23, 17.0.51, 16.14.33
info · registry-verified · 2022-10-25 · 3y ago
BURST
4 releases in 1m: 18.0.24, 17.0.52, 16.14.34, 15.7.11
info · registry-verified · 2022-10-27 · 3y ago
BURST
4 releases in 1m: 18.0.27, 17.0.53, 16.14.35, 15.7.12
info · registry-verified · 2023-01-18 · 3y ago
BURST
4 releases in 0m: 18.0.30, 17.0.54, 16.14.36, 15.7.13
info · registry-verified · 2023-03-27 · 3y ago
BURST
3 releases in 0m: 18.0.31, 17.0.55, 16.14.37
info · registry-verified · 2023-03-28 · 3y ago
BURST
4 releases in 2m: 18.0.33, 17.0.56, 16.14.38, 15.7.14
info · registry-verified · 2023-04-03 · 3y ago
BURST
3 releases in 1m: 18.0.34, 17.0.57, 16.14.39
info · registry-verified · 2023-04-10 · 3y ago
BURST
4 releases in 0m: 18.0.35, 17.0.58, 16.14.40, 15.7.16
info · registry-verified · 2023-04-12 · 3y ago
BURST
2 releases in 30m: 18.0.36, 18.0.37
info · registry-verified · 2023-04-17 · 3y ago
BURST
4 releases in 0m: 18.2.6, 17.0.59, 16.14.41, 15.7.17
info · registry-verified · 2023-05-06 · 3y ago
BURST
3 releases in 0m: 17.0.60, 16.14.42, 15.7.18
info · registry-verified · 2023-05-25 · 3y ago
BURST
4 releases in 0m: 18.2.10, 17.0.61, 16.14.43, 15.7.19
info · registry-verified · 2023-06-10 · 3y ago
BURST
4 releases in 1m: 18.2.19, 17.0.63, 16.14.44, 15.7.20
info · registry-verified · 2023-08-08 · 3y ago
BURST
4 releases in 0m: 18.2.20, 17.0.64, 16.14.45, 15.7.21
info · registry-verified · 2023-08-09 · 3y ago
BURST
4 releases in 1m: 18.2.21, 17.0.65, 16.14.46, 15.7.22
info · registry-verified · 2023-08-22 · 3y ago
BURST
4 releases in 1m: 18.2.23, 17.0.66, 16.14.47, 15.7.23
info · registry-verified · 2023-09-26 · 2y ago
BURST
3 releases in 0m: 18.2.24, 17.0.67, 16.14.48
info · registry-verified · 2023-10-01 · 2y ago
BURST
4 releases in 0m: 18.2.28, 17.0.68, 16.14.49, 15.7.24
info · registry-verified · 2023-10-10 · 2y ago
BURST
4 releases in 0m: 18.2.29, 17.0.69, 16.14.50, 15.7.25
info · registry-verified · 2023-10-18 · 2y ago
BURST
4 releases in 1m: 18.2.37, 17.0.70, 16.14.51, 15.7.26
info · registry-verified · 2023-11-07 · 2y ago
BURST
4 releases in 0m: 18.2.38, 17.0.71, 16.14.52, 15.7.27
info · registry-verified · 2023-11-21 · 2y ago
BURST
3 releases in 1m: 18.2.44, 17.0.72, 16.14.53
info · registry-verified · 2023-12-12 · 2y ago
BURST
4 releases in 2m: 18.2.45, 17.0.73, 16.14.54, 15.7.28
info · registry-verified · 2023-12-13 · 2y ago
BURST
3 releases in 0m: 18.2.46, 17.0.74, 16.14.55
info · registry-verified · 2023-12-28 · 2y ago
BURST
4 releases in 1m: 18.2.48, 17.0.75, 16.14.56, 15.7.29
info · registry-verified · 2024-01-15 · 2y ago
BURST
4 releases in 1m: 18.2.59, 17.0.76, 16.14.57, 15.7.30
info · registry-verified · 2024-02-26 · 2y ago
BURST
3 releases in 0m: 18.2.66, 17.0.77, 16.14.58
info · registry-verified · 2024-03-14 · 2y ago
BURST
3 releases in 29m: 18.2.67, 17.0.79, 16.14.59
info · registry-verified · 2024-03-18 · 2y ago
BURST
3 releases in 0m: 18.2.71, 17.0.80, 16.14.60
info · registry-verified · 2024-03-26 · 2y ago
BURST
3 releases in 0m: 18.3.6, 17.0.81, 16.14.61
info · registry-verified · 2024-09-16 · 1y ago
BURST
2 releases in 0m: 18.3.7, 17.0.82
info · registry-verified · 2024-09-17 · 1y ago
BURST
3 releases in 0m: 18.3.10, 17.0.83, 16.14.62
info · registry-verified · 2024-09-27 · 1y ago
BURST
2 releases in 0m: 19.0.0, 18.3.14
info · registry-verified · 2024-12-05 · 1y ago
BURST
5 releases in 0m: 19.0.12, 18.3.19, 17.0.84, 16.14.63, 15.7.31
info · registry-verified · 2025-03-19 · 1y ago
BURST
3 releases in 54m: 19.0.13, 19.0.14, 19.1.0
info · registry-verified · 2025-04-02 · 1y ago
BURST
2 releases in 0m: 19.1.3, 18.3.21
info · registry-verified · 2025-05-06 · 1y ago
BURST
4 releases in 0m: 19.1.5, 18.3.22, 17.0.86, 16.14.64
info · registry-verified · 2025-05-21 · 1y ago
BURST
4 releases in 0m: 19.1.6, 18.3.23, 17.0.87, 16.14.65
info · registry-verified · 2025-05-27 · 1y ago
BURST
5 releases in 0m: 19.1.11, 18.3.24, 17.0.88, 16.14.66, 15.7.32
info · registry-verified · 2025-08-22 · 12mo ago
BURST
2 releases in 8m: 15.7.33, 15.7.34
info · registry-verified · 2025-08-22 · 12mo ago
BURST
2 releases in 0m: 19.1.16, 18.3.25
info · registry-verified · 2025-09-30 · 10mo ago
BURST
4 releases in 0m: 19.2.1, 18.3.26, 17.0.89, 16.14.67
info · registry-verified · 2025-10-06 · 10mo ago
BURST
4 releases in 0m: 19.2.6, 18.3.27, 17.0.90, 16.14.68
info · registry-verified · 2025-11-18 · 9mo ago
BURST
6 releases in 27m: 19.2.12, 18.3.28, 17.0.91, 16.14.69, 15.7.36, 19.2.13
info · registry-verified · 2026-02-05 · 6mo ago
BURST
5 releases in 0m: 19.2.15, 18.3.29, 17.0.92, 16.14.70, 15.7.37
info · registry-verified · 2026-05-19 · 3mo ago
BURST
3 releases in 0m: 19.2.16, 18.3.30, 17.0.93
info · registry-verified · 2026-06-01 · 2mo ago
BURST
2 releases in 0m: 19.2.17, 18.3.31
info · registry-verified · 2026-06-05 · 2mo ago
release diff 18.3.31 → 19.2.18
+1 added · -0 removed · ~10 modified
canary.d.ts +77 lines
--- +++ @@ -32,51 +32,69 @@ -type NativeToggleEvent = ToggleEvent;+type NativeSubmitEvent = SubmitEvent;  declare module "." {-    export type Usable<T> = PromiseLike<T> | Context<T>;--    export function use<T>(usable: Usable<T>): T;--    interface ServerContextJSONArray extends ReadonlyArray<ServerContextJSONValue> {}-    export type ServerContextJSONValue =-        | string-        | boolean-        | number-        | null-        | ServerContextJSONArray-        | { [key: string]: ServerContextJSONValue };-    export interface ServerContext<T extends ServerContextJSONValue> {-        Provider: Provider<T>;-    }-    /**-     * Accepts a context object (the value returned from `React.createContext` or `React.createServerContext`) and returns the current-     * context value, as given by the nearest context provider for the given context.-     *-     * @version 16.8.0-     * @see {@link https://react.dev/reference/react/useContext}-     */-    function useContext<T extends ServerContextJSONValue>(context: ServerContext<T>): T;-    export function createServerContext<T extends ServerContextJSONValue>(-        globalName: string,-        defaultValue: T,-    ): ServerContext<T>;--    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type-    export function cache<CachedFunction extends Function>(fn: CachedFunction): CachedFunction;-     export function unstable_useCacheRefresh(): () => void; -    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS {-        functions: (formData: FormData) => void | Promise<void>;+    // @enableViewTransition+    export interface ViewTransitionInstance {+        /**+         * The {@link ViewTransitionProps name} that was used in the corresponding {@link ViewTransition} component or `"auto"` if the `name` prop was omitted.+         */+        name: string;     } -    export interface TransitionStartFunction {+    export type ViewTransitionClassPerType = Record<"default" | (string & {}), "none" | "auto" | (string & {})>;+    export type ViewTransitionClass = ViewTransitionClassPerType | ViewTransitionClassPerType[string];++    export interface ViewTransitionProps {+        children?: ReactNode | undefined;         /**-         * Marks all state updates inside the async function as transitions+         * Assigns the {@link https://developer.chrome.com/blog/view-transitions-update-io24#view-transition-class `view-transition-class`} class to the underlying DOM node.+         */+        default?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` or its parent Component is mounted and there's no other with the same name being deleted.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        enter?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` or its parent Component is unmounted and there's no other with the same name being deleted.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        exit?: ViewTransitionClass | undefined;+        /**+         * "auto" will automatically assign a view-transition-name to the inner DOM node.+         * That way you can add a View Transition to a Component without controlling its DOM nodes styling otherwise.          *-         * @see {https://react.dev/reference/react/useTransition#starttransition}-         *-         * @param callback+         * A difference between this and the browser's built-in view-transition-name: auto is that switching the DOM nodes within the `<ViewTransition>` component preserves the same name so this example cross-fades between the DOM nodes instead of causing an exit and enter.+         * @default "auto"          */-        (callback: () => Promise<VoidOrUndefinedOnly>): void;+        name?: "auto" | (string & {}) | undefined;+        /**+         * The `<ViewTransition>` or its parent Component is mounted and there's no other `<ViewTransition>` with the same name being deleted.+         */+        onEnter?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * The `<ViewTransition>` or its parent Component is unmounted and there's no other `<ViewTransition>` with the same name being deleted.+         */+        onExit?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * This `<ViewTransition>` is being mounted and another `<ViewTransition>` instance with the same name is being unmounted elsewhere.+         */+        onShare?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * The content of `<ViewTransition>` has changed either due to DOM mutations or because an inner child `<ViewTransition>` has resized.+         */+        onUpdate?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        ref?: Ref<ViewTransitionInstance> | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` is being mounted and another instance with the same name is being unmounted elsewhere.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        share?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if the content of this `<ViewTransition>` has changed either due to DOM mutations or because an inner child has resized.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        update?: ViewTransitionClass | undefined;     }@@ -84,82 +102,27 @@     /**-     * Similar to `useTransition` but allows uses where hooks are not available.+     * Opt-in for using {@link https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API View Transitions} in React.+     * View Transitions only trigger for async updates like {@link startTransition}, {@link useDeferredValue}, Actions or <{@link Suspense}> revealing from fallback to content.+     * Synchronous updates provide an opt-out but also guarantee that they commit immediately which View Transitions can't.      *-     * @param callback An _asynchronous_ function which causes state updates that can be deferred.+     * @see {@link https://react.dev/reference/react/ViewTransition `<ViewTransition>` reference documentation}      */-    export function startTransition(scope: () => Promise<VoidOrUndefinedOnly>): void;+    export const ViewTransition: ExoticComponent<ViewTransitionProps>; -    export function useOptimistic<State>(-        passthrough: State,-    ): [State, (action: State | ((pendingState: State) => State)) => void];-    export function useOptimistic<State, Action>(-        passthrough: State,-        reducer: (state: State, action: Action) => State,-    ): [State, (action: Action) => void];+    /**+     * @see {@link https://react.dev/reference/react/addTransitionType `addTransitionType` reference documentation}+     */+    export function addTransitionType(type: string): void; -    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES {-        cleanup: () => VoidOrUndefinedOnly;+    // @enableFragmentRefs+    export interface FragmentInstance {}++    export interface FragmentProps {+        ref?: Ref<FragmentInstance> | undefined;     } -    export function useActionState<State>(-        action: (state: Awaited<State>) => State | Promise<State>,-        initialState: Awaited<State>,-        permalink?: string,-    ): [state: Awaited<State>, dispatch: () => void, isPending: boolean];-    export function useActionState<State, Payload>(-        action: (state: Awaited<State>, payload: Payload) => State | Promise<State>,-        initialState: Awaited<State>,-        permalink?: string,-    ): [state: Awaited<State>, dispatch: (payload: Payload) => void, isPending: boolean];--    interface DOMAttributes<T> {-        // Transition Events-        onTransitionCancel?: TransitionEventHandler<T> | undefined;-        onTransitionCancelCapture?: TransitionEventHandler<T> | undefined;-        onTransitionRun?: TransitionEventHandler<T> | undefined;-        onTransitionRunCapture?: TransitionEventHandler<T> | undefined;-        onTransitionStart?: TransitionEventHandler<T> | undefined;-        onTransitionStartCapture?: TransitionEventHandler<T> | undefined;-    }--    type ToggleEventHandler<T = Element> = EventHandler<ToggleEvent<T>>;--    interface HTMLAttributes<T> {-        popover?: "" | "auto" | "manual" | "hint" | undefined;-        popoverTargetAction?: "toggle" | "show" | "hide" | undefined;-        popoverTarget?: string | undefined;-        onToggle?: ToggleEventHandler<T> | undefined;-        onBeforeToggle?: ToggleEventHandler<T> | undefined;-    }--    interface ToggleEvent<T = Element> extends SyntheticEvent<T, NativeToggleEvent> {-        oldState: "closed" | "open";-        newState: "closed" | "open";-    }--    interface LinkHTMLAttributes<T> {-        precedence?: string | undefined;-    }--    interface StyleHTMLAttributes<T> {-        href?: string | undefined;-        precedence?: string | undefined;-    }--    /**-     * @internal Use `Awaited<ReactNode>` instead-     */-    // Helper type to enable `Awaited<ReactNode>`.-    // Must be a copy of the non-thenables of `ReactNode`.-    type AwaitedReactNode =-        | ReactElement-        | string-        | number-        | Iterable<AwaitedReactNode>-        | ReactPortal-        | boolean-        | null-        | undefined;-    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {-        promises: Promise<AwaitedReactNode>;-        bigints: bigint;+    interface SubmitEvent<T = Element> extends SyntheticEvent<T, NativeSubmitEvent> {+        /**+         * Only available in react@canary+         */+        submitter: HTMLElement | null;     }
compiler-runtime.d.ts +4 lines
--- +++ @@ -0,0 +1,4 @@+// Not meant to be used directly+// Omitting all exports so that they don't appear in IDE autocomplete.++export {};
experimental.d.ts +77 lines
--- +++ @@ -45,2 +45,3 @@     export interface SuspenseProps {+        // @enableCPUSuspense         /**@@ -50,9 +51,12 @@          */-        unstable_expectedLoadTime?: number | undefined;+        defer?: boolean | undefined;     } -    export type SuspenseListRevealOrder = "forwards" | "backwards" | "together";-    export type SuspenseListTailMode = "collapsed" | "hidden";+    export type SuspenseListRevealOrder = "forwards" | "backwards" | "together" | "independent";+    export type SuspenseListTailMode = "collapsed" | "hidden" | "visible";      export interface SuspenseListCommonProps {+    }++    interface DirectionalSuspenseListProps extends SuspenseListCommonProps {         /**@@ -64,10 +68,8 @@          */-        children: ReactElement | Iterable<ReactElement>;-    }--    interface DirectionalSuspenseListProps extends SuspenseListCommonProps {+        children: Iterable<ReactElement> | AsyncIterable<ReactElement>;         /**          * Defines the order in which the `SuspenseList` children should be revealed.+         * @default "forwards"          */-        revealOrder: "forwards" | "backwards";+        revealOrder?: "forwards" | "backwards" | "unstable_legacy-backwards" | undefined;         /**@@ -75,5 +77,7 @@          *-         * - By default, `SuspenseList` will show all fallbacks in the list.          * - `collapsed` shows only the next fallback in the list.-         * - `hidden` doesn’t show any unloaded items.+         * - `hidden` doesn't show any unloaded items.+         * - `visible` shows all fallbacks in the list.+         *+         * @default "hidden"          */@@ -83,2 +87,3 @@     interface NonDirectionalSuspenseListProps extends SuspenseListCommonProps {+        children: ReactNode;         /**@@ -86,3 +91,3 @@          */-        revealOrder?: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps["revealOrder"]> | undefined;+        revealOrder: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps["revealOrder"]>;         /**@@ -90,3 +95,3 @@          */-        tail?: never | undefined;+        tail?: never;     }@@ -108,10 +113,2 @@ -    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type-    export function experimental_useEffectEvent<T extends Function>(event: T): T;--    /**-     * Warning: Only available in development builds.-     */-    function captureOwnerStack(): string | null;-     type Reference = object;@@ -125,7 +122,62 @@ -    export interface HTMLAttributes<T> {-        /**-         * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert}-         */-        inert?: boolean | undefined;+    // @enableGestureTransition+    // Implemented by the specific renderer e.g. `react-dom`.+    // Keep in mind that augmented interfaces merge their JSDoc so if you put+    // JSDoc here and in the renderer, the IDE will display both.+    export interface GestureProvider {}+    export interface GestureOptions {+        rangeStart?: number | undefined;+        rangeEnd?: number | undefined;+    }+    export type GestureOptionsRequired = {+        [P in keyof GestureOptions]-?: NonNullable<GestureOptions[P]>;+    };+    /** */+    export function unstable_startGestureTransition(+        provider: GestureProvider,+        scope: () => void,+        options?: GestureOptions,+    ): () => void;++    interface ViewTransitionProps {+        onGestureEnter?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureExit?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureShare?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureUpdate?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+    }++    // @enableSrcObject+    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_IMG_SRC_TYPES {+        srcObject: Blob;+    }++    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_MEDIA_SRC_TYPES {+        srcObject: Blob | MediaSource | MediaStream;+    }++    // @enableOptimisticKey+    export const optimisticKey: unique symbol;++    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES {+        optimisticKey: typeof optimisticKey;     }
global.d.ts +5 lines
--- +++ @@ -20,2 +20,3 @@ interface PointerEvent extends Event {}+interface SubmitEvent extends Event {} interface ToggleEvent extends Event {}@@ -161 +162,5 @@ interface TrustedHTML {}++interface Blob {}+interface MediaStream {}+interface MediaSource {}
index.d.ts +616 lines
--- +++ @@ -7,3 +7,2 @@ import * as CSS from "csstype";-import * as PropTypes from "prop-types"; @@ -19,2 +18,4 @@ type NativePointerEvent = PointerEvent;+type NativeSubmitEvent = SubmitEvent;+type NativeToggleEvent = ToggleEvent; type NativeTransitionEvent = TransitionEvent;@@ -35,2 +36,21 @@ declare const UNDEFINED_VOID_ONLY: unique symbol;++/**+ * @internal Use `Awaited<ReactNode>` instead+ */+// Helper type to enable `Awaited<ReactNode>`.+// Must be a copy of the non-thenables of `ReactNode`.+type AwaitedReactNode =+    | React.ReactElement+    | string+    | number+    | bigint+    | Iterable<React.ReactNode>+    | React.ReactPortal+    | boolean+    | null+    | undefined+    | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[+        keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES+    ]; @@ -96,4 +116,3 @@      * Similar to {@link JSXElementConstructor}, but with extra properties like-     * {@link FunctionComponent.defaultProps defaultProps } and-     * {@link ComponentClass.contextTypes contextTypes}.+     * {@link FunctionComponent.defaultProps defaultProps }.      *@@ -110,4 +129,3 @@      * Similar to {@link ComponentType}, but without extra properties like-     * {@link FunctionComponent.defaultProps defaultProps } and-     * {@link ComponentClass.contextTypes contextTypes}.+     * {@link FunctionComponent.defaultProps defaultProps }.      *@@ -118,22 +136,7 @@             props: P,-            /**-             * @deprecated-             *-             * @see {@link https://legacy.reactjs.org/docs/legacy-context.html#referencing-context-in-stateless-function-components React Docs}-             */-            deprecatedLegacyContext?: any,-        ) => ReactNode)-        | (new(-            props: P,-            /**-             * @deprecated-             *-             * @see {@link https://legacy.reactjs.org/docs/legacy-context.html#referencing-context-in-lifecycle-methods React Docs}-             */-            deprecatedLegacyContext?: any,-        ) => Component<any, any>);--    /**-     * A readonly ref container where {@link current} cannot be mutated.-     *+        ) => ReactNode | Promise<ReactNode>)+        // constructor signature must match React.Component+        | (new(props: P, context: any) => Component<any, any>);++    /**      * Created by {@link createRef}, or {@link useRef} when passed `null`.@@ -154,3 +157,3 @@          */-        readonly current: T | null;+        current: T;     }@@ -177,2 +180,3 @@             | void+            | (() => VoidOrUndefinedOnly)             | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[@@ -189,18 +193,11 @@ -    type Ref<T> = RefCallback<T> | RefObject<T> | null;-    /**-     * A legacy implementation of refs where you can pass a string to a ref prop.-     *-     * @see {@link https://react.dev/reference/react/Component#refs React Docs}-     *-     * @example-     *-     * ```tsx-     * <div ref="myRef" />-     * ```-     */-    // TODO: Remove the string ref special case from `PropsWithRef` once we remove LegacyRef-    type LegacyRef<T> = string | Ref<T>;--    /**+    type Ref<T> = RefCallback<T> | RefObject<T | null> | null;+    /**+     * @deprecated Use `Ref` instead. String refs are no longer supported.+     * If you're typing a library with support for React versions with string refs, use `RefAttributes<T>['ref']` instead.+     */+    type LegacyRef<T> = Ref<T>;+    /**+     * @deprecated Use `ComponentRef<T>` instead+     *      * Retrieves the type of the 'ref' prop for a given component type or tag name.@@ -224,14 +221,6 @@             | ForwardRefExoticComponent<any>-            | { new(props: any): Component<any> }-            | ((props: any, deprecatedLegacyContext?: any) => ReactNode)+            | { new(props: any, context: any): Component<any> }+            | ((props: any) => ReactNode)             | keyof JSX.IntrinsicElements,-    > =-        // need to check first if `ref` is a valid prop for [email protected]-        // otherwise it will infer `{}` instead of `never`-        "ref" extends keyof ComponentPropsWithRef<C>-            ? NonNullable<ComponentPropsWithRef<C>["ref"]> extends RefAttributes<-                infer Instance-            >["ref"] ? Instance-            : never-            : never;+    > = ComponentRef<C>; @@ -239,2 +228,4 @@ +    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES {}+     /**@@ -244,3 +235,9 @@      */-    type Key = string | number | bigint;+    type Key =+        | string+        | number+        | bigint+        | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES[+            keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES+        ]; @@ -303,3 +300,3 @@          */-        ref?: LegacyRef<T> | undefined;+        ref?: Ref<T> | undefined;     }@@ -328,3 +325,3 @@     interface ReactElement<-        P = any,+        P = unknown,         T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>,@@ -344,3 +341,9 @@ +    /**+     * @deprecated Use `ReactElement<P, React.FunctionComponent<P>>`+     */     interface FunctionComponentElement<P> extends ReactElement<P, FunctionComponent<P>> {+        /**+         * @deprecated Use `element.props.ref` instead.+         */         ref?: ("ref" extends keyof P ? P extends { ref?: infer R | undefined } ? R : never : never) | undefined;@@ -348,5 +351,14 @@ +    /**+     * @deprecated Use `ReactElement<P, React.ComponentClass<P>>`+     */     type CElement<P, T extends Component<P, ComponentState>> = ComponentElement<P, T>;+    /**+     * @deprecated Use `ReactElement<P, React.ComponentClass<P>>`+     */     interface ComponentElement<P, T extends Component<P, ComponentState>> extends ReactElement<P, ComponentClass<P>> {-        ref?: LegacyRef<T> | undefined;+        /**+         * @deprecated Use `element.props.ref` instead.+         */+        ref?: Ref<T> | undefined;     }@@ -359,2 +371,5 @@     // string fallback for custom web-components+    /**+     * @deprecated Use `ReactElement<P, string>`+     */     interface DOMElement<P extends HTMLAttributes<T> | SVGAttributes<T>, T extends Element>@@ -362,3 +377,6 @@     {-        ref: LegacyRef<T>;+        /**+         * @deprecated Use `element.props.ref` instead.+         */+        ref: Ref<T>;     }@@ -369,3 +387,3 @@     interface DetailedReactHTMLElement<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMElement<P, T> {-        type: keyof ReactHTML;+        type: HTMLElementType;     }@@ -374,3 +392,3 @@     interface ReactSVGElement extends DOMElement<SVGAttributes<SVGElement>, SVGElement> {-        type: keyof ReactSVG;+        type: SVGElementType;     }@@ -380,70 +398,2 @@     }--    //-    // Factories-    // ------------------------------------------------------------------------    /** @deprecated */-    type Factory<P> = (props?: Attributes & P, ...children: ReactNode[]) => ReactElement<P>;--    /** @deprecated */-    type SFCFactory<P> = FunctionComponentFactory<P>;--    /** @deprecated */-    type FunctionComponentFactory<P> = (-        props?: Attributes & P,-        ...children: ReactNode[]-    ) => FunctionComponentElement<P>;--    /** @deprecated */-    type ComponentFactory<P, T extends Component<P, ComponentState>> = (-        props?: ClassAttributes<T> & P,-        ...children: ReactNode[]-    ) => CElement<P, T>;--    /** @deprecated */-    type CFactory<P, T extends Component<P, ComponentState>> = ComponentFactory<P, T>;-    /** @deprecated */-    type ClassicFactory<P> = CFactory<P, ClassicComponent<P, ComponentState>>;--    /** @deprecated */-    type DOMFactory<P extends DOMAttributes<T>, T extends Element> = (-        props?: ClassAttributes<T> & P | null,-        ...children: ReactNode[]-    ) => DOMElement<P, T>;--    /** @deprecated */-    interface HTMLFactory<T extends HTMLElement> extends DetailedHTMLFactory<AllHTMLAttributes<T>, T> {}--    /** @deprecated */-    interface DetailedHTMLFactory<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMFactory<P, T> {-        (props?: ClassAttributes<T> & P | null, ...children: ReactNode[]): DetailedReactHTMLElement<P, T>;-    }--    /** @deprecated */-    interface SVGFactory extends DOMFactory<SVGAttributes<SVGElement>, SVGElement> {
… 1513 more lines (truncated)
package.json +8 lines
--- +++ @@ -2,3 +2,3 @@     "name": "@types/react",-    "version": "18.3.31",+    "version": "19.2.18",     "description": "TypeScript definitions for react",@@ -166,2 +166,7 @@         },+        "./compiler-runtime": {+            "types": {+                "default": "./compiler-runtime.d.ts"+            }+        },         "./experimental": {@@ -199,3 +204,2 @@     "dependencies": {-        "@types/prop-types": "*",         "csstype": "^3.2.2"@@ -203,4 +207,4 @@     "peerDependencies": {},-    "typesPublisherContentHash": "8ee185c606f82e91e22bd6c41a581f0b284f09472333a0d30863f96a4e72d74a",-    "typeScriptVersion": "5.3"+    "typesPublisherContentHash": "7694d96d924f28718f57b029b2c1a3dd61c406fa6ac1ef2619887840a17bfc33",+    "typeScriptVersion": "5.6" }
ts5.0/canary.d.ts +77 lines
--- +++ @@ -32,51 +32,69 @@ -type NativeToggleEvent = ToggleEvent;+type NativeSubmitEvent = SubmitEvent;  declare module "." {-    export type Usable<T> = PromiseLike<T> | Context<T>;--    export function use<T>(usable: Usable<T>): T;--    interface ServerContextJSONArray extends ReadonlyArray<ServerContextJSONValue> {}-    export type ServerContextJSONValue =-        | string-        | boolean-        | number-        | null-        | ServerContextJSONArray-        | { [key: string]: ServerContextJSONValue };-    export interface ServerContext<T extends ServerContextJSONValue> {-        Provider: Provider<T>;-    }-    /**-     * Accepts a context object (the value returned from `React.createContext` or `React.createServerContext`) and returns the current-     * context value, as given by the nearest context provider for the given context.-     *-     * @version 16.8.0-     * @see {@link https://react.dev/reference/react/useContext}-     */-    function useContext<T extends ServerContextJSONValue>(context: ServerContext<T>): T;-    export function createServerContext<T extends ServerContextJSONValue>(-        globalName: string,-        defaultValue: T,-    ): ServerContext<T>;--    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type-    export function cache<CachedFunction extends Function>(fn: CachedFunction): CachedFunction;-     export function unstable_useCacheRefresh(): () => void; -    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS {-        functions: (formData: FormData) => void | Promise<void>;+    // @enableViewTransition+    export interface ViewTransitionInstance {+        /**+         * The {@link ViewTransitionProps name} that was used in the corresponding {@link ViewTransition} component or `"auto"` if the `name` prop was omitted.+         */+        name: string;     } -    export interface TransitionStartFunction {+    export type ViewTransitionClassPerType = Record<"default" | (string & {}), "none" | "auto" | (string & {})>;+    export type ViewTransitionClass = ViewTransitionClassPerType | ViewTransitionClassPerType[string];++    export interface ViewTransitionProps {+        children?: ReactNode | undefined;         /**-         * Marks all state updates inside the async function as transitions+         * Assigns the {@link https://developer.chrome.com/blog/view-transitions-update-io24#view-transition-class `view-transition-class`} class to the underlying DOM node.+         */+        default?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` or its parent Component is mounted and there's no other with the same name being deleted.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        enter?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` or its parent Component is unmounted and there's no other with the same name being deleted.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        exit?: ViewTransitionClass | undefined;+        /**+         * "auto" will automatically assign a view-transition-name to the inner DOM node.+         * That way you can add a View Transition to a Component without controlling its DOM nodes styling otherwise.          *-         * @see {https://react.dev/reference/react/useTransition#starttransition}-         *-         * @param callback+         * A difference between this and the browser's built-in view-transition-name: auto is that switching the DOM nodes within the `<ViewTransition>` component preserves the same name so this example cross-fades between the DOM nodes instead of causing an exit and enter.+         * @default "auto"          */-        (callback: () => Promise<VoidOrUndefinedOnly>): void;+        name?: "auto" | (string & {}) | undefined;+        /**+         * The `<ViewTransition>` or its parent Component is mounted and there's no other `<ViewTransition>` with the same name being deleted.+         */+        onEnter?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * The `<ViewTransition>` or its parent Component is unmounted and there's no other `<ViewTransition>` with the same name being deleted.+         */+        onExit?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * This `<ViewTransition>` is being mounted and another `<ViewTransition>` instance with the same name is being unmounted elsewhere.+         */+        onShare?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        /**+         * The content of `<ViewTransition>` has changed either due to DOM mutations or because an inner child `<ViewTransition>` has resized.+         */+        onUpdate?: (instance: ViewTransitionInstance, types: Array<string>) => void | (() => void);+        ref?: Ref<ViewTransitionInstance> | undefined;+        /**+         * Combined with {@link className} if this `<ViewTransition>` is being mounted and another instance with the same name is being unmounted elsewhere.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        share?: ViewTransitionClass | undefined;+        /**+         * Combined with {@link className} if the content of this `<ViewTransition>` has changed either due to DOM mutations or because an inner child has resized.+         * `"none"` is a special value that deactivates the view transition name under that condition.+         */+        update?: ViewTransitionClass | undefined;     }@@ -84,82 +102,27 @@     /**-     * Similar to `useTransition` but allows uses where hooks are not available.+     * Opt-in for using {@link https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API View Transitions} in React.+     * View Transitions only trigger for async updates like {@link startTransition}, {@link useDeferredValue}, Actions or <{@link Suspense}> revealing from fallback to content.+     * Synchronous updates provide an opt-out but also guarantee that they commit immediately which View Transitions can't.      *-     * @param callback An _asynchronous_ function which causes state updates that can be deferred.+     * @see {@link https://react.dev/reference/react/ViewTransition `<ViewTransition>` reference documentation}      */-    export function startTransition(scope: () => Promise<VoidOrUndefinedOnly>): void;+    export const ViewTransition: ExoticComponent<ViewTransitionProps>; -    export function useOptimistic<State>(-        passthrough: State,-    ): [State, (action: State | ((pendingState: State) => State)) => void];-    export function useOptimistic<State, Action>(-        passthrough: State,-        reducer: (state: State, action: Action) => State,-    ): [State, (action: Action) => void];+    /**+     * @see {@link https://react.dev/reference/react/addTransitionType `addTransitionType` reference documentation}+     */+    export function addTransitionType(type: string): void; -    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES {-        cleanup: () => VoidOrUndefinedOnly;+    // @enableFragmentRefs+    export interface FragmentInstance {}++    export interface FragmentProps {+        ref?: Ref<FragmentInstance> | undefined;     } -    export function useActionState<State>(-        action: (state: Awaited<State>) => State | Promise<State>,-        initialState: Awaited<State>,-        permalink?: string,-    ): [state: Awaited<State>, dispatch: () => void, isPending: boolean];-    export function useActionState<State, Payload>(-        action: (state: Awaited<State>, payload: Payload) => State | Promise<State>,-        initialState: Awaited<State>,-        permalink?: string,-    ): [state: Awaited<State>, dispatch: (payload: Payload) => void, isPending: boolean];--    interface DOMAttributes<T> {-        // Transition Events-        onTransitionCancel?: TransitionEventHandler<T> | undefined;-        onTransitionCancelCapture?: TransitionEventHandler<T> | undefined;-        onTransitionRun?: TransitionEventHandler<T> | undefined;-        onTransitionRunCapture?: TransitionEventHandler<T> | undefined;-        onTransitionStart?: TransitionEventHandler<T> | undefined;-        onTransitionStartCapture?: TransitionEventHandler<T> | undefined;-    }--    type ToggleEventHandler<T = Element> = EventHandler<ToggleEvent<T>>;--    interface HTMLAttributes<T> {-        popover?: "" | "auto" | "manual" | "hint" | undefined;-        popoverTargetAction?: "toggle" | "show" | "hide" | undefined;-        popoverTarget?: string | undefined;-        onToggle?: ToggleEventHandler<T> | undefined;-        onBeforeToggle?: ToggleEventHandler<T> | undefined;-    }--    interface ToggleEvent<T = Element> extends SyntheticEvent<T, NativeToggleEvent> {-        oldState: "closed" | "open";-        newState: "closed" | "open";-    }--    interface LinkHTMLAttributes<T> {-        precedence?: string | undefined;-    }--    interface StyleHTMLAttributes<T> {-        href?: string | undefined;-        precedence?: string | undefined;-    }--    /**-     * @internal Use `Awaited<ReactNode>` instead-     */-    // Helper type to enable `Awaited<ReactNode>`.-    // Must be a copy of the non-thenables of `ReactNode`.-    type AwaitedReactNode =-        | ReactElement-        | string-        | number-        | Iterable<AwaitedReactNode>-        | ReactPortal-        | boolean-        | null-        | undefined;-    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {-        promises: Promise<AwaitedReactNode>;-        bigints: bigint;+    interface SubmitEvent<T = Element> extends SyntheticEvent<T, NativeSubmitEvent> {+        /**+         * Only available in react@canary+         */+        submitter: HTMLElement | null;     }
ts5.0/experimental.d.ts +77 lines
--- +++ @@ -45,2 +45,3 @@     export interface SuspenseProps {+        // @enableCPUSuspense         /**@@ -50,9 +51,12 @@          */-        unstable_expectedLoadTime?: number | undefined;+        defer?: boolean | undefined;     } -    export type SuspenseListRevealOrder = "forwards" | "backwards" | "together";-    export type SuspenseListTailMode = "collapsed" | "hidden";+    export type SuspenseListRevealOrder = "forwards" | "backwards" | "together" | "independent";+    export type SuspenseListTailMode = "collapsed" | "hidden" | "visible";      export interface SuspenseListCommonProps {+    }++    interface DirectionalSuspenseListProps extends SuspenseListCommonProps {         /**@@ -64,10 +68,8 @@          */-        children: ReactElement | Iterable<ReactElement>;-    }--    interface DirectionalSuspenseListProps extends SuspenseListCommonProps {+        children: Iterable<ReactElement> | AsyncIterable<ReactElement>;         /**          * Defines the order in which the `SuspenseList` children should be revealed.+         * @default "forwards"          */-        revealOrder: "forwards" | "backwards";+        revealOrder?: "forwards" | "backwards" | "unstable_legacy-backwards" | undefined;         /**@@ -75,5 +77,7 @@          *-         * - By default, `SuspenseList` will show all fallbacks in the list.          * - `collapsed` shows only the next fallback in the list.-         * - `hidden` doesn’t show any unloaded items.+         * - `hidden` doesn't show any unloaded items.+         * - `visible` shows all fallbacks in the list.+         *+         * @default "hidden"          */@@ -83,2 +87,3 @@     interface NonDirectionalSuspenseListProps extends SuspenseListCommonProps {+        children: ReactNode;         /**@@ -86,3 +91,3 @@          */-        revealOrder?: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps["revealOrder"]> | undefined;+        revealOrder: Exclude<SuspenseListRevealOrder, DirectionalSuspenseListProps["revealOrder"]>;         /**@@ -90,3 +95,3 @@          */-        tail?: never | undefined;+        tail?: never;     }@@ -108,10 +113,2 @@ -    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type-    export function experimental_useEffectEvent<T extends Function>(event: T): T;--    /**-     * Warning: Only available in development builds.-     */-    function captureOwnerStack(): string | null;-     type Reference = object;@@ -125,7 +122,62 @@ -    export interface HTMLAttributes<T> {-        /**-         * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert}-         */-        inert?: boolean | undefined;+    // @enableGestureTransition+    // Implemented by the specific renderer e.g. `react-dom`.+    // Keep in mind that augmented interfaces merge their JSDoc so if you put+    // JSDoc here and in the renderer, the IDE will display both.+    export interface GestureProvider {}+    export interface GestureOptions {+        rangeStart?: number | undefined;+        rangeEnd?: number | undefined;+    }+    export type GestureOptionsRequired = {+        [P in keyof GestureOptions]-?: NonNullable<GestureOptions[P]>;+    };+    /** */+    export function unstable_startGestureTransition(+        provider: GestureProvider,+        scope: () => void,+        options?: GestureOptions,+    ): () => void;++    interface ViewTransitionProps {+        onGestureEnter?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureExit?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureShare?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+        onGestureUpdate?: (+            timeline: GestureProvider,+            options: GestureOptionsRequired,+            instance: ViewTransitionInstance,+            types: Array<string>,+        ) => void | (() => void);+    }++    // @enableSrcObject+    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_IMG_SRC_TYPES {+        srcObject: Blob;+    }++    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_MEDIA_SRC_TYPES {+        srcObject: Blob | MediaSource | MediaStream;+    }++    // @enableOptimisticKey+    export const optimisticKey: unique symbol;++    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES {+        optimisticKey: typeof optimisticKey;     }
ts5.0/global.d.ts +5 lines
--- +++ @@ -20,2 +20,3 @@ interface PointerEvent extends Event {}+interface SubmitEvent extends Event {} interface ToggleEvent extends Event {}@@ -161 +162,5 @@ interface TrustedHTML {}++interface Blob {}+interface MediaStream {}+interface MediaSource {}
ts5.0/index.d.ts +612 lines
--- +++ @@ -7,3 +7,2 @@ import * as CSS from "csstype";-import * as PropTypes from "prop-types"; @@ -19,2 +18,4 @@ type NativePointerEvent = PointerEvent;+type NativeSubmitEvent = SubmitEvent;+type NativeToggleEvent = ToggleEvent; type NativeTransitionEvent = TransitionEvent;@@ -35,2 +36,21 @@ declare const UNDEFINED_VOID_ONLY: unique symbol;++/**+ * @internal Use `Awaited<ReactNode>` instead+ */+// Helper type to enable `Awaited<ReactNode>`.+// Must be a copy of the non-thenables of `ReactNode`.+type AwaitedReactNode =+    | React.ReactElement+    | string+    | number+    | bigint+    | Iterable<React.ReactNode>+    | React.ReactPortal+    | boolean+    | null+    | undefined+    | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[+        keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES+    ]; @@ -96,4 +116,3 @@      * Similar to {@link JSXElementConstructor}, but with extra properties like-     * {@link FunctionComponent.defaultProps defaultProps } and-     * {@link ComponentClass.contextTypes contextTypes}.+     * {@link FunctionComponent.defaultProps defaultProps }.      *@@ -110,4 +129,3 @@      * Similar to {@link ComponentType}, but without extra properties like-     * {@link FunctionComponent.defaultProps defaultProps } and-     * {@link ComponentClass.contextTypes contextTypes}.+     * {@link FunctionComponent.defaultProps defaultProps }.      *@@ -118,22 +136,7 @@             props: P,-            /**-             * @deprecated-             *-             * @see {@link https://legacy.reactjs.org/docs/legacy-context.html#referencing-context-in-stateless-function-components React Docs}-             */-            deprecatedLegacyContext?: any,         ) => ReactElement<any, any> | null)-        | (new(-            props: P,-            /**-             * @deprecated-             *-             * @see {@link https://legacy.reactjs.org/docs/legacy-context.html#referencing-context-in-lifecycle-methods React Docs}-             */-            deprecatedLegacyContext?: any,-        ) => Component<any, any>);--    /**-     * A readonly ref container where {@link current} cannot be mutated.-     *+        // constructor signature must match React.Component+        | (new(props: P, context: any) => Component<any, any>);++    /**      * Created by {@link createRef}, or {@link useRef} when passed `null`.@@ -154,3 +157,3 @@          */-        readonly current: T | null;+        current: T;     }@@ -177,2 +180,3 @@             | void+            | (() => VoidOrUndefinedOnly)             | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[@@ -189,18 +193,11 @@ -    type Ref<T> = RefCallback<T> | RefObject<T> | null;-    /**-     * A legacy implementation of refs where you can pass a string to a ref prop.-     *-     * @see {@link https://react.dev/reference/react/Component#refs React Docs}-     *-     * @example-     *-     * ```tsx-     * <div ref="myRef" />-     * ```-     */-    // TODO: Remove the string ref special case from `PropsWithRef` once we remove LegacyRef-    type LegacyRef<T> = string | Ref<T>;--    /**+    type Ref<T> = RefCallback<T> | RefObject<T | null> | null;+    /**+     * @deprecated Use `Ref` instead. String refs are no longer supported.+     * If you're typing a library with support for React versions with string refs, use `RefAttributes<T>['ref']` instead.+     */+    type LegacyRef<T> = Ref<T>;+    /**+     * @deprecated Use `ComponentRef<T>` instead+     *      * Retrieves the type of the 'ref' prop for a given component type or tag name.@@ -224,14 +221,6 @@             | ForwardRefExoticComponent<any>-            | { new(props: any): Component<any> }-            | ((props: any, deprecatedLegacyContext?: any) => ReactElement | null)+            | { new(props: any, context: any): Component<any> }+            | ((props: any) => ReactElement | null)             | keyof JSX.IntrinsicElements,-    > =-        // need to check first if `ref` is a valid prop for [email protected]-        // otherwise it will infer `{}` instead of `never`-        "ref" extends keyof ComponentPropsWithRef<C>-            ? NonNullable<ComponentPropsWithRef<C>["ref"]> extends RefAttributes<-                infer Instance-            >["ref"] ? Instance-            : never-            : never;+    > = ComponentRef<C>; @@ -239,2 +228,4 @@ +    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES {}+     /**@@ -244,3 +235,9 @@      */-    type Key = string | number | bigint;+    type Key =+        | string+        | number+        | bigint+        | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES[+            keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_KEY_TYPES+        ]; @@ -303,3 +300,3 @@          */-        ref?: LegacyRef<T> | undefined;+        ref?: Ref<T> | undefined;     }@@ -328,3 +325,3 @@     interface ReactElement<-        P = any,+        P = unknown,         T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>,@@ -344,3 +341,9 @@ +    /**+     * @deprecated Use `ReactElement<P, React.FunctionComponent<P>>`+     */     interface FunctionComponentElement<P> extends ReactElement<P, FunctionComponent<P>> {+        /**+         * @deprecated Use `element.props.ref` instead.+         */         ref?: ("ref" extends keyof P ? P extends { ref?: infer R | undefined } ? R : never : never) | undefined;@@ -348,5 +351,14 @@ +    /**+     * @deprecated Use `ReactElement<P, React.ComponentClass<P>>`+     */     type CElement<P, T extends Component<P, ComponentState>> = ComponentElement<P, T>;+    /**+     * @deprecated Use `ReactElement<P, React.ComponentClass<P>>`+     */     interface ComponentElement<P, T extends Component<P, ComponentState>> extends ReactElement<P, ComponentClass<P>> {-        ref?: LegacyRef<T> | undefined;+        /**+         * @deprecated Use `element.props.ref` instead.+         */+        ref?: Ref<T> | undefined;     }@@ -359,2 +371,5 @@     // string fallback for custom web-components+    /**+     * @deprecated Use `ReactElement<P, string>`+     */     interface DOMElement<P extends HTMLAttributes<T> | SVGAttributes<T>, T extends Element>@@ -362,3 +377,6 @@     {-        ref: LegacyRef<T>;+        /**+         * @deprecated Use `element.props.ref` instead.+         */+        ref: Ref<T>;     }@@ -369,3 +387,3 @@     interface DetailedReactHTMLElement<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMElement<P, T> {-        type: keyof ReactHTML;+        type: HTMLElementType;     }@@ -374,3 +392,3 @@     interface ReactSVGElement extends DOMElement<SVGAttributes<SVGElement>, SVGElement> {-        type: keyof ReactSVG;+        type: SVGElementType;     }@@ -380,70 +398,2 @@     }--    //-    // Factories-    // ------------------------------------------------------------------------    /** @deprecated */-    type Factory<P> = (props?: Attributes & P, ...children: ReactNode[]) => ReactElement<P>;--    /** @deprecated */-    type SFCFactory<P> = FunctionComponentFactory<P>;--    /** @deprecated */-    type FunctionComponentFactory<P> = (-        props?: Attributes & P,-        ...children: ReactNode[]-    ) => FunctionComponentElement<P>;--    /** @deprecated */-    type ComponentFactory<P, T extends Component<P, ComponentState>> = (-        props?: ClassAttributes<T> & P,-        ...children: ReactNode[]-    ) => CElement<P, T>;--    /** @deprecated */-    type CFactory<P, T extends Component<P, ComponentState>> = ComponentFactory<P, T>;-    /** @deprecated */-    type ClassicFactory<P> = CFactory<P, ClassicComponent<P, ComponentState>>;--    /** @deprecated */-    type DOMFactory<P extends DOMAttributes<T>, T extends Element> = (-        props?: ClassAttributes<T> & P | null,-        ...children: ReactNode[]-    ) => DOMElement<P, T>;--    /** @deprecated */-    interface HTMLFactory<T extends HTMLElement> extends DetailedHTMLFactory<AllHTMLAttributes<T>, T> {}--    /** @deprecated */-    interface DetailedHTMLFactory<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMFactory<P, T> {-        (props?: ClassAttributes<T> & P | null, ...children: ReactNode[]): DetailedReactHTMLElement<P, T>;-    }--    /** @deprecated */-    interface SVGFactory extends DOMFactory<SVGAttributes<SVGElement>, SVGElement> {-        (
… 1499 more lines (truncated)
webpack-cli npm
7.2.2 24d ago nominal
BURST ×8
latest 7.2.2 versions 133 maintainers 6
5.1.3
5.1.4
6.0.0
6.0.1
7.0.0
7.0.1
7.0.2
7.0.3
7.1.0
7.2.0
7.2.1
7.2.2
BURST
5 releases in 41m: 1.3.4, 1.3.5, 1.3.7, 1.3.8, 1.3.9
info · registry-verified · 2017-10-05 · 8y ago
BURST
2 releases in 47m: 1.4.1, 1.4.2
info · registry-verified · 2017-10-22 · 8y ago
BURST
2 releases in 30m: 1.4.3, 1.4.4
info · registry-verified · 2017-10-26 · 8y ago
BURST
2 releases in 25m: 1.4.7, 1.4.8
info · registry-verified · 2017-12-06 · 8y ago
BURST
2 releases in 32m: 1.5.1, 1.5.2
info · registry-verified · 2017-12-09 · 8y ago
BURST
2 releases in 4m: 2.0.3, 2.0.4
info · registry-verified · 2018-01-14 · 8y ago
BURST
2 releases in 24m: 2.1.1, 2.1.2
info · registry-verified · 2018-04-30 · 8y ago
BURST
2 releases in 54m: 3.2.2, 3.2.3
info · registry-verified · 2019-02-05 · 7y ago
release diff 7.2.1 → 7.2.2
+0 added · -0 removed · ~2 modified
bin/cli.js +12 lines
--- +++ @@ -3,2 +3,14 @@ "use strict";++// `module.enableCompileCache` is only available on Node.js >= 22.8.0+// eslint-disable-next-line n/no-unsupported-features/node-builtins+const { enableCompileCache } = require("node:module");++if (enableCompileCache) {+  try {+    enableCompileCache();+  } catch {+    // Ignore errors+  }+} 
package.json +1 lines
--- +++ @@ -2,3 +2,3 @@   "name": "webpack-cli",-  "version": "7.2.1",+  "version": "7.2.2",   "description": "CLI for webpack & friends",
pypi — by downloads
anyio pypi
4.14.2 1mo ago incident on record
YANKBURST ×2
latest 4.14.2 versions 70 maintainers 1
4.6.2
4.7.0
4.8.0
4.9.0
4.10.0
4.11.0
4.12.0
4.12.1
4.13.0
4.14.0
4.14.1
4.14.2
YANK
4.6.2 marked yanked (still downloadable)
high · registry-verified · 2024-10-13 · 1y ago
BURST
2 releases in 5m: 4.5.1, 4.6.1
info · registry-verified · 2024-10-13 · 1y ago
BURST
2 releases in 3m: 4.5.2, 4.6.2
info · registry-verified · 2024-10-13 · 1y ago
release diff 4.14.1 → 4.14.2
artifact too large or unavailable
attrs pypi
26.1.0 5mo ago incident on record
YANK
latest 26.1.0 versions 36 maintainers 1
22.1.0
22.2.0
23.1.0
23.2.0
24.1.0
24.2.0
24.3.0
25.1.0
25.2.0
25.3.0
25.4.0
26.1.0
YANK
21.1.0 marked yanked (still downloadable)
high · registry-verified · 2021-05-06 · 5y ago
release diff 25.4.0 → 26.1.0
+3 added · -2 removed · ~44 modified
bench/test_benchmarks.py +58 lines
--- +++ @@ -5,2 +5,5 @@ from __future__ import annotations++import functools+import time @@ -174 +177,56 @@         at(c)+++class TestCachedProperties:+    @attrs.define+    class Slotted:+        x: int = 0++        @functools.cached_property+        def cached(self):+            time.sleep(0.1)+            return 42++    @attrs.define(slots=False)+    class Unslotted:+        x: int = 0++        @functools.cached_property+        def cached(self):+            time.sleep(0.1)+            return 42++    def test_first_access(self):+        """+        Benchmark first access to a cached property (computation + storage).+        """+        for _ in range(ROUNDS):+            c = self.Slotted(42)+            _ = c.cached++    def test_repeated_access(self):+        """+        Benchmark repeated access to a cached property (should use stored+        value).+        """+        c = self.Slotted(42)+        _ = c.cached  # Prime the cache++        for _ in range(ROUNDS):+            _ = c.cached++    def test_create_cached_property_class(self):+        """+        Benchmark creating a class with a cached property+        """+        for _ in range(ROUNDS):++            @attrs.define+            class LocalC:+                x: int+                y: str+                z: dict[str, int]++                @functools.cached_property+                def cached(self):+                    return 42
pyproject.toml +10 lines
--- +++ @@ -131,2 +131,7 @@ [[tool.sponcon.sponsors]]+title = "Kraken Tech"+url = "https://kraken.tech/"+img = "Kraken.svg"++[[tool.sponcon.sponsors]] title = "Privacy Solutions"@@ -139,2 +144,7 @@ img = "FilePreviews.svg"++[[tool.sponcon.sponsors]]+title = "TestMu AI"+url = "https://www.testmuai.com/?utm_medium=sponsor&utm_source=structlog"+img = "TestMu-AI.svg" 
src/attr/_make.py +62 lines
--- +++ @@ -465,2 +465,11 @@ +    # Resolve default field alias before executing field_transformer, so that+    # the transformer receives fully populated Attribute objects with usable+    # alias values.+    for a in attrs:+        if not a.alias:+            # Evolve is very slow, so we hold our nose and do it dirty.+            _OBJ_SETATTR.__get__(a)("alias", _default_init_alias_for(a.name))+            _OBJ_SETATTR.__get__(a)("alias_is_default", True)+     if field_transformer is not None:@@ -482,9 +491,8 @@ -    # Resolve default field alias after executing field_transformer.-    # This allows field_transformer to differentiate between explicit vs-    # default aliases and supply their own defaults.+    # Resolve default field alias for any new attributes that the+    # field_transformer may have added without setting an alias.     for a in attrs:         if not a.alias:-            # Evolve is very slow, so we hold our nose and do it dirty.             _OBJ_SETATTR.__get__(a)("alias", _default_init_alias_for(a.name))+            _OBJ_SETATTR.__get__(a)("alias_is_default", True) @@ -571,3 +579,3 @@     """-    if isinstance(self, BaseException) and name in ("__notes__",):+    if isinstance(self, BaseException) and name == "__notes__":         BaseException.__delattr__(self, name)@@ -1098,5 +1106,3 @@     def add_replace(self):-        self._cls_dict["__replace__"] = self._add_method_dunders(-            lambda self, **changes: evolve(self, **changes)-        )+        self._cls_dict["__replace__"] = self._add_method_dunders(evolve)         return self@@ -1886,3 +1892,3 @@     """-    Return the tuple of *attrs* attributes for a class.+    Return the tuple of *attrs* attributes for a class or instance. @@ -1892,6 +1898,6 @@     Args:-        cls (type): Class to introspect.+        cls (type): Class or instance to introspect.      Raises:-        TypeError: If *cls* is not a class.+        TypeError: If *cls* is neither a class nor an *attrs* instance. @@ -1906,2 +1912,3 @@     .. versionchanged:: 23.1.0 Add support for generic classes.+    .. versionchanged:: 26.1.0 Add support for instances.     """@@ -1910,4 +1917,8 @@     if generic_base is None and not isinstance(cls, type):-        msg = "Passed object must be a class."-        raise TypeError(msg)+        type_ = type(cls)+        if getattr(type_, "__attrs_attrs__", None) is None:+            msg = "Passed object must be a class or attrs instance."+            raise TypeError(msg)++        return fields(type_) @@ -2018,3 +2029,3 @@         if a.on_setattr is not None:-            if frozen is True:+            if frozen is True and a.on_setattr is not setters.NO_OP:                 msg = "Frozen classes can't use on_setattr."@@ -2431,2 +2442,4 @@       any explicit overrides and default private-attribute-name handling.+    - ``alias_is_default`` (`bool`): Whether the ``alias`` was automatically+      generated (``True``) or explicitly provided by the user (``False``).     - ``inherited`` (`bool`): Whether or not that attribute has been inherited@@ -2456,2 +2469,3 @@     .. versionadded:: 22.2.0 *alias*+    .. versionadded:: 26.1.0 *alias_is_default* @@ -2480,2 +2494,3 @@         "alias",+        "alias_is_default",     )@@ -2502,2 +2517,3 @@         alias=None,+        alias_is_default=None,     ):@@ -2536,2 +2552,6 @@         bound_setattr("alias", alias)+        bound_setattr(+            "alias_is_default",+            alias is None if alias_is_default is None else alias_is_default,+        ) @@ -2571,2 +2591,3 @@             ca.alias,+            ca.alias is None,         )@@ -2588,2 +2609,16 @@         new._setattrs(changes.items())++        if "alias" in changes and "alias_is_default" not in changes:+            # Explicit alias provided -- no longer the default.+            _OBJ_SETATTR.__get__(new)("alias_is_default", False)+        elif (+            "name" in changes+            and "alias" not in changes+            # Don't auto-generate alias if the user picked picked the old one.+            and self.alias_is_default+        ):+            # Name changed, alias was auto-generated -- update it.+            _OBJ_SETATTR.__get__(new)(+                "alias", _default_init_alias_for(new.name)+            ) @@ -2605,2 +2640,13 @@         """+        if len(state) < len(self.__slots__):+            # Pre-26.1.0 pickle without alias_is_default -- infer it+            # heuristically.+            state_dict = dict(zip(self.__slots__, state))+            alias_is_default = state_dict.get(+                "alias"+            ) is None or state_dict.get("alias") == _default_init_alias_for(+                state_dict["name"]+            )+            state = (*state, alias_is_default)+         self._setattrs(zip(self.__slots__, state))@@ -2628,3 +2674,3 @@         validator=None,-        repr=True,+        repr=(name != "alias_is_default"),         cmp=None,@@ -3089,5 +3135,3 @@         else:-            self.__call__ = lambda value, instance, field: self.converter(-                value, instance, field-            )+            self.__call__ = self.converter 
src/attr/exceptions.py +4 lines
--- +++ @@ -3,4 +3,2 @@ from __future__ import annotations--from typing import ClassVar @@ -18,4 +16,6 @@ -    msg = "can't set attribute"-    args: ClassVar[tuple[str]] = [msg]+    def __init__(self):+        msg = "can't set attribute"+        super().__init__(msg)+        self.msg = msg 
src/attr/validators.py +4 lines
--- +++ @@ -81,3 +81,5 @@     .. versionadded:: 21.3.0-    """+    .. versionchanged:: 26.1.0 The contextmanager is nestable.+    """+    prev = get_run_validators()     set_run_validators(False)@@ -86,3 +88,3 @@     finally:-        set_run_validators(True)+        set_run_validators(prev) 
tests/test_functional.py +14 lines
--- +++ @@ -132,2 +132,3 @@                 inherited=False,+                alias_is_default=True,             ),@@ -145,2 +146,3 @@                 inherited=False,+                alias_is_default=True,             ),@@ -203,2 +205,3 @@                 inherited=False,+                alias_is_default=True,             ),@@ -216,2 +219,3 @@                 inherited=False,+                alias_is_default=True,             ),@@ -262,9 +266,16 @@ -        with pytest.raises(FrozenInstanceError) as e:+        with pytest.raises(+            FrozenInstanceError, match="can't set attribute"+        ) as e:             frozen.x = 2 -        with pytest.raises(FrozenInstanceError) as e:+        assert e.value.msg == e.value.args[0] == "can't set attribute"+        assert 1 == frozen.x++        with pytest.raises(+            FrozenInstanceError, match="can't set attribute"+        ) as e:             del frozen.x -        assert e.value.args[0] == "can't set attribute"+        assert e.value.msg == e.value.args[0] == "can't set attribute"         assert 1 == frozen.x
tests/test_hooks.py +145 lines
--- +++ @@ -180,3 +180,3 @@             "metadata=mappingproxy({'field_order': 1}), type='int', converter=None, "-            "kw_only=False, inherited=False, on_setattr=None, alias=None)",+            "kw_only=False, inherited=False, on_setattr=None, alias='x')",         ) == e.value.args@@ -234,2 +234,146 @@         assert ["x"] == [a.name for a in attr.fields(Base)]++    def test_hook_alias_available(self):+        """+        The field_transformer receives attributes with default aliases+        already resolved, not None.++        Regression test for #1479.+        """+        seen = []++        def hook(cls, attribs):+            seen[:] = [(a.name, a.alias, a.alias_is_default) for a in attribs]+            return attribs++        @attr.s(auto_attribs=True, field_transformer=hook)+        class C:+            _private: int+            _explicit: int = attr.ib(alias="_explicit")+            public: int++        assert [+            ("_private", "private", True),+            ("_explicit", "_explicit", False),+            ("public", "public", True),+        ] == seen++    def test_hook_evolve_name_updates_auto_alias(self):+        """+        When a field_transformer evolves a field's name, the alias is+        automatically updated if it was auto-generated.++        Regression test for #1479.+        """++        def hook(cls, attribs):+            return [a.evolve(name="renamed") for a in attribs]++        @attr.s(auto_attribs=True, field_transformer=hook)+        class C:+            _original: int++        f = attr.fields(C).renamed++        assert "renamed" == f.alias+        assert f.alias_is_default is True++    def test_hook_evolve_name_keeps_explicit_alias(self):+        """+        When a field_transformer evolves a field's name but the field had+        an explicit alias, the alias is preserved.++        Regression test for #1479.+        """++        def hook(cls, attribs):+            return [a.evolve(name="renamed") for a in attribs]++        @attr.s(auto_attribs=True, field_transformer=hook)+        class C:+            original: int = attr.ib(alias="my_alias")++        f = attr.fields(C).renamed++        assert "my_alias" == f.alias+        assert f.alias_is_default is False++    def test_hook_new_field_without_alias(self):+        """+        When a field_transformer adds a brand-new field without setting an+        alias, the post-transformer alias resolution fills it in.++        Regression test for #1479.+        """++        def hook(cls, attribs):+            return [+                *list(attribs),+                attr.Attribute(+                    name="_extra",+                    default=0,+                    validator=None,+                    repr=True,+                    cmp=None,+                    hash=None,+                    init=True,+                    metadata={},+                    type=int,+                    converter=None,+                    kw_only=False,+                    eq=True,+                    eq_key=None,+                    order=True,+                    order_key=None,+                    on_setattr=None,+                    alias=None,+                    inherited=False,+                ),+            ]++        @attr.s(auto_attribs=True, field_transformer=hook)+        class C:+            x: int++        f = attr.fields(C)._extra++        assert "extra" == f.alias+        assert f.alias_is_default is True++    def test_hook_explicit_alias_matching_default(self):+        """+        When a user explicitly sets an alias that happens to equal the+        auto-generated default, alias_is_default is still False.++        Regression test for #1479.+        """++        @attr.s(auto_attribs=True)+        class C:+            _private: int = attr.ib(alias="private")++        f = attr.fields(C)._private++        assert "private" == f.alias+        assert f.alias_is_default is False++    def test_hook_evolve_alias_sets_not_default(self):+        """+        When a field_transformer uses evolve() to set an explicit alias,+        alias_is_default becomes False.++        Regression test for #1479.+        """++        def hook(cls, attribs):+            return [a.evolve(alias="custom") for a in attribs]++        @attr.s(auto_attribs=True, field_transformer=hook)+        class C:+            x: int++        f = attr.fields(C).x++        assert "custom" == f.alias+        assert f.alias_is_default is False 
tests/test_make.py +113 lines
--- +++ @@ -11,3 +11,5 @@ import itertools+import pickle import sys+import types import unicodedata@@ -118,5 +120,3 @@ -    @pytest.mark.parametrize(-        "wrap", [lambda v: v, lambda v: [v], lambda v: and_(v)]-    )+    @pytest.mark.parametrize("wrap", [lambda v: v, lambda v: [v], and_])     def test_validator_decorator(self, wrap):@@ -247,3 +247,3 @@             "metadata=mappingproxy({}), type=None, converter=None, "-            "kw_only=False, inherited=False, on_setattr=None, alias=None)",+            "kw_only=False, inherited=False, on_setattr=None, alias='y')",         ) == e.value.args@@ -1552,8 +1552,15 @@         """-        Raises `TypeError` on non-classes.-        """-        with pytest.raises(TypeError) as e:-            fields(C())--        assert "Passed object must be a class." == e.value.args[0]+        Returns the class fields for *attrs* instances too.+        """+        assert fields(C()) is fields(C)++    def test_handler_non_attrs_instance(self):+        """+        Raises `TypeError` on non-*attrs* instances.+        """+        with pytest.raises(+            TypeError,+            match=r"Passed object must be a class or attrs instance\.",+        ):+            fields(object()) @@ -1777,5 +1784,3 @@         """-        C = make_class(-            "C", {"x": attr.ib(converter=lambda v: int(v))}, frozen=True-        )+        C = make_class("C", {"x": attr.ib(converter=int)}, frozen=True)         C("1")@@ -2391,2 +2396,97 @@ +    def test_alias_is_default(self):+        """+        alias_is_default is True for auto-generated aliases and False for+        explicitly provided ones -- even if the explicit value matches the+        auto-generated default.+        """++        @attrs.define+        class C:+            auto: int+            _private_auto: int+            explicit: int = attrs.field(alias="custom")+            _matches_default: int = attrs.field(alias="matches_default")++        fields = attr.fields_dict(C)++        assert fields["auto"].alias_is_default is True+        assert fields["_private_auto"].alias_is_default is True+        assert fields["explicit"].alias_is_default is False+        assert fields["_matches_default"].alias_is_default is False++    def test_alias_is_default_pickle_roundtrip(self):+        """+        alias_is_default survives pickle round-tripping.+        """++        @attrs.define+        class C:+            auto: int+            explicit: int = attrs.field(alias="custom")++        fields = attr.fields(C)++        for a in fields:+            restored = pickle.loads(pickle.dumps(a))++            assert a.alias == restored.alias+            assert a.alias_is_default == restored.alias_is_default++    X = (+        b"\x80\x05\x95_\x00\x00\x00\x00\x00\x00\x00\x8c\nattr._make\x94\x8c\tAttrib"+        b"ute\x94\x93\x94)\x81\x94(\x8c\x01x\x94h\x00\x8c\x08_Nothing\x94\x93"+        b"\x94K\x01\x85\x94R\x94N\x88\x88N\x88NN\x88}\x94\x8c\x08builtins\x94"+        b"\x8c\x03int\x94\x93\x94N\x89\x89Nh\x04t\x94b."+    )+    Y = (+        b"\x80\x05\x95b\x00\x00\x00\x00\x00\x00\x00\x8c\nattr._make\x94\x8c\tAttrib"+        b"ute\x94\x93\x94)\x81\x94(\x8c\x02_y\x94h\x00\x8c\x08_Nothing\x94"+        b"\x93\x94K\x01\x85\x94R\x94N\x88\x88N\x88NN\x88}\x94\x8c\x08builtins"+        b"\x94\x8c\x03int\x94\x93\x94N\x89\x89N\x8c\x01y\x94t\x94b."+    )+    Z = (+        b"\x80\x05\x95c\x00\x00\x00\x00\x00\x00\x00\x8c\nattr._make\x94\x8c\tAttrib"+        b"ute\x94\x93\x94)\x81\x94(\x8c\x01z\x94h\x00\x8c\x08_Nothing\x94\x93"+        b"\x94K\x01\x85\x94R\x94N\x88\x88N\x88NN\x88}\x94\x8c\x08builtins\x94"+        b"\x8c\x03int\x94\x93\x94N\x89\x89N\x8c\x03_z_\x94t\x94b."+    )++    @pytest.mark.parametrize(+        ("pickle_data", "name", "alias", "alias_is_default"),+        [+            (X, "x", "x", True),+            (Y, "_y", "y", True),+            (Z, "z", "_z_", False),+        ],+    )+    def test_can_unpickle_25_3_attributes(+        self, pickle_data, name, alias, alias_is_default+    ):+        """+        Can unpickle attributes created in 25.3.+        """++        assert Attribute(+            name=name,+            alias=alias,+            alias_is_default=alias_is_default,+            default=attrs.NOTHING,+            validator=None,+            repr=True,+            cmp=None,+            eq=True,+            eq_key=None,+            order=True,+            order_key=None,+            hash=None,+            init=True,+            metadata=types.MappingProxyType({}),+            type=int,+            converter=None,+            kw_only=False,+            inherited=False,+            on_setattr=None,+        ) == pickle.loads(pickle_data)+ 
tests/test_pyright.py +1 lines
--- +++ @@ -53,3 +53,3 @@             '"(self: DefineConverter, with_converter: str | Buffer | '-            'SupportsInt | SupportsIndex | SupportsTrunc) -> None"',+            'SupportsInt | SupportsIndex) -> None"',         ),
tests/test_setattr.py +10 lines
--- +++ @@ -223,2 +223,12 @@ +    @pytest.mark.parametrize("nop", [None, setters.NO_OP])+    def test_frozen_on_setattr_nops(self, nop):+        """+        on_setattr on frozen classes can be used for None and NO_OP.+        """++        @attr.s(frozen=True)+        class C:+            x = attr.ib(on_setattr=nop)+     def test_setattr_reset_if_no_custom_setattr(self, slots):
tests/test_validators.py +24 lines
--- +++ @@ -7,2 +7,3 @@ import re+import sys @@ -99,2 +100,18 @@ +    def test_disabled_ctx_nested(self):+        """+        Nested contextmanagers restore correct state.+        """+        assert _config._run_validators is True++        with validator_module.disabled():+            assert _config._run_validators is False++            with validator_module.disabled():+                assert _config._run_validators is False++            assert _config._run_validators is False++        assert _config._run_validators is True+ @@ -229,6 +246,9 @@ -        assert (-            "'func' must be one of None, fullmatch, match, search."-            == ei.value.args[0]-        )+        if sys.version_info >= (3, 15):+            errmsg = (+                "'func' must be one of None, fullmatch, prefixmatch, search."+            )+        else:+            errmsg = "'func' must be one of None, fullmatch, match, search."+        assert errmsg == ei.value.args[0] 
tests/utils.py +1 lines
--- +++ @@ -66,2 +66,3 @@         alias=_default_init_alias_for(name),+        alias_is_default=True,     )
typing-examples/baseline.py +9 lines
--- +++ @@ -94,2 +94,11 @@     num: int = attrs.field(validator=attrs.validators.ge(0))++[email protected]+class ValidatedOptionalOverTuple:+    num: int | None = attrs.field(+        validator=attrs.validators.optional(+            (attrs.validators.instance_of(int), attrs.validators.ge(0))  # ty:ignore [invalid-argument-type]+        )+    ) 
certifi pypi
2026.7.22 1mo ago incident on record
critical-tier YANKBURST ×4
latest 2026.7.22 versions 76 maintainers 1 critical-tier (snapshotted)
2025.6.15
2025.7.9
2025.7.14
2025.8.3
2025.10.5
2025.11.12
2026.1.4
2026.2.25
2026.4.22
2026.5.20
2026.6.17
2026.7.22
YANK
2022.5.18 marked yanked (still downloadable)
high · registry-verified · 2022-05-18 · 4y ago
BURST
3 releases in 21m: 0.0.2, 0.0.3, 0.0.4
info · registry-verified · 2011-12-28 · 14y ago
BURST
2 releases in 2m: 0.0.5, 0.0.6
info · registry-verified · 2011-12-28 · 14y ago
BURST
2 releases in 39m: 2015.9.6, 2015.9.6.1
info · registry-verified · 2015-09-06 · 10y ago
BURST
2 releases in 4m: 2017.7.27, 2017.7.27.1
info · registry-verified · 2017-07-27 · 9y ago
release diff 2026.6.17 → 2026.7.22
+2 added · -0 removed · ~6 modified
certifi/__init__.py +1 lines
--- +++ @@ -3,2 +3,2 @@ __all__ = ["contents", "where"]-__version__ = "2026.06.17"+__version__ = "2026.07.22"
certifi/tests/__init__.py +0 lines
binary or empty diff
certifi/tests/test_certify.py +18 lines
--- +++ @@ -0,0 +1,18 @@+import os+import unittest++import certifi+++class TestCertifi(unittest.TestCase):+    def test_cabundle_exists(self) -> None:+        assert os.path.exists(certifi.where())++    def test_read_contents(self) -> None:+        content = certifi.contents()+        assert "-----BEGIN CERTIFICATE-----" in content++    def test_py_typed_exists(self) -> None:+        assert os.path.exists(+            os.path.join(os.path.dirname(certifi.__file__), 'py.typed')+        )
cffi pypi
2.1.1 18d ago incident on record
critical-tier YANKBURST ×3INSTALL-EXEC
latest 2.1.1 versions 80 maintainers 1 critical-tier (snapshotted)
1.14.3
1.14.4
1.14.5
1.14.6
1.15.0
1.15.1
1.16.0
1.17.0
1.17.1
2.0.0
2.1.0
2.1.1
YANK
1.0.2 marked yanked (still downloadable)
high · registry-verified · 2015-05-25 · 11y ago
BURST
2 releases in 20m: 0.8.4, 0.8.5
info · registry-verified · 2014-07-05 · 12y ago
BURST
2 releases in 41m: 1.4.0, 1.4.1
info · registry-verified · 2015-12-17 · 10y ago
BURST
2 releases in 21m: 1.9.0, 1.9.1
info · registry-verified · 2016-11-12 · 9y ago
INSTALL-EXEC
setup.py in sdist uses subprocess/exec (runs at pip install)
warn · snapshot-derived
release diff 2.1.0 → 2.1.1
+0 added · -0 removed · ~11 modified
doc/source/conf.py +1 lines
--- +++ @@ -47,3 +47,3 @@ # The full version, including alpha/beta/rc tags.-release = '2.1.0'+release = '2.1.1' 
pyproject.toml +1 lines
--- +++ @@ -9,3 +9,3 @@ name = "cffi"-version = "2.1.0"+version = "2.1.1" dependencies = [
src/c/test_c.py +1 lines
--- +++ @@ -68,3 +68,3 @@ import sys-assert __version__ == "2.1.0", ("This test_c.py file is for testing a version"+assert __version__ == "2.1.1", ("This test_c.py file is for testing a version"                                      " of cffi that differs from the one that we"
src/cffi/__init__.py +2 lines
--- +++ @@ -7,4 +7,4 @@ -__version__ = "2.1.0"-__version_info__ = (2, 1, 0)+__version__ = "2.1.1"+__version_info__ = (2, 1, 1) 
charset-normalizer pypi
3.5.1 7d ago incident on record
critical-tier YANK
latest 3.5.1 versions 65 maintainers 1 critical-tier (snapshotted)
3.4.0
3.4.1
3.4.2
3.4.3
3.4.4
3.4.5
3.4.6
3.4.7
3.4.8
3.4.9
3.5.0
3.5.1
YANK
3.4.8 marked yanked (still downloadable)
high · registry-verified · 2026-07-06 · 1mo ago
release diff 3.5.0 → 3.5.1
+0 added · -0 removed · ~11 modified
pyproject.toml +1 lines
--- +++ @@ -1,3 +1,3 @@ [build-system]-requires = ["setuptools>=68,<83.1"]+requires = ["setuptools>=68,<84.1"] build-backend = "backend"
src/charset_normalizer/api.py +6 lines
--- +++ @@ -469,4 +469,6 @@ -        # We might want to check the sequence again with the whole content-        # Only if initial MD tests passes+        mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0++        # We might want to check the sequence again with the whole content,+        # but only if initial MD tests passed.         if (@@ -475,2 +477,4 @@             and not is_multi_byte_decoder+            and mean_mess_ratio < threshold+            and early_stop_count < max_chunk_gave_up         ):@@ -488,3 +492,2 @@ -        mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0         if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up:
src/charset_normalizer/version.py +1 lines
--- +++ @@ -6,3 +6,3 @@ -__version__ = "3.5.0"+__version__ = "3.5.1" VERSION = __version__.split(".")
click pypi
8.4.2 1mo ago incident on record
YANKBURST
latest 8.4.2 versions 64 maintainers 1
8.1.7
8.1.8
8.2.0
8.2.1
8.2.2
8.3.0
8.3.1
8.3.2
8.3.3
8.4.0
8.4.1
8.4.2
YANK
8.2.2 marked yanked (still downloadable)
high · registry-verified · 2025-08-02 · 1y ago
BURST
2 releases in 5m: 0.5, 0.5.1
info · registry-verified · 2014-05-06 · 12y ago
release diff 8.4.1 → 8.4.2
+0 added · -1 removed · ~30 modified
tests/test_utils.py +74 lines · 3 flagged
--- +++ @@ -18,3 +18,2 @@ import click.utils-from click._compat import MAC from click._compat import WIN@@ -288,2 +287,7 @@ def _test_gen_func_fails():+    raise RuntimeError("This is a test.")+    yield  # unreachable, keeps this a generator function+++def _test_gen_func_yields_then_fails():     yield "test"@@ -317,6 +321,2 @@ @pytest.mark.skipif(WIN, reason="Different behavior on windows.")[email protected](-    MAC and sys.version_info >= (3, 13) and not sys._is_gil_enabled(),-    reason="Generator exception tests are flaky in Python 3.14t on macOS.",-) @pytest.mark.parametrize(@@ -456,2 +456,71 @@     )++[email protected](WIN, reason="Different behavior on windows.")+def test_echo_via_pager_yields_before_exception(monkeypatch, tmp_path):+    """A generator that yields then raises: click writes the partial output to+    the pager stream before propagating the exception.++    The pager file content is intentionally NOT asserted: pipe-drain timing+    between click and the pager subprocess is outside click's control+    (#2899, #3470). Spying on ``MaybeStripAnsi.write`` records what click sent+    to the pager, which is deterministic regardless of scheduling.+    """+    monkeypatch.setitem(os.environ, "PAGER", "cat")+    monkeypatch.setattr(click._termui_impl, "isatty", lambda x: True)++    writes: list[str] = []+    real_write = click._termui_impl.MaybeStripAnsi.write++    def spy(self, text):+        writes.append(text)+        return real_write(self, text)++    monkeypatch.setattr(click._termui_impl.MaybeStripAnsi, "write", spy)++    pager_out_tmp = tmp_path / "pager_out.txt"+    with (+        pager_out_tmp.open("w") as f,+        patch.object(subprocess, "Popen", partial(subprocess.Popen, stdout=f)),+        pytest.raises(RuntimeError, match="This is a test."),+    ):+        click.echo_via_pager(_test_gen_func_yields_then_fails())++    assert "".join(writes) == "test", (+        f"click should have written the yielded chunk before exception, got {writes!r}"+    )++[email protected][email protected](WIN, reason="Different behavior on windows.")[email protected]("_", range(1000))+def test_stress_echo_via_pager_exception_cleanup(_, monkeypatch, tmp_path):+    """Repeated exceptions during ``echo_via_pager`` must not leak subprocesses.++    Regression coverage for the cleanup path in ``_pipepager``'s exception+    handler (issue #2899, PR #3470). Each iteration spawns a real pager+    subprocess, raises before any data is written and check there is no leak.+    """+    monkeypatch.setitem(os.environ, "PAGER", "cat")+    monkeypatch.setattr(click._termui_impl, "isatty", lambda x: True)++    spawned: list[subprocess.Popen] = []+    real_popen = subprocess.Popen++    def tracking_popen(*args, **kwargs):+        p = real_popen(*args, **kwargs)+        spawned.append(p)+        return p++    pager_out_tmp = tmp_path / "pager_out.txt"+    with (+        pager_out_tmp.open("w") as f,+        patch.object(subprocess, "Popen", partial(tracking_popen, stdout=f)),+        pytest.raises(RuntimeError),+    ):+        click.echo_via_pager(_test_gen_func_fails())++    assert spawned, "pager subprocess was never started"+    for p in spawned:+        assert p.returncode is not None, "pager subprocess not reaped" 
docs/conf.py +1 lines
--- +++ @@ -33,2 +33,3 @@ }+myst_enable_extensions = ["attrs_block"] myst_heading_anchors = 3
pyproject.toml +2 lines
--- +++ @@ -2,3 +2,3 @@ name = "click"-version = "8.4.1"+version = "8.4.2" description = "Composable command line interface toolkit"@@ -187,3 +187,3 @@ [tool.tox.env.stress]-description = "stress tests for stream lifecycle race conditions"+description = "high-iteration stress tests for race conditions" commands = [[@@ -192,3 +192,2 @@     "--override-ini=addopts=",-    "tests/test_stream_lifecycle.py",     {replace = "posargs", default = [], extend = true},
src/click/_compat.py +0 lines
--- +++ @@ -14,3 +14,2 @@ WIN = sys.platform.startswith("win")-MAC = sys.platform == "darwin" auto_wrap_for_ansi: t.Callable[[t.TextIO], t.TextIO] | None = None
src/click/_termui_impl.py +44 lines
--- +++ @@ -31,2 +31,3 @@ from .utils import echo+from .utils import KeepOpenFile @@ -432,4 +433,7 @@     """Context manager.+     Yields a writable file-like object which can be used as an output pager.-    .. versionadded:: 8.4++    .. versionadded:: 8.4.0+     :param color: controls if the pager supports ANSI colors or not.  The@@ -440,13 +444,24 @@         # BinaryIO annotations: buffered text streams can be unwrapped to bytes,-        # while text-only streams are yielded as-is.+        # while other streams are yielded as-is.+        wrapper: MaybeStripAnsi | None = None         if _has_binary_buffer(stream):             # Text stream backed by a binary buffer.-            stream = MaybeStripAnsi(stream.buffer, color=color, encoding=encoding)-        elif isinstance(stream, t.BinaryIO):-            # Binary stream-            stream = MaybeStripAnsi(stream, color=color, encoding=encoding)+            wrapper = MaybeStripAnsi(stream.buffer, color=color, encoding=encoding)+            stream = wrapper         try:-            yield stream+            # Narrow the BinaryIO | TextIO union that _pager_contextmanager+            # yields; the caller writes text to the pager.+            yield t.cast(t.TextIO, stream)         finally:-            stream.flush()+            try:+                stream.flush()+            finally:+                # Hand the binary buffer back to the pager that produced it+                # rather than letting this TextIOWrapper close it on garbage+                # collection. The pager owns the buffer's lifecycle: subprocess+                # pipes and temp files are closed by their own helpers, while a+                # borrowed stdout must stay open for the caller. detach() runs+                # even if flush() raised, so the buffer is never closed here.+                if wrapper is not None:+                    wrapper.detach() @@ -470,4 +485,7 @@     if not cmd_parts:+        # No usable pager: fall back to stdout through _nullpager so it gets the+        # same borrowed-stream handling and the caller's stream is not closed.         stdout = _default_text_stdout() or StringIO()-        yield stdout, "utf-8", False+        with _nullpager(stdout, color) as rv:+            yield rv         return@@ -481,4 +499,7 @@     if not cmd_filepath:+        # No usable pager: fall back to stdout through _nullpager so it gets the+        # same borrowed-stream handling and the caller's stream is not closed.         stdout = _default_text_stdout() or StringIO()-        yield stdout, "utf-8", False+        with _nullpager(stdout, color) as rv:+            yield rv         return@@ -570,4 +591,7 @@     if not cmd_parts:+        # No usable pager: fall back to stdout through _nullpager so it gets the+        # same borrowed-stream handling and the caller's stream is not closed.         stdout = _default_text_stdout() or StringIO()-        yield stdout, "utf-8", False+        with _nullpager(stdout, color) as rv:+            yield rv         return@@ -581,4 +605,7 @@     if not cmd_filepath:+        # No usable pager: fall back to stdout through _nullpager so it gets the+        # same borrowed-stream handling and the caller's stream is not closed.         stdout = _default_text_stdout() or StringIO()-        yield stdout, "utf-8", False+        with _nullpager(stdout, color) as rv:+            yield rv         return@@ -608,17 +635,2 @@ -class _SkipClose:-    def __init__(self, stream: t.IO[t.Any]) -> None:-        self.stream = stream--    def __getattr__(self, name: str) -> t.Any:-        return getattr(self.stream, name)--    @property-    def buffer(self) -> t.BinaryIO:-        return _SkipClose(self.stream.buffer)  # type: ignore[attr-defined, return-value]--    def close(self) -> None:-        pass-- @contextlib.contextmanager@@ -630,2 +642,6 @@     internal helpers.++    The stream is wrapped in :class:`~click.utils.KeepOpenFile` so that, as a+    borrowed stream, it is not closed by a ``with`` block. The wrapper that+    :func:`get_pager_file` builds around it is detached rather than closed.     """@@ -636,3 +652,3 @@ -    yield _SkipClose(stream), encoding, color  # type: ignore[misc]+    yield KeepOpenFile(stream), encoding, color  # type: ignore[misc] 
src/click/core.py +142 lines
--- +++ @@ -50,2 +50,4 @@ if t.TYPE_CHECKING:+    from typing_extensions import Self+     from .shell_completion import CompletionItem@@ -119,3 +121,3 @@     ctx: Context, param: Parameter | None = None-) -> cabc.Iterator[None]:+) -> cabc.Generator[None]:     """Context manager that attaches extra information to exceptions."""@@ -305,2 +307,30 @@ +    parent: Context | None+    command: Command+    info_name: str | None+    params: dict[str, t.Any]+    args: list[str]+    _protected_args: list[str]+    _opt_prefixes: set[str]+    obj: t.Any+    _meta: dict[str, t.Any]+    default_map: cabc.MutableMapping[str, t.Any] | None+    invoked_subcommand: str | None+    terminal_width: int | None+    max_content_width: int | None+    allow_extra_args: bool+    allow_interspersed_args: bool+    ignore_unknown_options: bool+    help_option_names: list[str]+    token_normalize_func: t.Callable[[str], str] | None+    resilient_parsing: bool+    auto_envvar_prefix: str | None+    color: bool | None+    show_default: bool | None+    _close_callbacks: list[t.Callable[[], t.Any]]+    _depth: int+    _parameter_source: dict[str, ParameterSource]+    _param_default_explicit: dict[str, bool]+    _exit_stack: ExitStack+     def __init__(@@ -332,5 +362,5 @@         #: with ``expose_value=False`` are not stored.-        self.params: dict[str, t.Any] = {}+        self.params = {}         #: the leftover arguments.-        self.args: list[str] = []+        self.args = []         #: protected arguments.  These are arguments that are prepended@@ -339,5 +369,5 @@         #: to implement nested parsing.-        self._protected_args: list[str] = []+        self._protected_args = []         #: the collected prefixes of the command's options.-        self._opt_prefixes: set[str] = set(parent._opt_prefixes) if parent else set()+        self._opt_prefixes = set(parent._opt_prefixes) if parent else set() @@ -347,4 +377,4 @@         #: the user object stored.-        self.obj: t.Any = obj-        self._meta: dict[str, t.Any] = getattr(parent, "meta", {})+        self.obj = obj+        self._meta = getattr(parent, "meta", {}) @@ -359,3 +389,3 @@ -        self.default_map: cabc.MutableMapping[str, t.Any] | None = default_map+        self.default_map = default_map @@ -371,3 +401,3 @@         #: should use a :func:`result_callback`.-        self.invoked_subcommand: str | None = None+        self.invoked_subcommand = None @@ -377,3 +407,3 @@         #: The width of the terminal (None is autodetection).-        self.terminal_width: int | None = terminal_width+        self.terminal_width = terminal_width @@ -384,3 +414,3 @@         #: default which is 80 for most things).-        self.max_content_width: int | None = max_content_width+        self.max_content_width = max_content_width @@ -402,3 +432,3 @@         #: .. versionadded:: 3.0-        self.allow_interspersed_args: bool = allow_interspersed_args+        self.allow_interspersed_args = allow_interspersed_args @@ -415,3 +445,3 @@         #: .. versionadded:: 4.0-        self.ignore_unknown_options: bool = ignore_unknown_options+        self.ignore_unknown_options = ignore_unknown_options @@ -424,3 +454,3 @@         #: The names for the help options.-        self.help_option_names: list[str] = help_option_names+        self.help_option_names = help_option_names @@ -431,3 +461,3 @@         #: options, choices, commands etc.-        self.token_normalize_func: t.Callable[[str], str] | None = token_normalize_func+        self.token_normalize_func = token_normalize_func @@ -436,3 +466,3 @@         #: will be ignored. Useful for completion.-        self.resilient_parsing: bool = resilient_parsing+        self.resilient_parsing = resilient_parsing @@ -456,3 +486,3 @@ -        self.auto_envvar_prefix: str | None = auto_envvar_prefix+        self.auto_envvar_prefix = auto_envvar_prefix @@ -462,3 +492,3 @@         #: Controls if styling output is wanted or not.-        self.color: bool | None = color+        self.color = color @@ -468,7 +498,7 @@         #: Show option default values when formatting help text.-        self.show_default: bool | None = show_default--        self._close_callbacks: list[t.Callable[[], t.Any]] = []+        self.show_default = show_default++        self._close_callbacks = []         self._depth = 0-        self._parameter_source: dict[str, ParameterSource] = {}+        self._parameter_source = {}         # Tracks whether the option that currently owns each parameter slot in@@ -478,3 +508,3 @@         # Refs: https://github.com/pallets/click/issues/3403-        self._param_default_explicit: dict[str, bool] = {}+        self._param_default_explicit = {}         self._exit_stack = ExitStack()@@ -514,3 +544,3 @@ -    def __enter__(self) -> Context:+    def __enter__(self) -> Self:         self._depth += 1@@ -534,3 +564,3 @@     @contextmanager-    def scope(self, cleanup: bool = True) -> cabc.Iterator[Context]:+    def scope(self, cleanup: bool = True) -> cabc.Generator[Context]:         """This helper method can be used with the context object to promote@@ -987,2 +1017,16 @@ +    name: str | None+    context_settings: cabc.MutableMapping[str, t.Any]+    callback: t.Callable[..., t.Any] | None+    params: list[Parameter]+    help: str | None+    epilog: str | None+    options_metavar: str | None+    short_help: str | None+    add_help_option: bool+    _help_option: Option | None+    no_args_is_help: bool+    hidden: bool+    deprecated: bool | str+     def __init__(@@ -1012,3 +1056,3 @@         #: an optional dictionary with defaults passed to the context.-        self.context_settings: cabc.MutableMapping[str, t.Any] = context_settings+        self.context_settings = context_settings @@ -1020,3 +1064,3 @@         #: will automatically be handled before non eager ones.-        self.params: list[Parameter] = params or []+        self.params = params or []         self.help = help@@ -1191,3 +1235,4 @@         if self.deprecated:-            text = f"{_(text)} {_format_deprecated_label(self.deprecated)}"+            label = _format_deprecated_label(self.deprecated)+            text = f"{_(text)} {label}" if text else label @@ -1594,2 +1639,8 @@ +    commands: cabc.MutableMapping[str, Command]+    invoke_without_command: bool+    subcommand_metavar: str+    chain: bool+    _result_callback: t.Callable[..., t.Any] | None+     def __init__(@@ -1615,3 +1666,3 @@         #: The registered subcommands by their exported names.-        self.commands: cabc.MutableMapping[str, Command] = commands+        self.commands = commands @@ -1624,4 +1675,11 @@         if subcommand_metavar is None:+            # When the group can run without a subcommand, the leading command+            # token is optional, so wrap it in brackets to reflect that.             if chain:-                subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."+                if invoke_without_command:+                    subcommand_metavar = "[COMMAND1] [ARGS]... [COMMAND2 [ARGS]...]..."+                else:+                    subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."+            elif invoke_without_command:+                subcommand_metavar = "[COMMAND] [ARGS]..."             else:@@ -2014,2 +2072,4 @@ +    sources: list[Group]+     def __init__(@@ -2022,3 +2082,3 @@         #: The list of registered groups.-        self.sources: list[Group] = sources or []+        self.sources = sources or [] @@ -2054,3 +2114,3 @@ -def _check_iter(value: t.Any) -> cabc.Iterator[t.Any]:+def _check_iter(value: cabc.Iterable[V]) -> cabc.Iterator[V]:     """Check if the value is iterable but not a string. Raises a type@@ -2157,2 +2217,21 @@ +    name: str+    opts: list[str]+    secondary_opts: list[str]+    # `Parameter.type` is annotated in `__init__` to avoid confusing mypy+    required: bool+    callback: t.Callable[[Context, Parameter, t.Any], t.Any] | None+    nargs: int+    multiple: bool+    expose_value: bool+    default: t.Any | t.Callable[[], t.Any] | None+    _default_explicit: bool+    is_eager: bool+    metavar: str | None+    envvar: str | cabc.Sequence[str] | None+    _custom_shell_complete: (+        t.Callable[[Context, Parameter, str], list[CompletionItem] | list[str]] | None+    )+    deprecated: bool | str+     def __init__(@@ -2186,5 +2265,2 @@     ) -> None:-        self.name: str-        self.opts: list[str]-        self.secondary_opts: list[str]
… 65 more lines (truncated)
src/click/decorators.py +30 lines
--- +++ @@ -436,4 +436,7 @@     If ``package_name`` is not provided, Click will try to detect it by-    inspecting the stack frames. This will be used to detect the-    version, so it must match the name of the installed package.+    inspecting the stack frames. If the detected (or given) name does+    not match an installed distribution, Click resolves it as an import+    (top-level module) name via+    :func:`importlib.metadata.packages_distributions`, so e.g. ``PIL``+    resolves to the ``Pillow`` distribution. @@ -462,2 +465,6 @@         package name, or be passed with ``package_name=``.++    .. versionchanged:: 8.4.2+        When ``package_name`` does not match an installed distribution,+        Click now resolves it as an import (top-level module).     """@@ -489,2 +496,3 @@         nonlocal version+        nonlocal package_name @@ -499,6 +507,22 @@             except importlib.metadata.PackageNotFoundError:-                raise RuntimeError(-                    f"{package_name!r} is not installed. Try passing"-                    " 'package_name' instead."-                ) from None+                # The given name didn't match an installed distribution.+                # Try resolving it as an import (top-level module) name,+                # e.g. ``PIL`` is provided by the ``Pillow`` distribution.+                distributions = importlib.metadata.packages_distributions().get(+                    package_name, []+                )+                if len(distributions) == 1:+                    package_name = distributions[0]+                    version = importlib.metadata.version(package_name)+                elif len(distributions) > 1:+                    raise RuntimeError(+                        f"{package_name!r} maps to multiple installed"+                        f" distributions ({', '.join(distributions)})."+                        " Pass 'package_name' to disambiguate."+                    ) from None+                else:+                    raise RuntimeError(+                        f"{package_name!r} is not installed. Try passing"+                        " 'package_name' instead."+                    ) from None 
src/click/exceptions.py +42 lines
--- +++ @@ -38,3 +38,6 @@     #: The exit code for this exception.-    exit_code = 1+    exit_code: t.ClassVar[int] = 1++    show_color: t.Final[bool | None]+    message: t.Final[str] @@ -44,3 +47,3 @@         # the color settings here to be used later on (in `show`)-        self.show_color: bool | None = resolve_color_default()+        self.show_color = resolve_color_default()         self.message = message@@ -73,3 +76,6 @@ -    exit_code = 2+    exit_code: t.ClassVar[int] = 2++    ctx: Context | None+    cmd: t.Final[Command | None] @@ -78,3 +84,3 @@         self.ctx = ctx-        self.cmd: Command | None = self.ctx.command if self.ctx else None+        self.cmd = self.ctx.command if self.ctx else None @@ -125,2 +131,5 @@ +    param: Parameter | None+    param_hint: cabc.Sequence[str] | str | None+     def __init__(@@ -160,2 +169,4 @@     """++    param_type: t.Final[str | None] @@ -226,2 +237,5 @@ +    option_name: t.Final[str]+    possibilities: t.Final[list[str] | None]+     def __init__(@@ -238,3 +252,3 @@         self.option_name = option_name-        self.possibilities: list[str] | None = None+         if possibilities:@@ -242,3 +256,6 @@ -            self.possibilities = get_close_matches(option_name, possibilities)+            possibilities_ = get_close_matches(option_name, possibilities)+        else:+            possibilities_ = None+        self.possibilities = possibilities_ @@ -255,2 +272,5 @@     """++    command_name: t.Final[str]+    possibilities: t.Final[list[str] | None] @@ -268,3 +288,3 @@         self.command_name = command_name-        self.possibilities: list[str] | None = None+         if possibilities:@@ -272,3 +292,6 @@ -            self.possibilities = get_close_matches(command_name, possibilities)+            possibilities_ = get_close_matches(command_name, possibilities)+        else:+            possibilities_ = None+        self.possibilities = possibilities_ @@ -290,2 +313,4 @@ +    option_name: t.Final[str]+     def __init__(@@ -307,4 +332,5 @@ class NoArgsIsHelpError(UsageError):+    ctx: Context+     def __init__(self, ctx: Context) -> None:-        self.ctx: Context         super().__init__(ctx.get_help(), ctx=ctx)@@ -317,2 +343,5 @@     """Raised if a file cannot be opened."""++    ui_filename: t.Final[str]+    filename: t.Final[str] @@ -323,3 +352,3 @@         super().__init__(hint)-        self.ui_filename: str = format_filename(filename)+        self.ui_filename = format_filename(filename)         self.filename = filename@@ -345,3 +374,5 @@ +    exit_code: t.Final[int]+     def __init__(self, code: int = 0) -> None:-        self.exit_code: int = code+        self.exit_code = code
src/click/formatting.py +11 lines
--- +++ @@ -121,2 +121,7 @@ +    indent_increment: int+    width: int+    current_indent: int+    buffer: list[str]+     def __init__(@@ -137,4 +142,4 @@         self.width = width-        self.current_indent: int = 0-        self.buffer: list[str] = []+        self.current_indent = 0+        self.buffer = [] @@ -225,3 +230,3 @@         self,-        rows: cabc.Sequence[tuple[str, str]],+        rows: cabc.Iterable[tuple[str, str]],         col_max: int = 30,@@ -268,3 +273,3 @@     @contextmanager-    def section(self, name: str) -> cabc.Iterator[None]:+    def section(self, name: str) -> cabc.Generator[None]:         """Helpful context manager that writes a paragraph, a heading,@@ -283,3 +288,3 @@     @contextmanager-    def indentation(self) -> cabc.Iterator[None]:+    def indentation(self) -> cabc.Generator[None]:         """A context manager that increases the indentation."""@@ -296,3 +301,3 @@ -def join_options(options: cabc.Sequence[str]) -> tuple[str, bool]:+def join_options(options: cabc.Iterable[str]) -> tuple[str, bool]:     """Given a list of option strings this joins them in the most appropriate
src/click/shell_completion.py +69 lines
--- +++ @@ -24,3 +24,3 @@     instruction: str,-) -> int:+) -> t.Literal[0, 1]:     """Perform shell completion for the given CLI program.@@ -57,3 +57,12 @@ -class CompletionItem:+if t.TYPE_CHECKING:+    from typing_extensions import TypeVar++    # `Any` is used as default for backwards compatibility (instead of e.g. `str`)+    _ValueT_co = TypeVar("_ValueT_co", covariant=True, default=t.Any)+else:+    _ValueT_co = t.TypeVar("_ValueT_co", covariant=True)+++class CompletionItem(t.Generic[_ValueT_co]):     """Represents a completion value and metadata about the value. The@@ -80,3 +89,3 @@         self,-        value: t.Any,+        value: _ValueT_co,         type: str = "plain",@@ -85,3 +94,3 @@     ) -> None:-        self.value: t.Any = value+        self.value: _ValueT_co = value         self.type: str = type@@ -183,3 +192,3 @@     for completion in $response;-        set -l metadata (string split \n $completion);+        set -l metadata (string split "," $completion); @@ -190,7 +199,3 @@         else if test $metadata[1] = "plain";-            if test $metadata[3] != "_";-                echo $metadata[2]\t$metadata[3];-            else;-                echo $metadata[2];-            end;+            echo $metadata[2];         end;@@ -202,2 +207,8 @@ """+++class _SourceVarsDict(t.TypedDict):+    complete_func: str+    complete_var: str+    prog_name: str @@ -227,2 +238,7 @@     """++    cli: Command+    ctx_args: cabc.MutableMapping[str, t.Any]+    prog_name: str+    complete_var: str @@ -248,3 +264,3 @@ -    def source_vars(self) -> dict[str, t.Any]:+    def source_vars(self) -> _SourceVarsDict:         """Vars for formatting :attr:`source_template`.@@ -275,3 +291,5 @@ -    def get_completions(self, args: list[str], incomplete: str) -> list[CompletionItem]:+    def get_completions(+        self, args: list[str], incomplete: str+    ) -> list[CompletionItem[str]]:         """Determine the context and last complete command or parameter@@ -287,3 +305,3 @@ -    def format_completion(self, item: CompletionItem) -> str:+    def format_completion(self, item: CompletionItem[str]) -> str:         """Format a completion item into the form recognized by the@@ -311,4 +329,4 @@ -    name = "bash"-    source_template = _SOURCE_BASH+    name: t.ClassVar[str] = "bash"+    source_template: t.ClassVar[str] = _SOURCE_BASH @@ -363,3 +381,3 @@ -    def format_completion(self, item: CompletionItem) -> str:+    def format_completion(self, item: CompletionItem[t.Any]) -> str:         return f"{item.type},{item.value}"@@ -370,4 +388,4 @@ -    name = "zsh"-    source_template = _SOURCE_ZSH+    name: t.ClassVar[str] = "zsh"+    source_template: t.ClassVar[str] = _SOURCE_ZSH @@ -385,3 +403,3 @@ -    def format_completion(self, item: CompletionItem) -> str:+    def format_completion(self, item: CompletionItem[str]) -> str:         help_ = item.help or "_"@@ -406,4 +424,4 @@ -    name = "fish"-    source_template = _SOURCE_FISH+    name: t.ClassVar[str] = "fish"+    source_template: t.ClassVar[str] = _SOURCE_FISH @@ -423,23 +441,20 @@ -    def format_completion(self, item: CompletionItem) -> str:-        """-        .. versionchanged:: 8.4.0-            Escape newlines in value and help to fix completion errors with-            multi-line help strings.-        """-        # The fish completion script splits each response line on literal-        # newlines, so any newline in the value or help would corrupt the-        # frame. Replace them with the two-character escape "\n" so the text-        # round-trips through fish without breaking the format. The "_"-        # sentinel for missing help mirrors :class:`ZshComplete`.-        help_ = item.help or "_"-        value = item.value.replace("\n", r"\n")-        help_escaped = help_.replace("\n", r"\n")-        return f"{item.type}\n{value}\n{help_escaped}"---ShellCompleteType = t.TypeVar("ShellCompleteType", bound="type[ShellComplete]")---_available_shells: dict[str, type[ShellComplete]] = {+    def format_completion(self, item: CompletionItem[str]) -> str:+        """+        .. versionchanged:: 8.4.2+            Escape newlines and replace tabs with spaces in the help text to+            fix completion errors with multi-line help strings.+        """+        # According to https://fishshell.com/docs/current/cmds/complete.html+        # Command substitutions found in ARGUMENTS should return a newline-+        # separated list of arguments, and each argument may optionally have a tab+        # character followed by the argument description.+        if item.help:+            help_ = item.help.replace("\n", "\\n").replace("\t", " ")+            return f"{item.type},{item.value}\t{help_}"++        return f"{item.type},{item.value}"+++_available_shells: t.Final[dict[str, type[ShellComplete]]] = {     "bash": BashComplete,@@ -449,6 +464,8 @@ +_ShellCompleteT = t.TypeVar("_ShellCompleteT", bound="ShellComplete")+  def add_completion_class(-    cls: ShellCompleteType, name: str | None = None-) -> ShellCompleteType:+    cls: type[_ShellCompleteT], name: str | None = None+) -> type[_ShellCompleteT]:     """Register a :class:`ShellComplete` subclass under the given name.@@ -470,2 +487,10 @@ [email protected]+def get_completion_class(shell: t.Literal["bash"]) -> type[BashComplete]: ...[email protected]+def get_completion_class(shell: t.Literal["fish"]) -> type[FishComplete]: ...[email protected]+def get_completion_class(shell: t.Literal["zsh"]) -> type[ZshComplete]: ...[email protected]+def get_completion_class(shell: str) -> type[ShellComplete] | None: ... def get_completion_class(shell: str) -> type[ShellComplete] | None:
src/click/termui.py +4 lines
--- +++ @@ -348,2 +348,6 @@             pager.write(text)+            # Flush after each write so a slow generator streams to the pager+            # incrementally rather than staying invisible until the pipe buffer+            # fills (~8 KB).+            pager.flush() 
src/click/testing.py +51 lines
--- +++ @@ -24,3 +24,7 @@ -CaptureMode = t.Literal["sys", "fd"]+if sys.platform == "win32":+    CaptureMode: t.TypeAlias = t.Literal["sys"]  # pyright: ignore[reportRedeclaration]+else:+    CaptureMode: t.TypeAlias = t.Literal["sys", "fd"]  # pyright: ignore[reportRedeclaration]+ExceptionInfo: t.TypeAlias = tuple[type[BaseException], BaseException, TracebackType] @@ -28,2 +32,6 @@ class EchoingStdin:+    _input: t.BinaryIO+    _output: t.BinaryIO+    _paused: bool+     def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None:@@ -62,3 +70,3 @@ @contextlib.contextmanager-def _pause_echo(stream: EchoingStdin | None) -> cabc.Iterator[None]:+def _pause_echo(stream: EchoingStdin | None) -> cabc.Generator[None]:     if stream is None:@@ -82,6 +90,10 @@ +    _targetfd: int+    saved_fd: int+    _tmpfile: t.BinaryIO | None+     def __init__(self, targetfd: int) -> None:         self._targetfd = targetfd-        self.saved_fd: int = -1-        self._tmpfile: t.BinaryIO | None = None+        self.saved_fd = -1+        self._tmpfile = None @@ -110,2 +122,4 @@ +    copy_to: io.BytesIO+     def __init__(self, copy_to: io.BytesIO) -> None:@@ -131,6 +145,10 @@ +    output: io.BytesIO+    stdout: BytesIOCopy+    stderr: BytesIOCopy+     def __init__(self) -> None:-        self.output: io.BytesIO = io.BytesIO()-        self.stdout: io.BytesIO = BytesIOCopy(copy_to=self.output)-        self.stderr: io.BytesIO = BytesIOCopy(copy_to=self.output)+        self.output = io.BytesIO()+        self.stdout = BytesIOCopy(copy_to=self.output)+        self.stderr = BytesIOCopy(copy_to=self.output) @@ -148,2 +166,6 @@     """++    _name: str+    _mode: str+    _original_fd: int @@ -159,3 +181,3 @@         self._mode = mode-        self._original_fd: int = -1+        self._original_fd = -1 @@ -230,2 +252,11 @@ +    runner: CliRunner+    stdout_bytes: bytes+    stderr_bytes: bytes+    output_bytes: bytes+    return_value: t.Any+    exit_code: int+    exception: BaseException | None+    exc_info: ExceptionInfo | None+     def __init__(@@ -239,5 +270,4 @@         exception: BaseException | None,-        exc_info: tuple[type[BaseException], BaseException, TracebackType]-        | None = None,-    ):+        exc_info: ExceptionInfo | None = None,+    ) -> None:         self.runner = runner@@ -322,2 +352,8 @@     """++    charset: str+    env: cabc.Mapping[str, str | None]+    echo_stdin: bool+    catch_exceptions: bool+    capture: CaptureMode @@ -340,6 +376,6 @@         self.charset = charset-        self.env: cabc.Mapping[str, str | None] = env or {}+        self.env = env or {}         self.echo_stdin = echo_stdin         self.catch_exceptions = catch_exceptions-        self.capture: CaptureMode = capture+        self.capture = capture @@ -367,3 +403,3 @@         color: bool = False,-    ) -> cabc.Iterator[tuple[io.BytesIO, io.BytesIO, io.BytesIO]]:+    ) -> cabc.Generator[tuple[io.BytesIO, io.BytesIO, io.BytesIO]]:         """A context manager that sets up the isolation for invoking of a@@ -707,3 +743,3 @@         self, temp_dir: str | os.PathLike[str] | None = None-    ) -> cabc.Iterator[str]:+    ) -> cabc.Generator[str]:         """A context manager that creates a temporary directory and
src/click/types.py +152 lines
--- +++ @@ -28,3 +28,8 @@ -ParamTypeValue = t.TypeVar("ParamTypeValue")+_ValueT = t.TypeVar("_ValueT")+_ValueT_contra = t.TypeVar("_ValueT_contra", contravariant=True)+_ValueT_co = t.TypeVar("_ValueT_co", covariant=True)++_FloatValueT = t.TypeVar("_FloatValueT", bound=float)+_FloatValueT_co = t.TypeVar("_FloatValueT_co", bound=float, covariant=True) @@ -36,3 +41,3 @@ -class ParamType(t.Generic[ParamTypeValue], abc.ABC):+class ParamType(t.Generic[_ValueT_co], abc.ABC):     """Represents the type of a parameter. Validates and converts values@@ -61,3 +66,3 @@     is_composite: t.ClassVar[bool] = False-    arity: t.ClassVar[int] = 1+    arity: int = 1  # read-only @@ -100,3 +105,3 @@         ctx: Context | None = None,-    ) -> ParamTypeValue | None:+    ) -> _ValueT_co | None:         if value is not None:@@ -117,3 +122,3 @@         self, value: t.Any, param: Parameter | None, ctx: Context | None-    ) -> ParamTypeValue:+    ) -> _ValueT_co:         """Convert the value to the correct type. This is not called if@@ -139,3 +144,3 @@         # metadata are not forced to redeclare ``convert``.-        return t.cast("ParamTypeValue", value)+        return t.cast("_ValueT_co", value) @@ -178,4 +183,4 @@ -class CompositeParamType(ParamType[ParamTypeValue]):-    is_composite = True+class CompositeParamType(ParamType[_ValueT_co]):+    is_composite: t.ClassVar[bool] = True @@ -186,12 +191,25 @@ -class FuncParamTypeInfoDict(ParamTypeInfoDict):-    func: t.Callable[[t.Any], t.Any]---class FuncParamType(ParamType[ParamTypeValue]):-    def __init__(self, func: t.Callable[[t.Any], ParamTypeValue]) -> None:-        self.name: str = func.__name__+if t.TYPE_CHECKING:+    # on Python 3.10 this will raise a TypeError++    class FuncParamTypeInfoDict(+        ParamTypeInfoDict,+        t.Generic[_ValueT_contra, _ValueT_co],+    ):+        func: t.Callable[[_ValueT_contra], _ValueT_co]+else:++    class FuncParamTypeInfoDict(ParamTypeInfoDict):+        func: t.Callable[[t.Any], t.Any]+++class FuncParamType(ParamType[_ValueT_co], t.Generic[_ValueT_contra, _ValueT_co]):+    name: str+    func: t.Callable[[_ValueT_contra], _ValueT_co]++    def __init__(self, func: t.Callable[[_ValueT_contra], _ValueT_co]) -> None:+        self.name = func.__name__         self.func = func -    def to_info_dict(self) -> FuncParamTypeInfoDict:+    def to_info_dict(self) -> FuncParamTypeInfoDict[_ValueT_contra, _ValueT_co]:         return {"func": self.func, **super().to_info_dict()}@@ -199,4 +217,4 @@     def convert(-        self, value: t.Any, param: Parameter | None, ctx: Context | None-    ) -> ParamTypeValue:+        self, value: _ValueT_contra, param: Parameter | None, ctx: Context | None+    ) -> _ValueT_co:         try:@@ -210,3 +228,3 @@                 except UnicodeError:-                    message = value.decode("utf-8", "replace")+                    message = t.cast("bytes", value).decode("utf-8", "replace") @@ -219,4 +237,4 @@     def convert(-        self, value: t.Any, param: Parameter | None, ctx: Context | None-    ) -> t.Any:+        self, value: _ValueT, param: Parameter | None, ctx: Context | None+    ) -> _ValueT:         return value@@ -236,3 +254,3 @@             try:-                value = value.decode(enc)+                return value.decode(enc)             except UnicodeError:@@ -241,8 +259,7 @@                     try:-                        value = value.decode(fs_enc)+                        return value.decode(fs_enc)                     except UnicodeError:-                        value = value.decode("utf-8", "replace")+                        return value.decode("utf-8", "replace")                 else:-                    value = value.decode("utf-8", "replace")-            return value  # type: ignore[no-any-return]+                    return value.decode("utf-8", "replace")         return str(value)@@ -253,8 +270,16 @@ -class ChoiceInfoDict(ParamTypeInfoDict):-    choices: cabc.Sequence[t.Any]-    case_sensitive: bool---class Choice(ParamType[ParamTypeValue], t.Generic[ParamTypeValue]):+if t.TYPE_CHECKING:+    # on Python 3.10 this will raise a TypeError++    class ChoiceInfoDict(ParamTypeInfoDict, t.Generic[_ValueT_co]):+        choices: tuple[_ValueT_co, ...]+        case_sensitive: bool+else:++    class ChoiceInfoDict(ParamTypeInfoDict):+        choices: tuple[t.Any, ...]+        case_sensitive: bool+++class Choice(ParamType[_ValueT_co], t.Generic[_ValueT_co]):     """The choice type allows a value to be checked against a fixed set@@ -286,11 +311,14 @@ -    name = "choice"+    name: str = "choice"++    choices: tuple[_ValueT_co, ...]+    case_sensitive: bool      def __init__(-        self, choices: cabc.Iterable[ParamTypeValue], case_sensitive: bool = True+        self, choices: cabc.Iterable[_ValueT_co], case_sensitive: bool = True     ) -> None:-        self.choices: cabc.Sequence[ParamTypeValue] = tuple(choices)+        self.choices = tuple(choices)         self.case_sensitive = case_sensitive -    def to_info_dict(self) -> ChoiceInfoDict:+    def to_info_dict(self) -> ChoiceInfoDict[_ValueT_co]:         return {@@ -303,3 +331,3 @@         self, ctx: Context | None = None-    ) -> cabc.Mapping[ParamTypeValue, str]:+    ) -> cabc.Mapping[_ValueT_co, str]:         """@@ -319,3 +347,3 @@ -    def normalize_choice(self, choice: ParamTypeValue, ctx: Context | None) -> str:+    def normalize_choice(self, choice: object, ctx: Context | None) -> str:         """@@ -340,3 +368,3 @@     def get_metavar(self, param: Parameter, ctx: Context) -> str | None:-        if param.param_type_name == "option" and not param.show_choices:  # type: ignore+        if param.param_type_name == "option" and not param.show_choices:  # type: ignore[attr-defined]             choice_metavars = [@@ -369,3 +397,3 @@         self, value: t.Any, param: Parameter | None, ctx: Context | None-    ) -> ParamTypeValue:+    ) -> _ValueT_co:         """@@ -458,4 +486,6 @@ +    formats: cabc.Sequence[str]+     def __init__(self, formats: cabc.Sequence[str] | None = None):-        self.formats: cabc.Sequence[str] = formats or [+        self.formats = formats or [             "%Y-%m-%d",@@ -468,3 +498,3 @@ -    def get_metavar(self, param: Parameter, ctx: Context) -> str | None:+    def get_metavar(self, param: Parameter, ctx: Context) -> str:         return f"[{'|'.join(self.formats)}]"@@ -504,8 +534,10 @@ -class _NumberParamTypeBase(ParamType[ParamTypeValue]):-    _number_class: t.Callable[[t.Any], ParamTypeValue]+class _NumberParamTypeBase(+    ParamType[_ValueT_co], t.Generic[_ValueT_contra, _ValueT_co]+):+    _number_class: t.Callable[[_ValueT_contra], _ValueT_co]      def convert(-        self, value: t.Any, param: Parameter | None, ctx: Context | None-    ) -> ParamTypeValue:+        self, value: _ValueT_contra, param: Parameter | None, ctx: Context | None+    ) -> _ValueT_co:         try:@@ -522,5 +554,27 @@ -class NumberRangeInfoDict(ParamTypeInfoDict):-    min: float | None-    max: float | None+if t.TYPE_CHECKING:+    # on Python 3.10 this will raise a TypeError++    class NumberRangeInfoDict(ParamTypeInfoDict, t.Generic[_FloatValueT_co]):+        min: _FloatValueT_co | None+        max: _FloatValueT_co | None+        min_open: bool+        max_open: bool+        clamp: bool+else:++    class NumberRangeInfoDict(ParamTypeInfoDict):+        min: t.Any | None+        max: t.Any | None+        min_open: bool+        max_open: bool+        clamp: bool+++class _NumberRangeBase(+    _NumberParamTypeBase[_ValueT_contra, _FloatValueT_co],+    t.Generic[_ValueT_contra, _FloatValueT_co],+):+    min: _FloatValueT_co | None+    max: _FloatValueT_co | None     min_open: bool@@ -529,8 +583,6 @@ --class _NumberRangeBase(_NumberParamTypeBase[ParamTypeValue]):     def __init__(         self,-        min: float | None = None,-        max: float | None = None,+        min: _FloatValueT_co | None = None,+        max: _FloatValueT_co | None = None,         min_open: bool = False,@@ -545,3 +597,3 @@ -    def to_info_dict(self) -> NumberRangeInfoDict:+    def to_info_dict(self) -> NumberRangeInfoDict[_FloatValueT_co]:
… 158 more lines (truncated)
src/click/utils.py +12 lines
--- +++ @@ -207,2 +207,14 @@ class KeepOpenFile:+    """Proxy a file object but keep it open across a ``with`` block.++    Wraps a borrowed file (such as ``sys.stdin`` or ``sys.stdout``) so that+    leaving a ``with`` block does not close it, as used by :func:`open_file`+    for the ``-`` filename. The caller stays responsible for the file: an+    explicit :meth:`close` still passes through to the wrapped object.++    Dunder methods are proxied explicitly: implicit special-method lookups+    bypass :meth:`__getattr__`, because Python resolves them on the type rather+    than the instance.+    """+     _file: t.IO[t.Any]
tests/test_arguments.py +26 lines
--- +++ @@ -308,2 +308,28 @@ [email protected](+    ("kwargs", "expected"),+    [+        ({}, "FOO"),+        ({"required": True}, "FOO"),+        ({"required": False}, "[FOO]"),+        ({"default": "x"}, "[FOO]"),+        ({"nargs": -1}, "[FOO]..."),+        ({"nargs": -1, "required": True}, "FOO..."),+        ({"nargs": 2}, "FOO..."),+        ({"nargs": 2, "required": False}, "[FOO]..."),+    ],+)+def test_argument_metavar_marks_optional(runner, kwargs, expected):+    """An argument is bracketed in the usage line only when it is optional."""++    @click.command()+    @click.argument("foo", **kwargs)+    def cli(foo):+        pass++    result = runner.invoke(cli, ["--help"])+    assert result.exit_code == 0+    assert result.output.splitlines()[0] == f"Usage: cli [OPTIONS] {expected}"++ @pytest.mark.parametrize("deprecated", [True, "USE B INSTEAD"])
tests/test_basic.py +119 lines
--- +++ @@ -571,2 +571,42 @@ +def test_choice_argument_optional_metavar(runner):+    """Optional Choice arguments reuse the type's brackets instead of doubling.++    Without this the usage line for a ``Choice`` argument with ``nargs=-1`` or+    ``required=False`` rendered as ``[[a|b|c]]``: one pair from ``Choice`` to+    enumerate values, a second pair from ``Argument`` to mark it optional.+    """++    @click.command()+    @click.argument("method", type=click.Choice(["foo", "bar", "baz"]), nargs=-1)+    def cli_variadic(method):+        pass++    @click.command()+    @click.argument("method", type=click.Choice(["foo", "bar", "baz"]), required=False)+    def cli_optional(method):+        pass++    variadic = runner.invoke(cli_variadic, ["--help"]).output+    assert "Usage: cli-variadic [OPTIONS] [foo|bar|baz]...\n" in variadic+    assert "[[foo|bar|baz]]" not in variadic++    optional = runner.invoke(cli_optional, ["--help"]).output+    assert "Usage: cli-optional [OPTIONS] [foo|bar|baz]\n" in optional+    assert "[[foo|bar|baz]]" not in optional+++def test_datetime_argument_optional_metavar(runner):+    """``DateTime`` arguments behave the same way as ``Choice``."""++    @click.command()+    @click.argument("when", type=click.DateTime(formats=["%Y-%m-%d"]), required=False)+    def cli(when):+        pass++    result = runner.invoke(cli, ["--help"])+    assert "Usage: cli [OPTIONS] [%Y-%m-%d]\n" in result.output+    assert "[[%Y-%m-%d]]" not in result.output++ def test_datetime_option_default(runner):@@ -741 +781,80 @@     assert "default: not found" in result.output+++def test_version_option_resolves_import_name_to_distribution(runner, monkeypatch):+    """When ``package_name`` (detected or passed) is an import name that+    differs from its installed distribution name (``PIL`` vs ``Pillow``),+    ``version_option`` resolves it via ``packages_distributions()`` instead+    of raising ``RuntimeError``.+    """+    import importlib.metadata++    def fake_version(name):+        if name == "pillow":+            return "10.4.0"+        raise importlib.metadata.PackageNotFoundError(name)++    monkeypatch.setattr(importlib.metadata, "version", fake_version)+    monkeypatch.setattr(+        importlib.metadata,+        "packages_distributions",+        lambda: {"PIL": ["pillow"]},+    )++    @click.command()+    @click.version_option(package_name="PIL")+    def cli():+        pass++    result = runner.invoke(cli, ["--version"], prog_name="imageapp")+    assert result.exit_code == 0+    assert "10.4.0" in result.output+++def test_version_option_ambiguous_import_name_errors(runner, monkeypatch):+    """When an import name maps to multiple installed distributions, the+    user must disambiguate. The error names the candidates.+    """+    import importlib.metadata++    def fake_version(name):+        raise importlib.metadata.PackageNotFoundError(name)++    monkeypatch.setattr(importlib.metadata, "version", fake_version)+    monkeypatch.setattr(+        importlib.metadata,+        "packages_distributions",+        lambda: {"plug": ["foo-plug", "bar-plug"]},+    )++    @click.command()+    @click.version_option(package_name="plug")+    def cli():+        pass++    result = runner.invoke(cli, ["--version"])+    assert result.exit_code != 0+    msg = str(result.exception)+    assert "multiple installed distributions" in msg+    assert "foo-plug" in msg+    assert "bar-plug" in msg+++def test_version_option_unknown_package_errors(runner, monkeypatch):+    """When the name resolves to no distribution, keep the existing error."""+    import importlib.metadata++    def fake_version(name):+        raise importlib.metadata.PackageNotFoundError(name)++    monkeypatch.setattr(importlib.metadata, "version", fake_version)+    monkeypatch.setattr(importlib.metadata, "packages_distributions", lambda: {})++    @click.command()+    @click.version_option(package_name="nonexistent")+    def cli():+        pass++    result = runner.invoke(cli, ["--version"])+    assert result.exit_code != 0+    assert "not installed" in str(result.exception)
tests/test_commands.py +43 lines
--- +++ @@ -299,2 +299,29 @@     assert result.output == "no subcommand, use default\nin subcommand\n"++[email protected](+    ("chain", "invoke_without_command", "metavar"),+    [+        (False, False, "COMMAND [ARGS]..."),+        (False, True, "[COMMAND] [ARGS]..."),+        (True, False, "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."),+        (True, True, "[COMMAND1] [ARGS]... [COMMAND2 [ARGS]...]..."),+    ],+)+def test_subcommand_metavar_marks_optional(+    runner, chain, invoke_without_command, metavar+):+    """The leading subcommand token is bracketed only when it is optional."""++    @click.group(chain=chain, invoke_without_command=invoke_without_command)+    def cli():+        pass++    @cli.command()+    def sub():+        pass++    result = runner.invoke(cli, ["--help"])+    assert result.exit_code == 0+    assert result.output.splitlines()[0] == f"Usage: cli [OPTIONS] {metavar}" @@ -494,2 +521,18 @@ @pytest.mark.parametrize("deprecated", [True, "USE OTHER COMMAND INSTEAD"])[email protected]("doc", ["", None])+def test_deprecated_empty_help_no_leading_space(runner, doc, deprecated):+    """A command with empty or missing help text must render the deprecation+    label at the normal indentation, without a stray leading space.+    """++    @click.command(deprecated=deprecated, help=doc)+    def cli():+        pass++    out = runner.invoke(cli, ["--help"]).output+    assert "\n  (DEPRECATED" in out+    assert "\n   (DEPRECATED" not in out++[email protected]("deprecated", [True, "USE OTHER COMMAND INSTEAD"]) def test_deprecated_in_invocation(runner, deprecated):
tests/test_options.py +16 lines
--- +++ @@ -58,2 +58,16 @@         assert deprecated in result.output++[email protected](+    ("deprecated", "expected"),+    [(True, "(DEPRECATED)"), ("USE B INSTEAD", "(DEPRECATED: USE B INSTEAD)")],+)[email protected]("help_text", ["", None])+def test_deprecated_empty_help_no_leading_space(help_text, deprecated, expected):+    """An option with empty or missing help text must not gain a stray leading+    space before the deprecation label.+    """+    opt = click.Option(["--foo"], help=help_text, deprecated=deprecated)+    ctx = click.Context(click.Command("cli"))+    assert opt.get_help_record(ctx)[1] == expected @@ -3308,6 +3322,4 @@ -    result = runner.invoke(cli, [])-    assert result.exit_code == 1-    assert isinstance(result.exception, UserWarning)-    assert "used more than once" in str(result.exception)+    with pytest.warns(UserWarning, match="used more than once"):+        runner.invoke(cli, []) 
tests/test_shell_completion.py +10 lines
--- +++ @@ -14,2 +14,3 @@ from click.shell_completion import CompletionItem+from click.shell_completion import FishComplete from click.shell_completion import shell_complete@@ -361,5 +362,5 @@         ("zsh", {"COMP_WORDS": "a b", "COMP_CWORD": "1"}, "plain\nb\nbee\n"),-        ("fish", {"COMP_WORDS": "", "COMP_CWORD": ""}, "plain\na\n_\nplain\nb\nbee\n"),-        ("fish", {"COMP_WORDS": "a b", "COMP_CWORD": "b"}, "plain\nb\nbee\n"),-        ("fish", {"COMP_WORDS": 'a "b', "COMP_CWORD": '"b'}, "plain\nb\nbee\n"),+        ("fish", {"COMP_WORDS": "", "COMP_CWORD": ""}, "plain,a\nplain,b\tbee\n"),+        ("fish", {"COMP_WORDS": "a b", "COMP_CWORD": "b"}, "plain,b\tbee\n"),+        ("fish", {"COMP_WORDS": 'a "b', "COMP_CWORD": '"b'}, "plain,b\tbee\n"),     ],@@ -580,46 +581,7 @@ [email protected]("_patch_for_completion")-def test_fish_multiline_help_complete(runner):-    """Test Fish completion with multi-line help text doesn't cause errors."""-    cli = Command(-        "cli",-        params=[-            Option(-                ["--at", "--attachment-type"],-                type=(str, str),-                multiple=True,-                help=(-                    "\b\nAttachment with explicit mimetype,\n--at image.jpg image/jpeg"-                ),-            ),-            Option(["--other"], help="Normal help"),-        ],-    )--    result = runner.invoke(-        cli,-        env={-            "COMP_WORDS": "cli --",-            "COMP_CWORD": "--",-            "_CLI_COMPLETE": "fish_complete",-        },-    )--    # Should not fail-    assert result.exit_code == 0--    # Output should contain escaped newlines, not literal newlines-    # Fish expects: plain\n--at\n{help_with_\\n}-    lines = result.output.split("\n")--    # Find the --at completion block (3 lines: type, value, help)-    for i in range(0, len(lines) - 2, 3):-        if lines[i] == "plain" and lines[i + 1] in ("--at", "--attachment-type"):-            help_line = lines[i + 2]-            # Help should have escaped newlines (\\n), not actual newlines-            assert "\\n" in help_line-            # Should contain the example text-            assert "image.jpg" in help_line.replace("\\n", " ")-            break-    else:-        pytest.fail("--at completion not found in output")+def test_fish_format_completion_escapes_help():+    fc = FishComplete(Command("x"), {}, "x", "_X_COMPLETE")+    item = CompletionItem("--at", help="first\nsecond\tthird")+    # The newline is escaped to the literal characters backslash-n and the tab+    # becomes a space, so each completion stays on one line for fish.+    assert fc.format_completion(item) == "plain,--at\tfirst\\nsecond third"
tests/test_stream_lifecycle.py +3 lines
--- +++ @@ -486,3 +486,5 @@ # These are marked with ``pytest.mark.stress`` so they can be included or-# excluded independently. The CI workflow runs them in a separate job.+# excluded independently. The ``tox -e stress`` env collects every+# ``pytest.mark.stress`` test across the suite (not just this file), so+# stress regressions for other components live alongside their unit tests. # ---------------------------------------------------------------------------
tests/test_termui.py +94 lines
--- +++ @@ -1,2 +1,3 @@ import contextlib+import gc import io@@ -728,2 +729,40 @@ +def test_echo_via_pager_streams_each_write(monkeypatch):+    """Each write is flushed so a slow generator streams to the pager+    incrementally instead of buffering until the end (issues #3242, #2542).+    """+    calls = []++    class RecordingStream(io.StringIO):+        def __init__(self):+            super().__init__()+            self.color = None++        def write(self, s):+            calls.append("write")+            return super().write(s)++        def flush(self):+            calls.append("flush")++    stream = RecordingStream()+    monkeypatch.setattr(click._termui_impl, "isatty", lambda _: False)+    monkeypatch.setattr(click._termui_impl, "_default_text_stdout", lambda: stream)++    def generate():+        yield "a\n"+        yield "b\n"+        yield "c\n"++    click.echo_via_pager(generate())++    # No two writes are adjacent: every chunk is flushed before the next one,+    # so the pager sees output as it is produced.+    assert not any(+        calls[i] == "write" and calls[i + 1] == "write" for i in range(len(calls) - 1)+    )+    assert calls.count("write") == 4  # three chunks plus the trailing newline+    assert stream.getvalue() == "a\nb\nc\n\n"++ def test_get_pager_file_pager_missing_binary_falls_back(monkeypatch, tmp_path):@@ -768,2 +807,57 @@     assert pager_out.read_text(encoding="utf-8") == "hello\n"+++def test_get_pager_file_missing_pager_keeps_borrowed_stream_open(monkeypatch):+    """A missing ``PAGER`` must not close the borrowed stdout (issue #3449).++    The ``8.4.0`` regression was only fixed for the no-tty ``_nullpager`` path;+    the ``_pipepager``/``_tempfilepager`` fallbacks (reached in a tty when+    ``PAGER`` resolves to nothing) used to close the borrowed stream too.+    """+    buffer = io.BytesIO()+    stream = io.TextIOWrapper(buffer, encoding="utf-8")++    monkeypatch.setitem(+        click._termui_impl.os.environ,+        "PAGER",+        "click-tests-nonexistent-pager-9b3f2",+    )+    monkeypatch.setattr(click._termui_impl, "isatty", lambda _: True)+    monkeypatch.setattr(click._termui_impl, "_default_text_stdout", lambda: stream)++    with click.get_pager_file() as pager:+        pager.write("hello\n")++    # Drop the wrapper reference and force finalization: the old bug closed the+    # borrowed buffer when the TextIOWrapper built by get_pager_file was+    # garbage-collected.+    del pager+    gc.collect()++    assert not buffer.closed+    assert not stream.closed+    assert buffer.getvalue().replace(b"\r\n", b"\n") == b"hello\n"+++def test_echo_via_pager_tty_pager_missing(runner, monkeypatch):+    """``echo_via_pager`` through the tty fallback keeps ``CliRunner`` working.++    Regression for issue #3449 via the pager fallback: a tty with ``PAGER``+    pointing at a missing binary used to close the runner's stdout, breaking+    ``CliRunner.invoke``.+    """+    monkeypatch.setattr(click._termui_impl, "isatty", lambda _: True)+    monkeypatch.setitem(+        click._termui_impl.os.environ,+        "PAGER",+        "click-tests-nonexistent-pager-9b3f2",+    )++    @click.command()+    def cli():+        click.echo_via_pager("Hello, Click!")++    result = runner.invoke(cli)+    assert not result.exception+    assert result.output == "Hello, Click!\n" 
tests/test_types.py +15 lines
--- +++ @@ -245,9 +245,18 @@ def test_file_surrogates(type, tmp_path):+    """Ensures that the error handling in ``click.File`` is robust.++    ``EILSEQ`` shows up with rootless Podman (FUSE-backed paths) and on filesystems+    that reject non-UTF-8 names, like ZFS with ``utf8only=on``.++    See: https://github.com/pallets/click/issues/2634+    """     path = tmp_path / "\udcff"--    # - common case: �': No such file or directory-    # - special case: Illegal byte sequence-    # The special case is seen with rootless Podman. The root cause is most-    # likely that the path is handled by a user-space program (FUSE).-    match = r"(�': No such file or directory|Illegal byte sequence)"+    match = (+        # Common case: �': No such file or directory.+        r"(�': No such file or directory"+        # BSD/macOS libc special case (EILSEQ).+        r"|Illegal byte sequence"+        # glibc special case (EILSEQ).+        r"|Invalid or incomplete multibyte or wide character)"+    )     with pytest.raises(click.BadParameter, match=match):
cryptography pypi
50.0.0 21d ago incident on record
critical-tier YANK ×3BURST ×2
latest 50.0.0 versions 158 maintainers 1 critical-tier (snapshotted)
46.0.1
46.0.2
46.0.3
46.0.4
46.0.5
46.0.6
46.0.7
47.0.0
48.0.0
48.0.1
49.0.0
50.0.0
YANK
37.0.3 marked yanked (still downloadable)
high · registry-verified · 2022-06-21 · 4y ago
YANK
38.0.2 marked yanked (still downloadable)
high · registry-verified · 2022-10-11 · 3y ago
YANK
45.0.0 marked yanked (still downloadable)
high · registry-verified · 2025-05-17 · 1y ago
BURST
2 releases in 46m: 2.4, 2.4.1
info · registry-verified · 2018-11-12 · 7y ago
BURST
2 releases in 53m: 45.0.0, 45.0.1
info · registry-verified · 2025-05-17 · 1y ago
release diff 49.0.0 → 50.0.0
+8 added · -0 removed · ~163 modified
+74 more files not shown
Cargo.toml +4 lines
--- +++ @@ -14,3 +14,3 @@ [workspace.package]-version = "0.49.0"+version = "0.50.0" authors = ["The cryptography developers <[email protected]>"]@@ -24,3 +24,3 @@ asn1 = { version = "0.24.1", default-features = false }-base64 = "0.22"+base64 = "0.23" cc = "1.2.63"@@ -31,4 +31,4 @@ openssl-sys = "0.9.116"-pem = { version = "3", default-features = false }-pyo3 = { version = "0.29", features = ["abi3"] }+pem = { version = "4", default-features = false }+pyo3 = { version = "0.29", features = ["abi3", "abi3t"] } pyo3-build-config = { version = "0.29" }
noxfile.py +12 lines
--- +++ @@ -26,2 +26,9 @@ +# See RUST_LOG in .github/workflows/ci.yml+UV_RUST_LOG = (+    "uv=debug,uv_client::cached_client=warn,"+    "uv_client::registry_client=error,uv_resolver::resolver=warn"+)++ def install(@@ -31,4 +38,6 @@ ) -> None:+    env = {}     if verbose:         args += ("-v",)+        env["RUST_LOG"] = UV_RUST_LOG     session.install(@@ -38,2 +47,3 @@         silent=False,+        env=env,     )@@ -98,7 +108,2 @@ -    if session.posargs:-        tests = session.posargs-    else:-        tests = ["tests/"]-     session.run(@@ -110,3 +115,3 @@         "--durations=10",-        *tests,+        *session.posargs,     )@@ -336,7 +341,2 @@ -    if session.posargs:-        tests = session.posargs-    else:-        tests = ["tests/"]-     session.run(@@ -347,3 +347,3 @@         "--durations=10",-        *tests,+        *session.posargs,     )
pyproject.toml +6 lines
--- +++ @@ -4,3 +4,3 @@ requires = [-    "maturin>=1.9.4,<2,!=1.12.0",+    "maturin>=1.14.1,<2", @@ -8,2 +8,3 @@     "cffi>=2.0.0; platform_python_implementation != 'PyPy'",+    "cffi>=2.1; python_version >= '3.15' and platform_python_implementation != 'PyPy'",     # Used by cffi (which import distutils, and in Python 3.12, distutils has@@ -17,3 +18,3 @@ name = "cryptography"-version = "49.0.0"+version = "50.0.0" authors = [@@ -77,3 +78,3 @@ test = [-    "cryptography_vectors==49.0.0",+    "cryptography_vectors==50.0.0",     "pytest >=7.4.0",@@ -142,2 +143,3 @@ addopts = "-r s --capture=no --strict-markers --benchmark-disable"+testpaths = ["tests"] console_output_style = "progress-even-when-capture-no"@@ -146,2 +148,3 @@     "supported: parametrized test requiring only_if and skip_message",+    "malloc_failure: this test expects malloc to fail under memory pressure and should not be run with overcommit", ]
src/_cffi_src/__init__.py +1 lines
--- +++ @@ -0,0 +1 @@+from __future__ import annotations
src/_cffi_src/openssl/__init__.py +2 lines
--- +++ @@ -3 +3,3 @@ # for complete details.++from __future__ import annotations
src/_cffi_src/openssl/pem.py +0 lines
--- +++ @@ -24,6 +24,2 @@ -int PEM_write_bio_X509_REQ(BIO *, X509_REQ *);--X509_REQ *PEM_read_bio_X509_REQ(BIO *, X509_REQ **, pem_password_cb *, void *);- DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *);
src/_cffi_src/openssl/x509.py +0 lines
--- +++ @@ -24,3 +24,2 @@ typedef ... X509_EXTENSION;-typedef ... X509_REQ; typedef ... X509_CRL;@@ -54,11 +53,2 @@ -int X509_REQ_set_version(X509_REQ *, long);-X509_REQ *X509_REQ_new(void);-void X509_REQ_free(X509_REQ *);-int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);-int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);-int X509_REQ_verify(X509_REQ *, EVP_PKEY *);-EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);-int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long);- X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **);@@ -69,5 +59,2 @@ X509 *d2i_X509_bio(BIO *, X509 **);--int i2d_X509_REQ_bio(BIO *, X509_REQ *);-X509_REQ *d2i_X509_REQ_bio(BIO *, X509_REQ **); @@ -97,5 +84,2 @@ -long X509_REQ_get_version(X509_REQ *);-X509_NAME *X509_REQ_get_subject_name(X509_REQ *);- Cryptography_STACK_OF_X509 *sk_X509_new_null(void);
src/cryptography/__about__.py +1 lines
--- +++ @@ -12,3 +12,3 @@ -__version__ = "49.0.0"+__version__ = "50.0.0" 
src/cryptography/cobblestone.py +21 lines
--- +++ @@ -0,0 +1,21 @@+# This file is dual licensed under the terms of the Apache License, Version+# 2.0, and the BSD License. See the LICENSE file in the root of this repository+# for complete details.++from __future__ import annotations++from cryptography.hazmat.bindings._rust import (+    cobblestone as _cobblestone,+)++Cobblestone128Decryptor = _cobblestone.Cobblestone128Decryptor+Cobblestone128Encryptor = _cobblestone.Cobblestone128Encryptor+Cobblestone256Decryptor = _cobblestone.Cobblestone256Decryptor+Cobblestone256Encryptor = _cobblestone.Cobblestone256Encryptor++__all__ = [+    "Cobblestone128Decryptor",+    "Cobblestone128Encryptor",+    "Cobblestone256Decryptor",+    "Cobblestone256Encryptor",+]
src/cryptography/fernet.py +38 lines
--- +++ @@ -26,2 +26,6 @@ +# Hoisted to module level so each operation doesn't reconstruct them.+_PKCS7_128 = padding.PKCS7(128)+_SHA256 = hashes.SHA256()+ @@ -46,2 +50,3 @@         self._encryption_key = key[16:]+        self._aes = algorithms.AES(self._encryption_key) @@ -63,8 +68,5 @@ -        padder = padding.PKCS7(algorithms.AES.block_size).padder()+        padder = _PKCS7_128.padder()         padded_data = padder.update(data) + padder.finalize()-        encryptor = Cipher(-            algorithms.AES(self._encryption_key),-            modes.CBC(iv),-        ).encryptor()+        encryptor = Cipher(self._aes, modes.CBC(iv)).encryptor()         ciphertext = encryptor.update(padded_data) + encryptor.finalize()@@ -78,3 +80,3 @@ -        h = HMAC(self._signing_key, hashes.SHA256())+        h = HMAC(self._signing_key, _SHA256)         h.update(basic_parts)@@ -127,4 +129,4 @@     def _verify_signature(self, data: bytes) -> None:-        h = HMAC(self._signing_key, hashes.SHA256())-        h.update(data[:-32])+        h = HMAC(self._signing_key, _SHA256)+        h.update(memoryview(data)[:-32])         try:@@ -150,7 +152,6 @@ +        mv = memoryview(data)         iv = data[9:25]-        ciphertext = data[25:-32]-        decryptor = Cipher(-            algorithms.AES(self._encryption_key), modes.CBC(iv)-        ).decryptor()+        ciphertext = mv[25:-32]+        decryptor = Cipher(self._aes, modes.CBC(iv)).decryptor()         plaintext_padded = decryptor.update(ciphertext)@@ -160,3 +161,3 @@             raise InvalidToken-        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()+        unpadder = _PKCS7_128.unpadder() @@ -200,5 +201,11 @@     def decrypt(self, msg: bytes | str, ttl: int | None = None) -> bytes:-        for f in self._fernets:-            try:-                return f.decrypt(msg, ttl)+        if ttl is None:+            time_info = None+        else:+            time_info = (ttl, int(time.time()))+        # Parse the token once rather than once per key.+        timestamp, data = Fernet._get_unverified_token_data(msg)+        for f in self._fernets:+            try:+                return f._decrypt_data(data, timestamp, time_info)             except InvalidToken:@@ -210,5 +217,11 @@     ) -> bytes:-        for f in self._fernets:-            try:-                return f.decrypt_at_time(msg, ttl, current_time)+        if ttl is None:+            raise ValueError(+                "decrypt_at_time() can only be used with a non-None ttl"+            )+        # Parse the token once rather than once per key.+        timestamp, data = Fernet._get_unverified_token_data(msg)+        for f in self._fernets:+            try:+                return f._decrypt_data(data, timestamp, (ttl, current_time))             except InvalidToken:@@ -218,5 +231,8 @@     def extract_timestamp(self, msg: bytes | str) -> int:-        for f in self._fernets:-            try:-                return f.extract_timestamp(msg)+        # Parse the token once rather than once per key.+        timestamp, data = Fernet._get_unverified_token_data(msg)+        for f in self._fernets:+            try:+                f._verify_signature(data)+                return timestamp             except InvalidToken:
src/cryptography/hazmat/_oid.py +5 lines
--- +++ @@ -89,2 +89,3 @@     UNSTRUCTURED_NAME = ObjectIdentifier("1.2.840.113549.1.9.2")+    UNSIGNED = ObjectIdentifier("1.3.6.1.5.5.7.25.1") @@ -127,2 +128,3 @@     GOSTR3410_2012_WITH_3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3")+    UNSIGNED = ObjectIdentifier("1.3.6.1.5.5.7.6.36") @@ -161,2 +163,3 @@     SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_512: None,+    SignatureAlgorithmOID.UNSIGNED: None, }@@ -192,2 +195,4 @@     ML_DSA_87 = ObjectIdentifier("2.16.840.1.101.3.4.3.19")+    ML_KEM_768 = ObjectIdentifier("2.16.840.1.101.3.4.4.2")+    ML_KEM_1024 = ObjectIdentifier("2.16.840.1.101.3.4.4.3") 
src/cryptography/hazmat/asn1/__init__.py +2 lines
--- +++ @@ -3,2 +3,4 @@ # for complete details.++from __future__ import annotations 
src/cryptography/hazmat/backends/openssl/backend.py +5 lines
--- +++ @@ -146,2 +146,6 @@                     hashes.SHA512_256,+                    hashes.SHA3_224,+                    hashes.SHA3_256,+                    hashes.SHA3_384,+                    hashes.SHA3_512,                 ),@@ -158,5 +162,2 @@         return rust_openssl.ciphers.cipher_supported(cipher, mode)--    def pbkdf2_hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool:-        return self.hmac_supported(algorithm) @@ -254,6 +255,3 @@     def dh_supported(self) -> bool:-        return (-            not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL-            and not rust_openssl.CRYPTOGRAPHY_IS_AWSLC-        )+        return not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL @@ -309,5 +307,2 @@ -    def pkcs7_supported(self) -> bool:-        return True- 
src/cryptography/hazmat/bindings/__init__.py +2 lines
--- +++ @@ -3 +3,3 @@ # for complete details.++from __future__ import annotations
src/cryptography/hazmat/bindings/openssl/__init__.py +2 lines
--- +++ @@ -3 +3,3 @@ # for complete details.++from __future__ import annotations
src/cryptography/hazmat/decrepit/ciphers/algorithms.py +3 lines
--- +++ @@ -34,2 +34,5 @@     def __init__(self, key: bytes):+        # Check the key type before the length-based deprecation warnings so+        # an invalid key type doesn't trigger a spurious warning.+        utils._check_byteslike("key", key)         if len(key) == 8:
src/cryptography/hazmat/primitives/__init__.py +2 lines
--- +++ @@ -3 +3,3 @@ # for complete details.++from __future__ import annotations
src/cryptography/hazmat/primitives/asymmetric/__init__.py +2 lines
--- +++ @@ -3 +3,3 @@ # for complete details.++from __future__ import annotations
src/cryptography/hazmat/primitives/asymmetric/dh.py +94 lines
--- +++ @@ -8,4 +8,11 @@ +from cryptography import utils from cryptography.hazmat.bindings._rust import openssl as rust_openssl from cryptography.hazmat.primitives import _serialization++_FFDH_DEPRECATION_MSG = (+    "Diffie-Hellman over finite fields (FFDH) is deprecated and support "+    "will be removed in a future release. Use a more modern key exchange "+    "algorithm."+) @@ -159 +166,88 @@ DHPrivateKey.register(rust_openssl.dh.DHPrivateKey)++# Aliases that do not emit the deprecation warning on attribute access, for+# internal use (e.g. the unions in+# cryptography.hazmat.primitives.asymmetric.types, which are evaluated at+# import time).+_DHPublicKey = DHPublicKey+_DHPrivateKey = DHPrivateKey++utils.deprecated(+    generate_parameters,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="generate_parameters",+)++utils.deprecated(+    DHPrivateNumbers,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPrivateNumbers",+)++utils.deprecated(+    DHPublicNumbers,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPublicNumbers",+)++utils.deprecated(+    DHParameterNumbers,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHParameterNumbers",+)++utils.deprecated(+    DHParameters,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHParameters",+)++utils.deprecated(+    DHParameters,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHParametersWithSerialization",+)++utils.deprecated(+    DHPublicKey,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPublicKey",+)++utils.deprecated(+    DHPublicKey,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPublicKeyWithSerialization",+)++utils.deprecated(+    DHPrivateKey,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPrivateKey",+)++utils.deprecated(+    DHPrivateKey,+    __name__,+    _FFDH_DEPRECATION_MSG,+    utils.DeprecatedIn50,+    name="DHPrivateKeyWithSerialization",+)
src/cryptography/hazmat/primitives/asymmetric/mldsa.py +1 lines
--- +++ @@ -504 +504,2 @@     MLDSA87PrivateKey.register(rust_openssl.mldsa.MLDSA87PrivateKey)+    MLDSAMuHasher = rust_openssl.mldsa.MLDSAMuHasher
src/cryptography/hazmat/primitives/asymmetric/padding.py +30 lines
--- +++ @@ -17,2 +17,8 @@     name = "EMSA-PKCS1-v1_5"++    def __eq__(self, other: object) -> bool:+        if not isinstance(other, PKCS1v15):+            return NotImplemented++        return True @@ -58,2 +64,10 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, PSS):+            return NotImplemented++        return (+            self._mgf == other._mgf and self._salt_length == other._salt_length+        )+     @property@@ -79,2 +93,12 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, OAEP):+            return NotImplemented++        return (+            self._mgf == other._mgf+            and self._algorithm == other._algorithm+            and self._label == other._label+        )+     @property@@ -99,2 +123,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, MGF1):+            return NotImplemented++        return self._algorithm == other._algorithm+ 
src/cryptography/hazmat/primitives/asymmetric/types.py +7 lines
--- +++ @@ -21,5 +21,6 @@ -# Every asymmetric key type+# Every asymmetric key type. These use the private DH aliases so that+# importing this module doesn't trigger the FFDH deprecation warning. PublicKeyTypes = typing.Union[-    dh.DHPublicKey,+    dh._DHPublicKey,     dsa.DSAPublicKey,@@ -39,3 +40,3 @@ PrivateKeyTypes = typing.Union[-    dh.DHPrivateKey,+    dh._DHPrivateKey,     ed25519.Ed25519PrivateKey,@@ -77,3 +78,3 @@ ]-# This type removes DHPublicKey. x448/x25519 can be a public key+# This type removes DHPublicKey. x448/x25519/mlkem can be a public key # but cannot be used in signing so they are allowed here.@@ -88,2 +89,4 @@     mldsa.MLDSA87PublicKey,+    mlkem.MLKEM768PublicKey,+    mlkem.MLKEM1024PublicKey,     x25519.X25519PublicKey,
src/cryptography/hazmat/primitives/ciphers/modes.py +1 lines
--- +++ @@ -106,3 +106,3 @@     _MAX_ENCRYPTED_BYTES = (2**39 - 256) // 8-    _MAX_AAD_BYTES = (2**64) // 8+    _MAX_AAD_BYTES = (2**64 - 1) // 8 
src/cryptography/hazmat/primitives/hashes.py +111 lines
--- +++ @@ -7,2 +7,3 @@ import abc+import sys @@ -105,2 +106,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA1):+            return NotImplemented++        return True+ @@ -111,2 +118,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA512_224):+            return NotImplemented++        return True+ @@ -117,2 +130,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA512_256):+            return NotImplemented++        return True+ @@ -123,2 +142,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA224):+            return NotImplemented++        return True+ @@ -129,2 +154,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA256):+            return NotImplemented++        return True+ @@ -135,2 +166,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA384):+            return NotImplemented++        return True+ @@ -141,2 +178,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA512):+            return NotImplemented++        return True+ @@ -147,2 +190,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA3_224):+            return NotImplemented++        return True+ @@ -153,2 +202,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA3_256):+            return NotImplemented++        return True+ @@ -159,2 +214,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA3_384):+            return NotImplemented++        return True+ @@ -165,2 +226,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHA3_512):+            return NotImplemented++        return True+ @@ -179,2 +246,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHAKE128):+            return NotImplemented++        return self._digest_size == other._digest_size+     @property@@ -182,2 +255,6 @@         return self._digest_size++    @classmethod+    def xof(cls):+        return cls(sys.maxsize) @@ -197,2 +274,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SHAKE256):+            return NotImplemented++        return self._digest_size == other._digest_size+     @property@@ -200,2 +283,6 @@         return self._digest_size++    @classmethod+    def xof(cls):+        return cls(sys.maxsize) @@ -206,2 +293,8 @@     block_size = 64++    def __eq__(self, other: object) -> bool:+        if not isinstance(other, MD5):+            return NotImplemented++        return True @@ -220,2 +313,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, BLAKE2b):+            return NotImplemented++        return self._digest_size == other._digest_size+     @property@@ -237,2 +336,8 @@ +    def __eq__(self, other: object) -> bool:+        if not isinstance(other, BLAKE2s):+            return NotImplemented++        return self._digest_size == other._digest_size+     @property@@ -246 +351,7 @@     block_size = 64++    def __eq__(self, other: object) -> bool:+        if not isinstance(other, SM3):+            return NotImplemented++        return True
src/cryptography/hazmat/primitives/keywrap.py +14 lines
--- +++ @@ -6,172 +6,11 @@ -import typing+from cryptography.hazmat.bindings._rust import openssl as rust_openssl -from cryptography.hazmat.primitives.ciphers import Cipher-from cryptography.hazmat.primitives.ciphers.algorithms import AES-from cryptography.hazmat.primitives.ciphers.modes import ECB-from cryptography.hazmat.primitives.constant_time import bytes_eq---def _wrap_core(-    wrapping_key: bytes,-    a: bytes,-    r: list[bytes],-) -> bytes:-    # RFC 3394 Key Wrap - 2.2.1 (index method)-    encryptor = Cipher(AES(wrapping_key), ECB()).encryptor()-    n = len(r)-    for j in range(6):-        for i in range(n):-            # every encryption operation is a discrete 16 byte chunk (because-            # AES has a 128-bit block size) and since we're using ECB it is-            # safe to reuse the encryptor for the entire operation-            b = encryptor.update(a + r[i])-            a = (-                int.from_bytes(b[:8], byteorder="big") ^ ((n * j) + i + 1)-            ).to_bytes(length=8, byteorder="big")-            r[i] = b[-8:]--    assert encryptor.finalize() == b""--    return a + b"".join(r)---def aes_key_wrap(-    wrapping_key: bytes,-    key_to_wrap: bytes,-    backend: typing.Any = None,-) -> bytes:-    if len(wrapping_key) not in [16, 24, 32]:-        raise ValueError("The wrapping key must be a valid AES key length")--    if len(key_to_wrap) < 16:-        raise ValueError("The key to wrap must be at least 16 bytes")--    if len(key_to_wrap) % 8 != 0:-        raise ValueError("The key to wrap must be a multiple of 8 bytes")--    a = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"-    r = [key_to_wrap[i : i + 8] for i in range(0, len(key_to_wrap), 8)]-    return _wrap_core(wrapping_key, a, r)---def _unwrap_core(-    wrapping_key: bytes,-    a: bytes,-    r: list[bytes],-) -> tuple[bytes, list[bytes]]:-    # Implement RFC 3394 Key Unwrap - 2.2.2 (index method)-    decryptor = Cipher(AES(wrapping_key), ECB()).decryptor()-    n = len(r)-    for j in reversed(range(6)):-        for i in reversed(range(n)):-            atr = (-                int.from_bytes(a, byteorder="big") ^ ((n * j) + i + 1)-            ).to_bytes(length=8, byteorder="big") + r[i]-            # every decryption operation is a discrete 16 byte chunk so-            # it is safe to reuse the decryptor for the entire operation-            b = decryptor.update(atr)-            a = b[:8]-            r[i] = b[-8:]--    assert decryptor.finalize() == b""-    return a, r---def aes_key_wrap_with_padding(-    wrapping_key: bytes,-    key_to_wrap: bytes,-    backend: typing.Any = None,-) -> bytes:-    if len(wrapping_key) not in [16, 24, 32]:-        raise ValueError("The wrapping key must be a valid AES key length")--    if not key_to_wrap or len(key_to_wrap) > 2**32:-        raise ValueError("key_to_wrap must be between 1 and 2^32 bytes")--    aiv = b"\xa6\x59\x59\xa6" + len(key_to_wrap).to_bytes(-        length=4, byteorder="big"-    )-    # pad the key to wrap if necessary-    pad = (8 - (len(key_to_wrap) % 8)) % 8-    key_to_wrap = key_to_wrap + b"\x00" * pad-    if len(key_to_wrap) == 8:-        # RFC 5649 - 4.1 - exactly 8 octets after padding-        encryptor = Cipher(AES(wrapping_key), ECB()).encryptor()-        b = encryptor.update(aiv + key_to_wrap)-        assert encryptor.finalize() == b""-        return b-    else:-        r = [key_to_wrap[i : i + 8] for i in range(0, len(key_to_wrap), 8)]-        return _wrap_core(wrapping_key, aiv, r)---def aes_key_unwrap_with_padding(-    wrapping_key: bytes,-    wrapped_key: bytes,-    backend: typing.Any = None,-) -> bytes:-    if len(wrapped_key) < 16:-        raise InvalidUnwrap("Must be at least 16 bytes")--    if len(wrapping_key) not in [16, 24, 32]:-        raise ValueError("The wrapping key must be a valid AES key length")--    if len(wrapped_key) == 16:-        # RFC 5649 - 4.2 - exactly two 64-bit blocks-        decryptor = Cipher(AES(wrapping_key), ECB()).decryptor()-        out = decryptor.update(wrapped_key)-        assert decryptor.finalize() == b""-        a = out[:8]-        data = out[8:]-        n = 1-    else:-        r = [wrapped_key[i : i + 8] for i in range(0, len(wrapped_key), 8)]-        encrypted_aiv = r.pop(0)-        n = len(r)-        a, r = _unwrap_core(wrapping_key, encrypted_aiv, r)-        data = b"".join(r)--    # 1) Check that MSB(32,A) = A65959A6.-    # 2) Check that 8*(n-1) < LSB(32,A) <= 8*n.  If so, let-    #    MLI = LSB(32,A).-    # 3) Let b = (8*n)-MLI, and then check that the rightmost b octets of-    #    the output data are zero.-    mli = int.from_bytes(a[4:], byteorder="big")-    b = (8 * n) - mli-    if (-        not bytes_eq(a[:4], b"\xa6\x59\x59\xa6")-        or not 8 * (n - 1) < mli <= 8 * n-        or (b != 0 and not bytes_eq(data[-b:], b"\x00" * b))-    ):-        raise InvalidUnwrap()--    if b == 0:-        return data-    else:-        return data[:-b]---def aes_key_unwrap(-    wrapping_key: bytes,-    wrapped_key: bytes,-    backend: typing.Any = None,-) -> bytes:-    if len(wrapped_key) < 24:-        raise InvalidUnwrap("Must be at least 24 bytes")--    if len(wrapped_key) % 8 != 0:-        raise InvalidUnwrap("The wrapped key must be a multiple of 8 bytes")--    if len(wrapping_key) not in [16, 24, 32]:-        raise ValueError("The wrapping key must be a valid AES key length")--    aiv = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"-    r = [wrapped_key[i : i + 8] for i in range(0, len(wrapped_key), 8)]-    a = r.pop(0)-    a, r = _unwrap_core(wrapping_key, a, r)-    if not bytes_eq(a, aiv):-        raise InvalidUnwrap()--    return b"".join(r)+__all__ = [+    "InvalidUnwrap",+    "aes_key_unwrap",+    "aes_key_unwrap_with_padding",+    "aes_key_wrap",+    "aes_key_wrap_with_padding",+] @@ -180 +19,7 @@     pass+++aes_key_wrap = rust_openssl.keywrap.aes_key_wrap+aes_key_unwrap = rust_openssl.keywrap.aes_key_unwrap+aes_key_wrap_with_padding = rust_openssl.keywrap.aes_key_wrap_with_padding+aes_key_unwrap_with_padding = rust_openssl.keywrap.aes_key_unwrap_with_padding
grpcio-status pypi
1.83.0 29d ago incident on record
YANK ×10BURST ×6INSTALL-EXEC
latest 1.83.0 versions 201 maintainers 1
1.74.0
1.75.0
1.75.1
1.76.0
1.78.0
1.78.1
1.80.0
1.81.0
1.81.1
1.82.0
1.82.1
1.83.0
YANK
1.45.0 marked yanked (still downloadable)
high · registry-verified · 2022-03-23 · 4y ago
YANK
1.48.0 marked yanked (still downloadable)
high · registry-verified · 2022-07-28 · 4y ago
YANK
1.49.0 marked yanked (still downloadable)
high · registry-verified · 2022-09-15 · 3y ago
YANK
1.51.0 marked yanked (still downloadable)
high · registry-verified · 2022-11-21 · 3y ago
YANK
1.52.0 marked yanked (still downloadable)
high · registry-verified · 2023-02-06 · 3y ago
YANK
1.55.0 marked yanked (still downloadable)
high · registry-verified · 2023-05-22 · 3y ago
YANK
1.65.0 marked yanked (still downloadable)
high · registry-verified · 2024-07-11 · 2y ago
YANK
1.72.0 marked yanked (still downloadable)
high · registry-verified · 2025-04-25 · 1y ago
YANK
1.78.1 marked yanked (still downloadable)
high · registry-verified · 2026-02-20 · 6mo ago
YANK
1.82.0 marked yanked (still downloadable)
high · registry-verified · 2026-07-06 · 1mo ago
BURST
2 releases in 33m: 1.22.1, 1.23.0
info · registry-verified · 2019-08-15 · 7y ago
BURST
4 releases in 37m: 1.46.5, 1.47.2, 1.48.2, 1.49.1
info · registry-verified · 2022-09-22 · 3y ago
BURST
2 releases in 11m: 1.53.1, 1.54.2
info · registry-verified · 2023-05-12 · 3y ago
BURST
2 releases in 2m: 1.54.3, 1.53.2
info · registry-verified · 2023-08-02 · 3y ago
BURST
5 releases in 54m: 1.64.3, 1.63.2, 1.62.3, 1.61.3, 1.60.2
info · registry-verified · 2024-08-06 · 2y ago
BURST
2 releases in 9m: 1.59.5, 1.58.3
info · registry-verified · 2024-08-06 · 2y ago
INSTALL-EXEC
setup.py in sdist uses install-hook (runs at pip install)
warn · snapshot-derived
release diff 1.82.1 → 1.83.0
+0 added · -0 removed · ~5 modified
grpc_version.py +1 lines
--- +++ @@ -16,2 +16,2 @@ -VERSION = '1.82.1'+VERSION = '1.83.0'
setup.py +3 lines
--- +++ @@ -56,3 +56,5 @@ INSTALL_REQUIRES = (-    "protobuf>=7.35.1,<8.0.0",+    # Note that we don't ship pb2 files with this package, so the protobuf+    # version bounds don't have to be in lockstep with grpcio-tools.+    "protobuf>=6.33.5,<8.0.0",     "grpcio>={version}".format(version=grpc_version.VERSION),
numpy pypi
2.5.2 12d ago incident on record
YANKBURST ×2
latest 2.5.2 versions 150 maintainers 1
2.3.4
2.3.5
2.4.0
2.4.1
2.4.2
2.4.3
2.4.4
2.4.5
2.4.6
2.5.0
2.5.1
2.5.2
YANK
2.4.0 marked yanked (still downloadable)
high · registry-verified · 2025-12-20 · 8mo ago
BURST
3 releases in 22m: 1.10.4, 1.9.3, 1.8.2
info · registry-verified · 2016-04-20 · 10y ago
BURST
15 releases in 40m: 1.7.2, 1.6.2, 1.10.3, 1.10.2, 1.10.1, 1.10.0, 1.9.2, 1.9.1, 1.9.0, 1.8.1, 1.8.0, 1.7.1, 1.7.0, 1.6.1, 1.6.0
info · registry-verified · 2016-04-20 · 10y ago
release diff 2.5.1 → 2.5.2
artifact too large or unavailable
packaging pypi
26.3 17d ago incident on record
critical-tier YANKBURST ×3
latest 26.3 versions 54 maintainers 1 critical-tier (snapshotted)
22.0
23.0
23.1
23.2
24.0
24.1
24.2
25.0
26.0
26.1
26.2
26.3
YANK
20.6 marked yanked (still downloadable)
high · registry-verified · 2020-11-28 · 5y ago
BURST
2 releases in 9m: 20.2, 20.3
info · registry-verified · 2020-03-05 · 6y ago
BURST
2 releases in 3m: 20.6, 20.7
info · registry-verified · 2020-11-28 · 5y ago
BURST
2 releases in 5m: 21.1, 21.2
info · registry-verified · 2021-10-29 · 4y ago
release diff 26.2 → 26.3
+10 added · -0 removed · ~51 modified
+20 more files not shown
src/packaging/_manylinux.py +34 lines · 1 flagged
--- +++ @@ -9,5 +9,9 @@ import warnings-from typing import Generator, Iterator, NamedTuple, Sequence+from typing import TYPE_CHECKING, NamedTuple  from ._elffile import EIClass, EIData, ELFFile, EMachine++if TYPE_CHECKING:+    import types+    from collections.abc import Generator, Iterator, Sequence @@ -28,4 +32,2 @@ -# `os.PathLike` not a generic type until Python 3.9, so sticking with `str`-# as the type for `path` until then. @contextlib.contextmanager@@ -138,7 +140,7 @@ -    # Call gnu_get_libc_version, which returns a string like "2.5"+    # Call gnu_get_libc_version, which returns a string like "2.5".     gnu_get_libc_version.restype = ctypes.c_char_p-    version_str: str = gnu_get_libc_version()-    # py2 / py3 compatibility:-    if not isinstance(version_str, str):+    # A c_char_p restype comes back as bytes, so decode to text.+    version_str: str | bytes = gnu_get_libc_version()+    if isinstance(version_str, bytes):         version_str = version_str.decode("ascii")@@ -181,2 +183,15 @@ # From PEP 513, PEP 600[email protected]_cache(maxsize=1)+def _get_manylinux_module() -> types.ModuleType | None:+    """Return the ``_manylinux`` C extension module, or None if unavailable.++    The result is cached for the lifetime of the process, since the presence+    of the module does not change while running.+    """+    try:+        return __import__("_manylinux")+    except ImportError:+        return None++ def _is_compatible(arch: str, version: _GLibCVersion) -> bool:@@ -186,8 +201,7 @@     # Check for presence of _manylinux module.-    try:-        import _manylinux  # noqa: PLC0415-    except ImportError:+    manylinux_mod = _get_manylinux_module()+    if manylinux_mod is None:         return True-    if hasattr(_manylinux, "manylinux_compatible"):-        result = _manylinux.manylinux_compatible(version[0], version[1], arch)+    if hasattr(manylinux_mod, "manylinux_compatible"):+        result = manylinux_mod.manylinux_compatible(version[0], version[1], arch)         if result is not None:@@ -195,12 +209,14 @@         return True-    if version == _GLibCVersion(2, 5) and hasattr(_manylinux, "manylinux1_compatible"):-        return bool(_manylinux.manylinux1_compatible)+    if version == _GLibCVersion(2, 5) and hasattr(+        manylinux_mod, "manylinux1_compatible"+    ):+        return bool(manylinux_mod.manylinux1_compatible)     if version == _GLibCVersion(2, 12) and hasattr(-        _manylinux, "manylinux2010_compatible"+        manylinux_mod, "manylinux2010_compatible"     ):-        return bool(_manylinux.manylinux2010_compatible)+        return bool(manylinux_mod.manylinux2010_compatible)     if version == _GLibCVersion(2, 17) and hasattr(-        _manylinux, "manylinux2014_compatible"+        manylinux_mod, "manylinux2014_compatible"     ):-        return bool(_manylinux.manylinux2014_compatible)+        return bool(manylinux_mod.manylinux2014_compatible)     return True
src/packaging/direct_url.py +32 lines · 2 flagged
--- +++ @@ -11,2 +11,3 @@     from collections.abc import Collection+    from urllib.parse import SplitResult @@ -85,3 +86,3 @@         return netloc-    user_pass, netloc_no_user_pass = netloc.split("@", 1)+    user_pass, netloc_no_user_pass = netloc.rsplit("@", 1)     if user_pass in safe_user_passwords:@@ -111,4 +112,11 @@ +def _file_url_has_absolute_path(parsed_url: SplitResult) -> bool:+    return parsed_url.path.startswith("/")++ class DirectUrlValidationError(Exception):-    """Raised when when input data is not spec-compliant."""+    """Raised when when input data is not spec-compliant.++    .. versionadded:: 26.1+    """ @@ -148,2 +156,4 @@ class VcsInfo:+    """The version control information of a :class:`DirectUrl`."""+     vcs: str@@ -175,2 +185,4 @@ class ArchiveInfo:+    """The archive information of a :class:`DirectUrl`."""+     hashes: Mapping[str, str] | None = None@@ -221,2 +233,4 @@ class DirInfo:+    """The local directory information of a :class:`DirectUrl`."""+     editable: bool | None = None@@ -239,3 +253,6 @@ class DirectUrl:-    """A class representing a direct URL."""+    """A class representing a direct URL.++    .. versionadded:: 26.1+    """ @@ -279,7 +296,14 @@             )-        if direct_url.dir_info is not None and not direct_url.url.startswith("file://"):-            raise DirectUrlValidationError(-                "URL scheme must be file:// when dir_info is present",-                context="url",-            )+        if direct_url.dir_info is not None:+            parsed_url = urllib.parse.urlsplit(direct_url.url)+            if parsed_url.scheme != "file":+                raise DirectUrlValidationError(+                    "URL scheme must be file:// when dir_info is present",+                    context="url",+                )+            if not _file_url_has_absolute_path(parsed_url):+                raise DirectUrlValidationError(+                    "File URL must be absolute when dir_info is present",+                    context="url",+                )         # XXX subdirectory must be relative, can we, should we validate that here?
src/packaging/pylock.py +47 lines · 1 flagged
--- +++ @@ -16,5 +16,10 @@ )-from urllib.parse import urlparse--from .markers import Environment, Marker, default_environment+from urllib.parse import unquote, urlparse++from .markers import (+    Environment,+    Marker,+    _pep440_python_full_version,+    default_environment,+) from .specifiers import SpecifierSet@@ -47,2 +52,3 @@     "Pylock",+    "PylockSelectError",     "PylockUnsupportedVersionError",@@ -101,3 +107,6 @@         return None-    if not isinstance(value, expected_type):+    if not isinstance(value, expected_type) or (+        # Special case: bool is a subclass of int, but TOML distinguishes the two+        expected_type is int and isinstance(value, bool)+    ):         raise PylockValidationError(@@ -257,3 +266,4 @@     url_path = urlparse(url).path-    return url_path.rsplit("/", 1)[-1]+    # The last path component is percent-encoded, so decode it to the file name+    return unquote(url_path.rsplit("/", 1)[-1]) @@ -308,3 +318,6 @@ class PylockSelectError(Exception):-    """Base exception for errors raised by :meth:`Pylock.select`."""+    """Base exception for errors raised by :meth:`Pylock.select`.++    .. versionadded:: 26.1+    """ @@ -462,3 +475,6 @@     def filename(self) -> str:-        """Get the filename of the sdist."""+        """Get the filename of the sdist.++        .. versionadded:: 26.1+        """         filename = self.name or _path_name(self.path) or _url_name(self.url)@@ -739,2 +755,3 @@         dependency_groups: Collection[str] | None = None,+        prefer_sdist_predicate: Callable[[NormalizedName], bool] | None = None,     ) -> Iterator[@@ -760,2 +777,7 @@ +        The *prefer_sdist_predicate* parameter is called for packages with a source+        distribution. If it returns ``True``, the source distribution is selected+        before attempting wheel compatibility. If no source distribution is+        available, wheel selection proceeds as usual without calling the predicate.+         This method must be used on valid Pylock instances (i.e. one obtained@@ -763,4 +785,11 @@         :meth:`Pylock.validate`).++        .. versionadded:: 26.1++        .. versionchanged:: 26.3+            Added the *prefer_sdist_predicate* parameter.         """-        compatible_tags_selector = create_compatible_tags_selector(tags or sys_tags())+        compatible_tags_selector = create_compatible_tags_selector(+            tags if tags is not None else sys_tags()+        ) @@ -784,3 +813,3 @@         )-        env_python_full_version = (+        env_python_full_version = _pep440_python_full_version(             environment["python_full_version"]@@ -871,2 +900,11 @@                 yield package, package.archive++            # - Else if source preference selects an available+            #   :ref:`pylock-packages-sdist`:+            elif (+                package.sdist is not None+                and prefer_sdist_predicate is not None+                and prefer_sdist_predicate(package.name)+            ):+                yield package, package.sdist 
src/packaging/tags.py +182 lines · 2 flagged
--- +++ @@ -14,2 +14,3 @@ import sysconfig+from collections.abc import Iterable, Iterator, Sequence from importlib.machinery import EXTENSION_SUFFIXES@@ -17,6 +18,2 @@     TYPE_CHECKING,-    Iterable,-    Iterator,-    Sequence,-    Tuple,     TypeVar,@@ -28,4 +25,4 @@ if TYPE_CHECKING:-    from collections.abc import Callable, Iterable-    from typing import AbstractSet+    from collections.abc import Callable+    from collections.abc import Set as AbstractSet @@ -35,4 +32,6 @@     "AppleVersion",+    "InvalidTag",     "PythonVersion",     "Tag",+    "TooManyTagsError",     "UnsortedTagsError",@@ -49,2 +48,3 @@     "platform_tags",+    "pure_python_tags",     "sys_tags",@@ -60,3 +60,14 @@ PythonVersion = Sequence[int]-AppleVersion = Tuple[int, int]+"""+A sequence of integers describing a Python version, e.g. ``(3, 13)``.++.. versionadded:: 20.0+"""++AppleVersion = tuple[int, int]+"""+A ``(major, minor)`` integer pair describing an Apple OS version.++.. versionadded:: 24.2+""" _T = TypeVar("_T")@@ -84,2 +95,21 @@     Raised when a tag component is not in sorted order per PEP 425.++    .. versionadded:: 26.1+    """+++class InvalidTag(ValueError):+    """+    Raised when an interpreter component is not an identifier, a tag component+    is empty, or a tag does not have exactly three components.++    .. versionadded:: 26.3+    """+++class TooManyTagsError(ValueError):+    """+    Raised when a compressed tag set exceeds the configured limit.++    .. versionadded:: 26.3     """@@ -202,3 +232,5 @@ -def parse_tag(tag: str, *, validate_order: bool = False) -> frozenset[Tag]:+def parse_tag(+    tag: str, *, validate_order: bool = False, limit: int | None = None+) -> frozenset[Tag]:     """@@ -214,2 +246,5 @@ +    If **limit** is not ``None``, the compressed tag set can generate at most+    that many tags.+     :param str tag: The tag to parse, e.g. ``"py3-none-any"``.@@ -217,4 +252,11 @@         are in sorted order.+    :param int | None limit: The maximum number of tags to parse.     :raises UnsortedTagsError: If **validate_order** is true and any compressed tag         set component is not in sorted order.+    :raises InvalidTag: If the interpreter field is not an identifier; if the+        interpreter, ABI, or platform field (or any member of a compressed tag+        set) is empty; or if the tag does not have exactly three components.+    :raises TooManyTagsError: If **limit** is not ``None`` and the compressed tag+        set would generate more than **limit** tags.+    :raises ValueError: If **limit** is negative. @@ -222,17 +264,48 @@        The *validate_order* parameter.-    """-    tags = set()-    interpreters, abis, platforms = tag.split("-")-    if validate_order:-        for component in (interpreters, abis, platforms):-            parts = component.split(".")-            if parts != sorted(parts):-                raise UnsortedTagsError(-                    f"Tag component {component!r} is not in sorted order per PEP 425"-                )-    for interpreter in interpreters.split("."):-        for abi in abis.split("."):-            for platform_ in platforms.split("."):-                tags.add(Tag(interpreter, abi, platform_))-    return frozenset(tags)++    .. versionadded:: 26.3+       Raises :class:`InvalidTag` when an interpreter component is not an+       identifier, a tag component is empty, or a tag does not have exactly+       three components.+       Added the *limit* parameter. Raises :class:`TooManyTagsError` if the compressed+       tag set would generate more than *limit* tags.+    """++    if limit is not None and limit < 0:+        raise ValueError("limit must be non-negative")++    component_parts = [component.split(".") for component in tag.split("-")]+    for parts in component_parts:+        if "" in parts:+            component = ".".join(parts)+            raise InvalidTag(f"Tag {tag!r} has an empty component: {component!r}")+        if validate_order and parts != sorted(parts):+            component = ".".join(parts)+            raise UnsortedTagsError(+                f"Tag component {component!r} is not in sorted order per PEP 425"+            )++    tag_count = 1+    for parts in component_parts:+        tag_count *= len(parts)++    if limit is not None and tag_count > limit:+        raise TooManyTagsError(+            f"Compressed tag set would generate {tag_count} tags, exceeding "+            f"limit {limit}"+        )++    try:+        interpreters, abis, platforms = component_parts+    except ValueError as exc:+        raise InvalidTag(f"Tag {tag!r} must have exactly three components") from exc+    for interpreter in interpreters:+        if not interpreter.isidentifier():+            raise InvalidTag(f"Tag {tag!r} has an invalid interpreter: {interpreter!r}")+    return frozenset(+        Tag(interpreter, abi, platform_)+        for interpreter in interpreters+        for abi in abis+        for platform_ in platforms+    ) @@ -357,2 +430,4 @@     :param bool warn: Whether warnings should be logged. Defaults to ``False``.++    .. versionadded:: 20.0     """@@ -366,4 +441,6 @@     abis = list(abis)-    # 'abi3' and 'none' are explicitly handled later.-    for explicit_abi in ("abi3", "none"):+    threading = _is_threaded_cpython(abis)+    # Stable ABIs and 'none' are explicitly handled later.+    explicit_abis = ("abi3", "abi3t", "none") if threading else ("abi3", "none")+    for explicit_abi in explicit_abis:         try:@@ -378,6 +455,4 @@ -    threading = _is_threaded_cpython(abis)     use_abi3 = _abi3_applies(python_version, threading)     use_abi3t = _abi3t_applies(python_version, threading)-     if use_abi3:@@ -419,3 +494,3 @@     ext_suffix = _get_config_var("EXT_SUFFIX", warn=True)-    if not isinstance(ext_suffix, str) or ext_suffix[0] != ".":+    if not isinstance(ext_suffix, str) or not ext_suffix.startswith("."):         raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")@@ -428,3 +503,6 @@         # non-windows-        abi = "cp" + soabi.split("-")[1]+        cpython_parts = soabi.split("-")+        if len(cpython_parts) < 2 or not cpython_parts[1]:+            raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")+        abi = "cp" + cpython_parts[1]     elif soabi.startswith("cp"):@@ -471,2 +549,4 @@     :param bool warn: Whether warnings should be logged. Defaults to ``False``.++    .. versionadded:: 20.0     """@@ -500,2 +580,26 @@ +def pure_python_tags(+    python_version: PythonVersion | None = None,+) -> Iterator[Tag]:+    """+    Yields the pure-Python tags compatible with ``python_version``.++    The tags use the ``"none"`` ABI and ``"any"`` platform, so their+    generation does not depend on the running platform.++    .. versionadded:: 26.3++    :param Sequence python_version: A one- or two-item sequence representing the+                                 compatible version of Python. Defaults to+                                 ``sys.version_info[:2]``.+    :raises ValueError: If ``python_version`` is an empty sequence.+    """+    if python_version is None:+        python_version = sys.version_info[:2]+    elif not python_version:+        raise ValueError("python_version must contain at least one item")+    for version in _py_interpreter_range(python_version):+        yield Tag(version, "none", "any")++ def compatible_tags(@@ -522,2 +626,4 @@                                platforms compatible with the current system.++    .. versionadded:: 20.0     """@@ -531,4 +637,3 @@         yield Tag(interpreter, "none", "any")-    for version in _py_interpreter_range(python_version):-        yield Tag(version, "none", "any")+    yield from pure_python_tags(python_version) @@ -550,3 +655,3 @@             return []-        formats.extend(["intel", "fat64", "fat32"])+        formats.extend(["intel", "fat64", "fat3"]) @@ -555,3 +660,3 @@             return []-        formats.extend(["intel", "fat32", "fat"])+        formats.extend(["intel", "fat3", "fat"]) @@ -566,3 +671,3 @@             return []-        formats.extend(["fat32", "fat"])+        formats.extend(["fat3", "fat"]) 
… 104 more lines (truncated)
tests/test_requirements.py +214 lines · 1 flagged
--- +++ @@ -32,2 +32,16 @@     ("scikit-learn==1.0.1", "scikit_learn==1.0.1"),+    # Trailing-zero-equivalent specifiers compare equal, so they must hash+    # equal too (regression guard for the __hash__/__eq__ invariant).+    ("foo==1.0.0", "foo==1.0.0.0"),+    ("foo>=1.0", "foo>=1.0.0"),+    # Canonical-specifier hashing must hold alongside extras + marker.+    (+        'foo[a]==1.0.0; python_version>="3.8"',+        'foo[a]==1.0.0.0; python_version>="3.8"',+    ),+    # Extras that normalize to the same value are equivalent.+    ("urllib3[secure]", "urllib3[SECURE]"),+    ("fishtank[all-blue]", "fishtank[all_blue]"),+    ("fishtank[all-blue]", "fishtank[all---blue]"),+    ("fishtank[crazy-bunches]", "fishtank[cRazy_BUnches]"), ]@@ -167,2 +181,14 @@ +def test_requirement_marker_with_embedded_double_quote_round_trips() -> None:+    req_string = 'demo; \'a" == os_name or python_version >= "0" or "b\' == os_name'+    req = Requirement(req_string)++    assert str(req) == req_string+    assert req.marker is not None+    assert req.marker.evaluate() is False+    round_tripped_marker = Requirement(str(req)).marker+    assert round_tripped_marker is not None+    assert round_tripped_marker.evaluate() is False++ class TestRequirementParsing:@@ -205,2 +231,20 @@ +    @pytest.mark.parametrize("line_break", ["\n", "\r", "\r\n"])+    @pytest.mark.parametrize(+        "requirement",+        [+            "name>=1",+            'name; python_version >= "3"',+        ],+    )+    def test_error_when_suffixed_with_line_break(+        self, requirement: str, line_break: str+    ) -> None:+        with pytest.raises(InvalidRequirement):+            Requirement(requirement + line_break)++    @pytest.mark.parametrize("whitespace", [" ", "\t", " \t"])+    def test_trailing_horizontal_whitespace(self, whitespace: str) -> None:+        assert Requirement("name>=1" + whitespace) == Requirement("name>=1")+     def test_empty_extras(self) -> None:@@ -233,2 +277,10 @@ +    def test_error_when_specifier_set_rejects_parsed_specifier(self) -> None:+        # GIVEN+        to_parse = "demo===x,y"++        # WHEN+        with pytest.raises(InvalidRequirement, match="Invalid specifier: 'y'"):+            Requirement(to_parse)+     def test_error_when_empty_string(self) -> None:@@ -330,2 +382,40 @@ +    @pytest.mark.parametrize("operator", ["==", "!="])+    def test_error_when_prefix_match_uses_post_release(self, operator: str) -> None:+        # GIVEN+        to_parse = f"name {operator} 1.2.3.post4.*"+        op_tilde = len(operator) * "~"++        # WHEN+        with pytest.raises(InvalidRequirement) as ctx:+            Requirement(to_parse)++        # THEN+        assert ctx.exconly() == (+            "packaging.requirements.InvalidRequirement: "+            ".* suffix cannot be used with pre-release, post-release, "+            "dev or local versions\n"+            f"    name {operator} 1.2.3.post4.*\n"+            f"         {op_tilde}~~~~~~~~~~~~~^"+        )++    def test_error_when_prefix_match_uses_post_release_without_spaces(+        self,+    ) -> None:+        # GIVEN+        to_parse = "name==1.2.3.post4.*"++        # WHEN+        with pytest.raises(InvalidRequirement) as ctx:+            Requirement(to_parse)++        # THEN+        assert ctx.exconly() == (+            "packaging.requirements.InvalidRequirement: "+            ".* suffix cannot be used with pre-release, post-release, "+            "dev or local versions\n"+            "    name==1.2.3.post4.*\n"+            "        ~~~~~~~~~~~~~~^"+        )+     @pytest.mark.parametrize("operator", [">=", "<=", ">", "<", "~="])@@ -464,2 +554,30 @@         )++    @pytest.mark.parametrize(+        ("to_parse", "expected"),+        [+            (+                'name; os_name == "C:\\"',+                "packaging.requirements.InvalidRequirement: Invalid quoted string\n"+                '    name; os_name == "C:\\"\n'+                "                     ~~~~~^",+            ),+            (+                r'name; os_name == "\x"',+                "packaging.requirements.InvalidRequirement: Invalid quoted string\n"+                r'    name; os_name == "\x"'+                "\n"+                "                     ~~~~^",+            ),+        ],+    )+    def test_error_invalid_marker_malformed_quoted_string(+        self, to_parse: str, expected: str+    ) -> None:+        # WHEN+        with pytest.raises(InvalidRequirement) as ctx:+            Requirement(to_parse)++        # THEN+        assert ctx.exconly() == expected @@ -711,2 +829,11 @@ +def test_requirement_slots() -> None:+    # Requirement defines __slots__, so instances have no __dict__ and reject+    # unknown attributes.+    r = Requirement("requests>=2.0")+    assert not hasattr(r, "__dict__")+    with pytest.raises(AttributeError):+        r.nonexistent = 1  # type: ignore[attr-defined]++ @pytest.mark.parametrize(@@ -731,2 +858,14 @@ [email protected]("prereleases", [None, True, False])+def test_pickle_requirement_preserves_prereleases(prereleases: bool | None) -> None:+    # The specifier's explicit prereleases override is not captured by the+    # requirement string, so it must be preserved separately across a pickle+    # round trip.  See https://github.com/pypa/packaging/issues/1204.+    r = Requirement("foo>=1.0")+    r.specifier.prereleases = prereleases+    loaded = pickle.loads(pickle.dumps(r))+    assert loaded.specifier._prereleases == prereleases+    assert loaded == r++ def test_pickle_requirement_setstate_rejects_invalid_state() -> None:@@ -740,3 +879,9 @@ -def test_pickle_requirement_setstate_rejects_invalid_string() -> None:[email protected](+    "invalid_requirement",+    ["this is not a valid requirement", "demo===x,y"],+)+def test_pickle_requirement_setstate_rejects_invalid_string(+    invalid_requirement: str,+) -> None:     # Cover the string branch where Requirement() raises InvalidRequirement.@@ -744,3 +889,3 @@     with pytest.raises(TypeError, match="Cannot restore Requirement"):-        r.__setstate__("this is not a valid requirement")+        r.__setstate__(invalid_requirement) @@ -803,2 +948,69 @@ +# Pickle bytes generated with packaging==26.1, Python 3.13.1, pickle protocol 2,+# for ``Requirement("requests>=2.0")`` after setting+# ``r.specifier.prereleases = True``.  Format: plain __dict__ (no __getstate__),+# with the override stored on the nested SpecifierSet.+_PACKAGING_26_1_PICKLE_REQUESTS_GE_2_0_PRERELEASES = (+    b"\x80\x02cpackaging.requirements\nRequirement\nq\x00)\x81q\x01}q\x02("+    b"X\x04\x00\x00\x00nameq\x03X\x08\x00\x00\x00requestsq\x04X\x03\x00\x00\x00"+    b"urlq\x05NX\x06\x00\x00\x00extrasq\x06c__builtin__\nset\nq\x07]q\x08\x85q"+    b"\tRq\nX\t\x00\x00\x00specifierq\x0bcpackaging.specifiers\nSpecifierSet\n"+    b"q\x0c)\x81q\rN}q\x0e(X\x0e\x00\x00\x00_canonicalizedq\x0f\x88X\x0e\x00"+    b"\x00\x00_has_arbitraryq\x10\x89X\x11\x00\x00\x00_is_unsatisfiableq\x11N"+    b"X\x0c\x00\x00\x00_prereleasesq\x12\x88X\r\x00\x00\x00_resolved_opsq\x13N"+    b"X\x06\x00\x00\x00_specsq\x14cpackaging.specifiers\nSpecifier\nq\x15)\x81"+    b"q\x16N}q\x17(h\x12NX\x07\x00\x00\x00_rangesq\x18NX\x05\x00\x00\x00_specq"+    b"\x19X\x02\x00\x00\x00>=q\x1aX\x03\x00\x00\x002.0q\x1b\x86q\x1cX\r\x00\x00"+    b"\x00_spec_versionq\x1dNX\x0f\x00\x00\x00_wildcard_splitq\x1eNu\x86q\x1f"+    b'b\x85q u\x86q!bX\x06\x00\x00\x00markerq"Nub.'+)+++# Pickle bytes generated with packaging==26.2, Python 3.13.1, pickle protocol 2,+# for ``Requirement("requests>=2.0")`` after setting+# ``r.specifier.prereleases = True``.  Format: just the requirement string, so+# the override was already dropped at pickle time (the bug fixed in 26.3).+_PACKAGING_26_2_PICKLE_REQUESTS_GE_2_0_PRERELEASES = (+    b"\x80\x02cpackaging.requirements\nRequirement\nq\x00)\x81q\x01X\r\x00\x00"+    b"\x00requests>=2.0q\x02b."+)+++# Pickle bytes generated with packaging==26.3, Python 3.13.1, pickle protocol 2,+# for ``Requirement("requests>=2.0")`` after setting+# ``r.specifier.prereleases = True``.  Format: (requirement string, prereleases).+_PACKAGING_26_3_PICKLE_REQUESTS_GE_2_0_PRERELEASES = (+    b"\x80\x02cpackaging.requirements\nRequirement\nq\x00)\x81q\x01X\r\x00\x00"+    b"\x00requests>=2.0q\x02\x88\x86q\x03b."+)+++def test_pickle_requirement_old_format_preserves_prereleases() -> None:+    # A specifier prereleases override stored in a packaging <= 26.1 pickle+    # (plain __dict__) is preserved on load.+    r = pickle.loads(_PACKAGING_26_1_PICKLE_REQUESTS_GE_2_0_PRERELEASES)+    assert isinstance(r, Requirement)+    assert r == Requirement("requests>=2.0")+    assert r.specifier.prereleases is True+++def test_pickle_requirement_26_2_format_loads() -> None:+    # A packaging 26.2 pickle uses the string-only format, which never stored+    # the prereleases override (the bug fixed in 26.3).  It must still load,+    # with prereleases defaulting back to None.+    r = pickle.loads(_PACKAGING_26_2_PICKLE_REQUESTS_GE_2_0_PRERELEASES)+    assert isinstance(r, Requirement)+    assert r == Requirement("requests>=2.0")+    assert r.specifier.prereleases is None+++def test_pickle_requirement_new_format_preserves_prereleases() -> None:+    # A specifier prereleases override stored in a packaging 26.3+ pickle+    # ((requirement string, prereleases) tuple) is preserved on load.+    r = pickle.loads(_PACKAGING_26_3_PICKLE_REQUESTS_GE_2_0_PRERELEASES)+    assert isinstance(r, Requirement)+    assert r == Requirement("requests>=2.0")+    assert r.specifier.prereleases is True++
… 1 more lines (truncated)
docs/conf.py +26 lines
--- +++ @@ -90,2 +90,9 @@ +# Rewrite bare ``Path`` in rendered annotations to the stdlib target so+# intersphinx resolves it (annotations are strings under+# ``from __future__ import annotations``).+autodoc_type_aliases = {+    "Path": "pathlib.Path",+}+ # -- Options for extlinks -----------------------------------------------------@@ -105 +112,20 @@ }++# -- Options for nitpicky mode ------------------------------------------------+# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-nitpick_ignore++# Built with ``-n`` so unresolved cross-references fail the build. These+# targets have no documentation page on purpose, so they are allowed to+# stay unresolved: private internal types, and TypeVars / type aliases the+# Python domain cannot resolve as classes.+nitpick_ignore = [+    ("py:class", "packaging.version._BaseVersion"),+    ("py:class", "_Validator"),+    ("py:class", "_MetadataVersion"),+    ("py:class", "_VersionReplace"),+    ("py:class", "T"),+    ("py:class", "_T"),+    ("py:class", "packaging.specifiers.T"),+    ("py:class", "UnparsedVersion"),+    ("py:class", "UnparsedVersionVar"),+]
pyproject.toml +7 lines
--- +++ @@ -11,3 +11,3 @@ readme = "README.rst"-requires-python = ">=3.8"+requires-python = ">=3.9" authors = [{name = "Donald Stufft", email = "[email protected]"}]@@ -19,3 +19,2 @@   "Programming Language :: Python :: 3 :: Only",-  "Programming Language :: Python :: 3.8",   "Programming Language :: Python :: 3.9",@@ -26,2 +25,3 @@   "Programming Language :: Python :: 3.14",+  "Programming Language :: Python :: 3.15",   "Programming Language :: Python :: Implementation :: CPython",@@ -50,3 +50,2 @@   "furo",-  "typing-extensions>=4.1.0; python_version < '3.9'", ]@@ -113,7 +112,8 @@ warn_unused_ignores = true-python_version = "3.8"+python_version = "3.9" files = ["src", "tests", "noxfile.py"]+native_parser = true  [[tool.mypy.overrides]]-module = ["_manylinux", "pretend", "progress.*", "pkg_resources"]+module = ["_manylinux", "pretend"] ignore_missing_imports = true@@ -132,2 +132,3 @@     "COM812",  # trailing commas teach the formatter+    "CPY001",  # no copyright messages in files (for now)     "D",       # doc formatting@@ -137,2 +138,3 @@     "FIX",     # has todos+    "ISC004",  # unparenthesized implicit string concatenation in collection     "N818",    # exceptions must end in "*Error"@@ -161,3 +163,2 @@ "tasks/*.py" = ["T20"]-"tasks/check.py" = ["UP032"] "tasks/check_frozen_revs.py" = ["ANN401"]
src/packaging/__init__.py +1 lines
--- +++ @@ -8,3 +8,3 @@ -__version__ = "26.2"+__version__ = "26.3" 
src/packaging/_elffile.py +5 lines
--- +++ @@ -36,3 +36,3 @@     X8664 = 62-    AArc64 = 183+    AArch64 = 183 @@ -59,4 +59,4 @@         try:-            # e_fmt: Format for program header.-            # p_fmt: Format for section header.+            # e_fmt: Format for the ELF header.+            # p_fmt: Format for a program header.             # p_idx: Indexes to find p_type, p_offset, and p_filesz.@@ -83,4 +83,4 @@                 _,-                self._e_phentsize,  # Size of section.-                self._e_phnum,  # Number of sections.+                self._e_phentsize,  # Size of a program header entry.+                self._e_phnum,  # Number of program headers.             ) = self._read(e_fmt)
src/packaging/_musllinux.py +5 lines
--- +++ @@ -12,5 +12,8 @@ import sys-from typing import Iterator, NamedTuple, Sequence+from typing import TYPE_CHECKING, NamedTuple  from ._elffile import ELFFile++if TYPE_CHECKING:+    from collections.abc import Iterator, Sequence @@ -83,3 +86,3 @@     print("tags:", end=" ")-    for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):+    for t in platform_tags([re.sub(r"[.-]", "_", plat.split("-", 1)[-1])]):         print(t, end="\n      ")
src/packaging/_parser.py +34 lines
--- +++ @@ -9,5 +9,6 @@ import ast-from typing import List, Literal, NamedTuple, Sequence, Tuple, Union--from ._tokenizer import DEFAULT_RULES, Tokenizer+from collections.abc import Sequence+from typing import Literal, NamedTuple, Union++from ._tokenizer import DEFAULT_RULES, ParserSyntaxError, Tokenizer @@ -69,3 +70,10 @@     def serialize(self) -> str:-        return f'"{self}"'+        value = str(self)+        if '"' not in value:+            return f'"{value}"'+        if "'" not in value:+            return f"'{value}'"+        raise ValueError(+            "Cannot serialize marker value containing both quote characters"+        ) @@ -81,5 +89,5 @@ MarkerVar = Union[Variable, Value]-MarkerItem = Tuple[MarkerVar, Op, MarkerVar]+MarkerItem = tuple[MarkerVar, Op, MarkerVar] MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]]-MarkerList = List[Union["MarkerList", MarkerAtom, MarkerLogical]]+MarkerList = list[Union["MarkerList", MarkerAtom, MarkerLogical]] @@ -266,6 +274,15 @@         span_start = tokenizer.position-        parsed_specifiers += tokenizer.read().text+        specifier = tokenizer.read().text+        parsed_specifiers += specifier         if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):+            message = ".* suffix can only be used with `==` or `!=` operators"+            if specifier.startswith("!=") or (+                specifier.startswith("==") and not specifier.startswith("===")+            ):+                message = (+                    ".* suffix cannot be used with pre-release, post-release, "+                    "dev or local versions"+                )             tokenizer.raise_syntax_error(-                ".* suffix can only be used with `==` or `!=` operators",+                message,                 span_start=span_start,@@ -356,3 +373,11 @@     elif tokenizer.check("QUOTED_STRING"):-        return process_python_str(tokenizer.read().text)+        token = tokenizer.read()+        try:+            return process_python_str(token.text)+        except (SyntaxError, ValueError) as exc:+            raise ParserSyntaxError(+                "Invalid quoted string",+                source=tokenizer.source,+                span=(token.position, token.position + len(token.text)),+            ) from exc     else:
src/packaging/_ranges.py +836 lines
--- +++ @@ -0,0 +1,836 @@+# This file is dual licensed under the terms of the Apache License, Version+# 2.0, and the BSD License. See the LICENSE file in the root of this repository+# for complete details.+"""Private version-range helpers used by :mod:`packaging.specifiers`."""++from __future__ import annotations++import enum+import functools+from typing import (+    TYPE_CHECKING,+    Any,+    Final,+)++from .version import InvalidVersion, Version++if TYPE_CHECKING:+    from collections.abc import Callable, Iterable, Iterator, Sequence+    from typing import Union++    # Total-order key for comparing two boundaries (boundary-vs-boundary only).+    # The post slot may be ``_BOUNDARY_INF`` for an AFTER_POSTS boundary.+    _BoundaryOrderSuffix = tuple[int, int, int, Union[int, float], int, int]+    _BoundaryOrderKey = tuple[int, tuple[int, ...], _BoundaryOrderSuffix, float]++__all__ = [+    "FULL_RANGE",+    "bounds_for_spec",+    "coerce_version",+    "filter_by_ranges",+    "intersect_ranges",+    "intersect_specifier_bounds",+    "least_version_above",+    "matches_bounds_only",+    "range_is_empty",+    "ranges_are_prerelease_only",+    "resolve_prereleases",+    "standard_ranges",+    "wildcard_ranges",+]++#: The smallest possible PEP 440 version. No valid version is less than this.+MIN_VERSION: Final[Version] = Version("0.dev0")++#: The smallest non-pre-release version, i.e. the nearest non-pre-release at or+#: above the ``-inf`` floor.+MIN_RELEASE: Final[Version] = Version("0")++#: Sorts above any real post number and any local label, so a boundary can be+#: ordered above the version family it covers when two boundaries are compared.+_BOUNDARY_INF: Final[float] = float("inf")+++class BoundaryKind(enum.Enum):+    """Where a boundary marker sits in the version ordering."""++    AFTER_LOCALS = enum.auto()  # after V+local, before V.post0+    AFTER_POSTS = enum.auto()  # after V.postN, before next release++[email protected]_ordering+class BoundaryVersion:+    """A point on the version line between two real PEP 440 versions.++    Relative to a base version V::++        V < V+local < AFTER_LOCALS(V) < V.post0 < AFTER_POSTS(V)++    AFTER_LOCALS is the upper bound of ``<=V``, ``==V``, ``!=V`` (no+    local), and the lower bound of the upper-side range of ``!=V``.+    AFTER_POSTS is the lower bound of ``>V`` (V final or pre-release),+    excluding V's post-releases per PEP 440.+    """++    __slots__ = (+        "_cached_dev",+        "_cached_epoch",+        "_cached_post",+        "_cached_pre",+        "_cached_trimmed_release",+        "kind",+        "version",+    )++    def __init__(self, version: Version, kind: BoundaryKind) -> None:+        self.version = version+        self.kind = kind+        self._cached_trimmed_release = trim_release(version.release)+        self._cached_epoch = version.epoch+        self._cached_pre = version.pre+        self._cached_post = version.post+        self._cached_dev = version.dev++    def _is_family(self, other: Version) -> bool:+        """Is ``other`` a version that this boundary sorts above?"""+        if other.epoch != self._cached_epoch:+            return False+        # Inline release-trim comparison: other.release matches the+        # trimmed release iff its leading slice is equal and any extra+        # components are zero. Avoids trim_release's tuple allocation.+        other_release = other.release+        trimmed_release = self._cached_trimmed_release+        trimmed_length = len(trimmed_release)+        if len(other_release) < trimmed_length:+            return False+        if other_release[:trimmed_length] != trimmed_release:+            return False+        for i in range(trimmed_length, len(other_release)):+            if other_release[i] != 0:+                return False+        if other.pre != self._cached_pre:+            return False+        if self.kind == BoundaryKind.AFTER_LOCALS:+            # Local family: same public version, any local label.+            return other.post == self._cached_post and other.dev == self._cached_dev+        # Post family: V itself + any post-release of V.+        return other.dev == self._cached_dev or other.post is not None++    def _order_key(self) -> _BoundaryOrderKey:+        """Sort key placing this boundary just above the versions it covers.++        It extends ``V``'s comparison key ``(epoch, release, suffix)`` with+        a trailing ``_BOUNDARY_INF`` local component, so the key sorts after+        ``V`` and every ``V+local`` (whose keys carry a real, finite local+        segment). ``suffix`` is the 6-int comparison suffix+        ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``.++        For an AFTER_POSTS boundary the suffix is replaced with one whose+        post number is ``_BOUNDARY_INF``, so the key also sorts after every+        ``V.postN``. An AFTER_LOCALS boundary uses ``V``'s suffix unchanged.+        """+        version_key = self.version._key+        suffix: _BoundaryOrderSuffix = version_key[2]++        if self.kind == BoundaryKind.AFTER_POSTS:+            suffix = (suffix[0], suffix[1], 1, _BOUNDARY_INF, 1, 0)++        return version_key[0], version_key[1], suffix, _BOUNDARY_INF++    def __eq__(self, other: object) -> bool:+        # Key off the order key so equality matches the ``<`` / ``>`` order:+        # ``AFTER_POSTS(1.0)`` and ``AFTER_POSTS(1.0.post1)`` are the same point.+        if isinstance(other, BoundaryVersion):+            return self._order_key() == other._order_key()+        return NotImplemented++    def __lt__(self, other: BoundaryVersion | Version) -> bool:+        if isinstance(other, BoundaryVersion):+            return self._order_key() < other._order_key()+        # boundary < other_version iff V < other AND other not in family.+        # The cheap V >= other path short-circuits before the family check.+        if not (self.version < other):+            return False+        return not self._is_family(other)++    def __gt__(self, other: BoundaryVersion | Version) -> bool:+        # Defined directly to bypass functools.total_ordering's+        # NotImplemented round-trip on reflected ``Version < boundary``.+        if isinstance(other, BoundaryVersion):+            return self._order_key() > other._order_key()+        if self.version >= other:+            return True+        return self._is_family(other)++    def __hash__(self) -> int:+        # Keyed to ``__eq__`` (the order key), so equal boundaries hash equal.+        return hash(self._order_key())++    def __repr__(self) -> str:+        return f"{self.__class__.__name__}({self.version!r}, {self.kind.name})"+++if TYPE_CHECKING:+    _VersionOrBoundary = Union[Version, BoundaryVersion, None]++[email protected]_ordering+class LowerBound:+    """Lower bound of a version range.++    A version *v* of ``None`` means unbounded below (-inf).+    At equal versions, ``[v`` sorts before ``(v`` because an inclusive+    bound starts earlier.+    """++    __slots__ = ("_above", "inclusive", "version")++    def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None:+        self.version = version+        self.inclusive = inclusive+        # Pre-bind a predicate "is parsed at or above this lower+        # bound?" for the hot filter / contains loops. One direct+        # call per check, no operator-dispatch chain.+        if version is None:+            self._above: Callable[[Version], bool] | None = None+        elif isinstance(version, BoundaryVersion):+            # >V produces an AFTER_POSTS lower bound; the upper-side+            # range of !=V produces an AFTER_LOCALS lower bound.+            if version.kind == BoundaryKind.AFTER_POSTS:+                self._above = _make_above_after_posts(version.version)+            else:+                self._above = _make_above_after_locals(version.version)+        elif inclusive:+            self._above = version.__le__+        else:+            self._above = version.__lt__++    def __eq__(self, other: object) -> bool:+        if not isinstance(other, LowerBound):+            return NotImplemented+        return self.version == other.version and self.inclusive == other.inclusive++    def __lt__(self, other: LowerBound) -> bool:+        if not isinstance(other, LowerBound):+            return NotImplemented+        # -inf < anything (except -inf itself).+        if self.version is None:+            return other.version is not None+        if other.version is None:+            return False+        if self.version != other.version:+            return self.version < other.version+        # [v < (v: inclusive starts earlier.+        return self.inclusive and not other.inclusive++    def __hash__(self) -> int:+        return hash((self.version, self.inclusive))++    def __repr__(self) -> str:+        bracket = "[" if self.inclusive else "("+        return f"<{self.__class__.__name__} {bracket}{self.version!r}>"++[email protected]_ordering+class UpperBound:+    """Upper bound of a version range.++    A version *v* of ``None`` means unbounded above (+inf).+    At equal versions, ``v)`` sorts before ``v]`` because an exclusive+    bound ends earlier.+    """++    __slots__ = ("_below", "inclusive", "version")++    def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None:+        self.version = version
… 589 more lines (truncated)
src/packaging/_tokenizer.py +10 lines
--- +++ @@ -5,5 +5,8 @@ from dataclasses import dataclass-from typing import Generator, Mapping, NoReturn+from typing import TYPE_CHECKING, NoReturn  from .specifiers import Specifier++if TYPE_CHECKING:+    from collections.abc import Generator, Mapping @@ -12,2 +15,4 @@ class Token:+    __slots__ = ("name", "position", "text")+     name: str@@ -86,3 +91,3 @@     "WS": re.compile(r"[ \t]+"),-    "END": re.compile(r"$"),+    "END": re.compile(r"\Z"), }@@ -96,2 +101,4 @@     """++    __slots__ = ("next_token", "position", "rules", "source") @@ -137,3 +144,3 @@ -        The token is *not* read.+        The token is read and returned.         """
src/packaging/dependency_groups.py +38 lines
--- +++ @@ -6,3 +6,3 @@ from .errors import _ErrorCollector-from .requirements import Requirement+from .requirements import InvalidRequirement, Requirement @@ -30,2 +30,4 @@     The same dependency groups were defined twice, with different non-normalized names.++    .. versionadded:: 26.1     """@@ -36,2 +38,4 @@     The dependency group includes form a cycle.++    .. versionadded:: 26.1     """@@ -52,2 +56,6 @@ +    # Support pickling; ``args`` does not match ``__init__``'s signature.+    def __reduce__(self) -> tuple[type[CyclicDependencyGroup], tuple[str, str, str]]:+        return (self.__class__, (self.requested_group, self.group, self.include_group))+ @@ -60,2 +68,4 @@     format.++    .. versionadded:: 26.1     """@@ -69,2 +79,8 @@ class DependencyGroupInclude:+    """+    A reference to another dependency group by name.++    .. versionadded:: 26.1+    """+     __slots__ = ("include_group",)@@ -93,2 +109,4 @@         ``[dependency-groups]``.++    .. versionadded:: 26.1     """@@ -229,5 +247,6 @@                 # packaging.requirements.Requirement parsing ensures that this is a-                # valid PEP 508 Dependency Specifier-                # raises InvalidRequirement on failure-                elements.append(Requirement(item))+                # valid PEP 508 Dependency Specifier. Collect InvalidRequirement+                # if it throws that.+                with errors.collect(InvalidRequirement):+                    elements.append(Requirement(item))             elif isinstance(item, Mapping):@@ -241,5 +260,17 @@                     include_group = item["include-group"]-                    elements.append(DependencyGroupInclude(include_group=include_group))+                    if not isinstance(include_group, str):+                        msg = (+                            "Dependency group include-group value is not a string: "+                            f"{item!r}"+                        )+                        errors.error(TypeError(msg))+                    else:+                        elements.append(+                            DependencyGroupInclude(include_group=include_group)+                        )             else:                 errors.error(TypeError(f"Invalid dependency group item: {item!r}"))++        if errors.errors:+            return () @@ -263,2 +294,4 @@     :param groups: the name of the group(s) to resolve++    .. versionadded:: 26.1     """
src/packaging/licenses/__init__.py +18 lines
--- +++ @@ -50,3 +50,3 @@ -license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$")+license_ref_allowed = re.compile("^[A-Za-z0-9.-]+$") @@ -66,3 +66,3 @@         ...-    packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid'+    packaging.licenses.InvalidLicenseExpression: Unknown license: 'invalid'     """@@ -150,5 +150,14 @@     normalized_tokens = []-    for token in tokens:+    last_license_start = False+    for index, token in enumerate(tokens):         if token in {"or", "and", "with", "(", ")"}:+            if token == "with" and (+                not last_license_start+                or index + 1 == len(tokens)+                or tokens[index + 1] in {"or", "and", "with", "(", ")"}+            ):+                message = f"Invalid license expression: {raw_license_expression!r}"+                raise InvalidLicenseExpression(message)             normalized_tokens.append(token.upper())+            last_license_start = False             continue@@ -161,2 +170,3 @@             normalized_tokens.append(EXCEPTIONS[token]["id"])+            last_license_start = False         else:@@ -170,6 +180,7 @@             if final_token.startswith("licenseref-"):-                if not license_ref_allowed.match(final_token):-                    message = f"Invalid licenseref: {final_token!r}"+                license_ref_id = final_token[len("licenseref-") :]+                if suffix or not license_ref_allowed.match(license_ref_id):+                    message = f"Invalid licenseref: {token!r}"                     raise InvalidLicenseExpression(message)-                normalized_tokens.append(license_refs[final_token] + suffix)+                normalized_tokens.append(license_refs[final_token])             else:@@ -179,2 +190,3 @@                 normalized_tokens.append(LICENSES[final_token]["id"] + suffix)+            last_license_start = True 
src/packaging/markers.py +108 lines
--- +++ @@ -6,2 +6,3 @@ +import functools import operator@@ -10,3 +11,4 @@ import sys-from typing import AbstractSet, Callable, Literal, Mapping, TypedDict, Union, cast+from collections.abc import Set as AbstractSet+from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, cast @@ -17,2 +19,5 @@ from .utils import canonicalize_name++if TYPE_CHECKING:+    from collections.abc import Mapping @@ -42,2 +47,4 @@ * ``"requirement"`` (i.e. all other situations)++.. versionadded:: 25.0 """@@ -70,4 +77,13 @@ -class UndefinedEnvironmentName(ValueError):-    """Raised when evaluating a marker that references a missing environment key."""+class UndefinedEnvironmentName(KeyError):+    """Raised when evaluating a marker that references a missing environment key.++    Subclasses :class:`KeyError` so that code catching the bare ``KeyError`` that+    a missing environment lookup historically produced keeps working.++    .. versionchanged:: 26.3+        Now subclasses :class:`KeyError` (was :class:`ValueError`) and is raised by+        :meth:`Marker.evaluate` for missing environment keys, where a bare+        ``KeyError`` was raised before.+    """ @@ -154,2 +170,4 @@ ) -> MarkerList | MarkerAtom | str:+    if isinstance(result, list):+        return [_normalize_extras(r) for r in result]     if not isinstance(result, tuple):@@ -158,8 +176,20 @@     lhs, op, rhs = result-    if isinstance(lhs, Variable) and lhs.value == "extra":+    if isinstance(lhs, Variable) and lhs.value == "extra" and isinstance(rhs, Value):         normalized_extra = canonicalize_name(rhs.value)         rhs = Value(normalized_extra)-    elif isinstance(rhs, Variable) and rhs.value == "extra":+    elif isinstance(rhs, Variable) and rhs.value == "extra" and isinstance(lhs, Value):         normalized_extra = canonicalize_name(lhs.value)         lhs = Value(normalized_extra)+    elif (+        isinstance(rhs, Variable)+        and rhs.value in MARKERS_ALLOWING_SET+        and isinstance(lhs, Value)+    ):+        # PEP 685 (extras) / PEP 735 (dependency_groups): the set-valued membership+        # literal must also be normalized. evaluate() already canonicalizes both+        # operands for these keys (see _normalize), so normalizing the literal at+        # parse time keeps __str__/__eq__/__hash__ consistent with evaluate() -- e.g.+        # Marker('"Foo" in extras') and Marker('"foo" in extras') must compare and+        # hash equal (the membership variable is always the right-hand operand).+        lhs = Value(canonicalize_name(lhs.value))     return lhs, op, rhs@@ -180,6 +210,4 @@ -    # Sometimes we have a structure like [[...]] which is a single item list-    # where the single item is itself it's own list. In that case we want skip-    # the rest of this function so that we don't get extraneous () on the-    # outside.+    # Unwrap a redundant [[...]] wrapper, but keep the nesting context so a+    # nested group keeps the parentheses its and/or precedence needs.     if (@@ -189,3 +217,3 @@     ):-        return _format_marker(marker[0])+        return _format_marker(marker[0], first=first) @@ -253,2 +281,11 @@ +def _lookup_environment(+    environment: dict[str, str | AbstractSet[str]], key: str+) -> str | AbstractSet[str]:+    try:+        return environment[key]+    except KeyError:+        raise UndefinedEnvironmentName(key) from None++ def _evaluate_markers(@@ -266,3 +303,3 @@                 environment_key = lhs.value-                lhs_value = environment[environment_key]+                lhs_value = _lookup_environment(environment, environment_key)                 rhs_value = rhs.value@@ -271,5 +308,11 @@                 environment_key = rhs.value-                rhs_value = environment[environment_key]--            assert isinstance(lhs_value, str), "lhs must be a string"+                rhs_value = _lookup_environment(environment, environment_key)++            if not isinstance(lhs_value, str):+                raise UndefinedComparison(+                    f"Set-valued marker {environment_key!r} can only be used "+                    f'with the membership form (e.g. "<name>" in '+                    f"{environment_key}); it cannot appear on the left-hand "+                    f"side of {op.serialize()!r}."+                )             lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key)@@ -294,6 +337,10 @@ -def default_environment() -> Environment:-    """Return the default marker environment for the current Python process.--    This is the base environment used by :meth:`Marker.evaluate`.[email protected]+def _cached_default_environment() -> Environment:+    """Build the default marker environment for the current Python process.++    The values are derived from process-constant data (the running interpreter+    and the host platform), so this is cached and built only once. The result is+    shared between callers and must never be mutated; :func:`default_environment`+    returns a fresh copy.     """@@ -314,2 +361,18 @@     }+++def default_environment() -> Environment:+    """Return the default marker environment for the current Python process.++    This is the base environment used by :meth:`Marker.evaluate`. A fresh copy+    is returned on every call so callers may freely mutate the result; a shallow+    copy suffices because all values are immutable strings.++    .. versionchanged:: 26.3+        The environment is computed once per process and cached, since it is+        derived from process-constant data. Patching ``platform``/``sys``/``os``+        after the first call has no effect; pass an explicit ``environment`` to+        :meth:`Marker.evaluate` to evaluate against different values.+    """+    return cast("Environment", dict(_cached_default_environment())) @@ -423,2 +486,6 @@     def __and__(self, other: Marker) -> Marker:+        """Combine this marker with another using ``and``.++        .. versionadded:: 26.1+        """         if not isinstance(other, Marker):@@ -428,2 +495,6 @@     def __or__(self, other: Marker) -> Marker:+        """Combine this marker with another using ``or``.++        .. versionadded:: 26.1+        """         if not isinstance(other, Marker):@@ -456,2 +527,5 @@ +        .. versionchanged:: 25.0+            Added the ``context`` parameter, which influences which marker names+            are considered valid.         """@@ -461,5 +535,6 @@         if context == "lock_file":-            current_environment.update(-                extras=frozenset(), dependency_groups=frozenset()-            )+            current_environment |= {+                "extras": frozenset(),+                "dependency_groups": frozenset(),+            }         elif context == "metadata":@@ -468,3 +543,3 @@         if environment is not None:-            current_environment.update(environment)+            current_environment |= environment             if "extra" in current_environment:@@ -481,2 +556,12 @@ +def _pep440_python_full_version(python_full_version: str) -> str:+    """+    Work around platform.python_version() returning something that is not PEP 440+    compliant for non-tagged Python builds.+    """+    if python_full_version.endswith("+"):+        return f"{python_full_version}local"+    return python_full_version++ def _repair_python_full_version(@@ -489,4 +574,3 @@     python_full_version = cast("str", env["python_full_version"])-    if python_full_version.endswith("+"):-        env["python_full_version"] = f"{python_full_version}local"+    env["python_full_version"] = _pep440_python_full_version(python_full_version)     return env
src/packaging/metadata.py +146 lines
--- +++ @@ -8,2 +8,3 @@ import pathlib+import re import typing@@ -24,2 +25,3 @@     from .licenses import NormalizedLicenseExpression+    from .version import Version @@ -44,3 +46,6 @@ class InvalidMetadata(ValueError):-    """A metadata field contains invalid data."""+    """A metadata field contains invalid data.++    .. versionadded:: 23.2+    """ @@ -52,2 +57,6 @@         super().__init__(message)++    # Support pickling; ``args`` does not match ``__init__``'s signature.+    def __reduce__(self) -> tuple[type[InvalidMetadata], tuple[str, str]]:+        return (self.__class__, (self.field, self.args[0])) @@ -127,3 +136,5 @@     license_expression: str+    """.. versionadded:: 24.2"""     license_files: list[str]+    """.. versionadded:: 24.2""" @@ -131,3 +142,7 @@     import_names: list[str]+    """.. versionadded:: 26.0"""     import_namespaces: list[str]+    """.. versionadded:: 26.0"""++    # Metadata 2.6 - PEP 808 (no new fields, behavior change for Dynamic) @@ -227,3 +242,6 @@         payload = msg.get_payload()-        assert isinstance(payload, str)+        # A multipart payload makes get_payload() return a list of messages+        # rather than a str; route it to ``unparsed``.+        if not isinstance(payload, str):+            raise ValueError("payload is not a string")  # noqa: TRY004         return payload@@ -233,3 +251,6 @@         bpayload = msg.get_payload(decode=True)-        assert isinstance(bpayload, bytes)+        # A multipart payload makes get_payload(decode=True) return None;+        # route it to ``unparsed``.+        if not isinstance(bpayload, bytes):+            raise ValueError("payload in an invalid encoding")  # noqa: TRY004         try:@@ -289,2 +310,8 @@ +# A bare "\r" makes the email generator raise ``HeaderWriteError``, and on+# CPython releases without the CVE-2024-6923 fix any ``str.splitlines``+# boundary ends the header line, so fold all of them, not just "\n".+_LINE_BOUNDARY_RE = re.compile(r"\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]")++ # This class is for writing RFC822 messages@@ -294,2 +321,4 @@     implementation that handles multi-line values, and some nice defaults.++    .. versionadded:: 26.0     """@@ -302,3 +331,3 @@         size = len(name) + 2-        value = value.replace("\n", "\n" + " " * size)+        value = _LINE_BOUNDARY_RE.sub("\n" + " " * size, value)         return (name, value)@@ -312,2 +341,4 @@     with `bytes()`.++    .. versionadded:: 26.0     """@@ -513,4 +544,16 @@ # Keep the two values in sync.-_VALID_METADATA_VERSIONS = ["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5"]-_MetadataVersion = Literal["1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5"]+_VALID_METADATA_VERSIONS = [+    "1.0",+    "1.1",+    "1.2",+    "2.1",+    "2.2",+    "2.3",+    "2.4",+    "2.5",+    "2.6",+]+_MetadataVersion = Literal[+    "1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6"+] @@ -574,5 +617,3 @@     ) -> InvalidMetadata:-        exc = InvalidMetadata(-            self.raw_name, msg.format_map({"field": repr(self.raw_name)})-        )+        exc = InvalidMetadata(self.raw_name, msg)         exc.__cause__ = cause@@ -588,3 +629,3 @@         if not value:-            raise self._invalid_metadata("{field} is a required field")+            raise self._invalid_metadata(f"{self.raw_name!r} is a required field")         # Validate the name as a side-effect.@@ -594,3 +635,3 @@             raise self._invalid_metadata(-                f"{value!r} is invalid for {{field}}", cause=exc+                f"{value!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -599,5 +640,5 @@ -    def _process_version(self, value: str) -> version_module.Version:+    def _process_version(self, value: str) -> Version:         if not value:-            raise self._invalid_metadata("{field} is a required field")+            raise self._invalid_metadata(f"{self.raw_name!r} is a required field")         try:@@ -606,3 +647,3 @@             raise self._invalid_metadata(-                f"{value!r} is invalid for {{field}}", cause=exc+                f"{value!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -610,5 +651,5 @@     def _process_summary(self, value: str) -> str:-        """Check the field contains no newlines."""-        if "\n" in value:-            raise self._invalid_metadata("{field} must be a single line")+        """Check the field contains no line breaks."""+        if _LINE_BOUNDARY_RE.search(value):+            raise self._invalid_metadata(f"{self.raw_name!r} must be a single line")         return value@@ -617,4 +658,20 @@         content_types = {"text/plain", "text/x-rst", "text/markdown"}+        invalid_msg = (+            f"{self.raw_name!r} must be one of {list(content_types)}, not {value!r}"+        )         message = email.message.EmailMessage()-        message["content-type"] = value+        try:+            message["content-type"] = value+        # The email parser can raise IndexError on malformed RFC 2231+        # parameters such as "text/plain; x*".+        except (ValueError, IndexError) as exc:+            msg = f"{value!r} is not a valid content type for {self.raw_name!r}"+            raise self._invalid_metadata(msg, cause=exc) from exc+        content_type_header = message["content-type"]+        if content_type_header.defects:+            defect = content_type_header.defects[0]+            msg = (+                f"{value!r} is not a valid content type for {self.raw_name!r}: {defect}"+            )+            raise self._invalid_metadata(msg, cause=defect) from defect @@ -623,3 +680,3 @@             message.get_content_type().lower(),-            message["content-type"].params,+            content_type_header.params,         )@@ -628,10 +685,8 @@         if content_type not in content_types or content_type not in value.lower():+            raise self._invalid_metadata(invalid_msg)++        charset = parameters.get("charset", "UTF-8")+        if charset.lower() != "utf-8":             raise self._invalid_metadata(-                f"{{field}} must be one of {list(content_types)}, not {value!r}"-            )--        charset = parameters.get("charset", "UTF-8")-        if charset != "UTF-8":-            raise self._invalid_metadata(-                f"{{field}} can only specify the UTF-8 charset, not {charset!r}"+                f"{self.raw_name!r} can only specify the UTF-8 charset, not {charset!r}"             )@@ -642,4 +697,4 @@             raise self._invalid_metadata(-                f"valid Markdown variants for {{field}} are {list(markdown_variants)}, "-                f"not {variant!r}",+                f"valid Markdown variants for {self.raw_name!r} are "+                f"{list(markdown_variants)}, not {variant!r}",             )@@ -648,3 +703,4 @@     def _process_dynamic(self, value: list[str]) -> list[str]:-        for dynamic_field in map(str.lower, value):+        dynamic_fields = list(map(str.lower, value))+        for dynamic_field in dynamic_fields:             if dynamic_field in {"name", "version", "metadata-version"}:@@ -657,3 +713,3 @@                 )-        return list(map(str.lower, value))+        return dynamic_fields @@ -669,3 +725,3 @@             raise self._invalid_metadata(-                f"{name!r} is invalid for {{field}}", cause=exc+                f"{name!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -679,3 +735,3 @@             raise self._invalid_metadata(-                f"{value!r} is invalid for {{field}}", cause=exc+                f"{value!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -692,3 +748,3 @@             raise self._invalid_metadata(-                f"{req!r} is invalid for {{field}}", cause=exc+                f"{req!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -702,3 +758,3 @@             raise self._invalid_metadata(-                f"{value!r} is invalid for {{field}}", cause=exc+                f"{value!r} is invalid for {self.raw_name!r}", cause=exc             ) from exc@@ -710,3 +766,3 @@                 raise self._invalid_metadata(-                    f"{path!r} is invalid for {{field}}, "+                    f"{path!r} is invalid for {self.raw_name!r}, "                     "parent directory indicators are not allowed"@@ -715,3 +771,3 @@                 raise self._invalid_metadata(-                    f"{path!r} is invalid for {{field}}, paths must be resolved"+                    f"{path!r} is invalid for {self.raw_name!r}, paths must be resolved"                 )@@ -722,3 +778,3 @@                 raise self._invalid_metadata(-                    f"{path!r} is invalid for {{field}}, paths must be relative"+                    f"{path!r} is invalid for {self.raw_name!r}, paths must be relative"                 )@@ -726,3 +782,4 @@                 raise self._invalid_metadata(-                    f"{path!r} is invalid for {{field}}, paths must use '/' delimiter"+                    f"{path!r} is invalid for {self.raw_name!r}, "+                    "paths must use '/' delimiter"                 )@@ -738,3 +795,3 @@                     raise self._invalid_metadata(-                        f"{name!r} is invalid for {{field}}; "+                        f"{name!r} is invalid for {self.raw_name!r}; "                         f"{identifier!r} is not a valid identifier"@@ -743,3 +800,3 @@                     raise self._invalid_metadata(-                        f"{name!r} is invalid for {{field}}; "+                        f"{name!r} is invalid for {self.raw_name!r}; "                         f"{identifier!r} is a keyword"@@ -748,3 +805,3 @@
… 93 more lines (truncated)
src/packaging/ranges.py +2067 lines
--- +++ @@ -0,0 +1,2067 @@+# This file is dual licensed under the terms of the Apache License, Version+# 2.0, and the BSD License. See the LICENSE file in the root of this repository+# for complete details.+"""Public :class:`VersionRange` API.++A set-algebra view of the versions accepted by a+:class:`~packaging.specifiers.SpecifierSet`. Ranges support intersection,+union, complement, and difference; membership and filtering match the+originating specifier set; and conversion back to a+:class:`~packaging.specifiers.SpecifierSet` is available where a PEP 440 form+exists.++.. testsetup::++    from packaging.ranges import VersionRange+    from packaging.specifiers import SpecifierSet+    from packaging.version import Version+"""++from __future__ import annotations++import enum+import typing+from typing import (+    TYPE_CHECKING,+    Any,+    TypeVar,+    Union,+)++from ._ranges import (+    FULL_RANGE,+    MIN_VERSION,+    NEG_INF,+    POS_INF,+    BoundaryKind,+    BoundaryVersion,+    LowerBound,+    UpperBound,+    coerce_version,+    filter_by_ranges,+    intersect_ranges,+    least_version_above,+    matches_bounds_only,+    range_is_empty,+    ranges_are_prerelease_only,+    trim_release,+)+from .version import Version++if TYPE_CHECKING:+    from collections.abc import Callable, Iterable, Iterator, Sequence++    from ._ranges import Interval+    from .specifiers import SpecifierSet+++__all__ = ["VersionRange"]++T = TypeVar("T")+UnparsedVersion = Union[Version, str]+UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion)++#: The most ``!=`` exclusion fragments (``!=V`` points or ``!=P.*`` prefixes)+#: that :meth:`VersionRange.to_specifier_set` will materialize to spell a+#: single gap or run. Every site that expands a version-number-driven chain+#: charges it against this cap, and chains that spell one gap together share+#: it (see :func:`_decompose_dev0_gap` and :func:`_encode_gap`),+#: so no gap ever materializes more than this many exclusions. Past the cap+#: the recovery returns ``None`` rather than emit the unbounded chain a range+#: such as ``==5.* | ==1000000.*`` would otherwise drive.+_MAX_EXCLUSION_RUN = 128+++class _SetOp(enum.Enum):+    """The binary set operation ``_combine_literals`` resolves over ``===`` literals."""++    INTERSECTION = enum.auto()+    UNION = enum.auto()+    DIFFERENCE = enum.auto()+++def __dir__() -> list[str]:+    return __all__+++# Range algebra: intersection and the empty-interval test live in the engine+# (``intersect_ranges`` / ``range_is_empty``); union and complement are only+# needed here, so they live in this module.+++def _union_ranges(+    left: Sequence[Interval],+    right: Sequence[Interval],+) -> list[Interval]:+    """Union two sorted, non-overlapping interval lists.++    A linear merge over the two pre-sorted inputs followed by a single+    coalescing pass: adjacent or overlapping intervals collapse so the result+    is itself sorted and non-overlapping.+    """+    if not left:+        return list(right)+    if not right:+        return list(left)++    merged_input: list[Interval] = []+    left_index = right_index = 0+    while left_index < len(left) and right_index < len(right):+        if left[left_index][0] <= right[right_index][0]:+            merged_input.append(left[left_index])+            left_index += 1+        else:+            merged_input.append(right[right_index])+            right_index += 1+    merged_input.extend(left[left_index:])+    merged_input.extend(right[right_index:])++    merged: list[Interval] = [merged_input[0]]+    for lower, upper in merged_input[1:]:+        prev_lower, prev_upper = merged[-1]++        if (+            prev_upper.version is None+            or lower.version is None+            or prev_upper.version > lower.version+        ):+            overlaps = True+        elif prev_upper.version == lower.version:+            overlaps = prev_upper.inclusive or lower.inclusive+        else:+            # An ordering gap may still hold no version when the two bounds+            # straddle a synthetic boundary; merge across an empty gap to+            # stay canonical.+            gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive)+            gap_upper = UpperBound(lower.version, not lower.inclusive)+            overlaps = range_is_empty(gap_lower, gap_upper)++        if overlaps:+            merged[-1] = (prev_lower, max(prev_upper, upper))+        else:+            merged.append((lower, upper))++    return merged+++def _complement_ranges(ranges: Sequence[Interval]) -> list[Interval]:+    """Complement a sorted, non-overlapping interval list.++    Yields the gaps between intervals plus a leading gap before the first and+    a trailing gap after the last. Bound inclusivity flips so that+    complement-of-complement round-trips back to the input.+    """+    if not ranges:+        return list(FULL_RANGE)++    result: list[Interval] = []+    prev_upper: UpperBound | None = None++    for lower, upper in ranges:+        if prev_upper is None:+            # Leading gap below the first interval. Every range reaching here is+            # floor-canonical: ``_canonical_floor`` has already folded an+            # inclusive lower at or below ``0.dev0`` into ``-inf``. So a finite+            # first lower always leaves a non-empty gap down to ``-inf``, while a+            # ``-inf`` lower leaves no leading gap at all.+            if lower.version is not None:+                gap_upper = UpperBound(lower.version, not lower.inclusive)+                result.append((NEG_INF, gap_upper))+        else:+            gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive)+            gap_upper = UpperBound(lower.version, not lower.inclusive)+            # Input intervals are canonical (sorted, disjoint, non-touching),+            # so the gap between two of them always holds at least one version.+            result.append((gap_lower, gap_upper))+        prev_upper = upper++    # The empty-input early return guarantees the loop ran.+    assert prev_upper is not None+    if prev_upper.version is not None:+        gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive)+        result.append((gap_lower, POS_INF))++    return result+++def _canonical_floor(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]:+    """Collapse the PEP 440 floor in a sorted interval list.++    Only the first interval can touch ``0.dev0`` (the minimum version). An+    inclusive lower at or below it admits everything below, the same as+    ``-inf``, so ``>=0.dev0`` becomes the one canonical full range. An+    exclusive upper at or below it leaves the interval empty, so it is dropped.+    """+    if not bounds:+        return bounds++    lower, upper = bounds[0]+    if range_is_empty(NEG_INF, upper):+        return bounds[1:]++    if (+        lower.inclusive+        and isinstance(lower.version, Version)+        and lower.version <= MIN_VERSION+    ):+        return ((NEG_INF, upper), *bounds[1:])++    return bounds+++def _predecessor_boundary(version: Version) -> BoundaryVersion | None:+    """The boundary whose least successor is *version*, or ``None``.++    Inverse of :func:`~packaging._ranges.least_version_above`. A plain version+    that is exactly such a successor (``1.0a2.dev0`` sits just above+    ``AFTER_POSTS(1.0a1)``) folds back to that boundary, so ``>=1.0a2.dev0`` and+    ``>1.0a1`` share one form. The proposed boundary is confirmed by+    round-tripping through ``least_version_above``.+    """+    # Only a least successor carries a dev segment, so nothing else can fold.+    if version.dev is None:+        return None++    candidate: BoundaryVersion | None = None+    if version.pre is not None and version.dev == 0 and version.post is None:+        # 1.0a2.dev0 -> AFTER_POSTS(1.0a1)+        kind, number = version.pre+        if number >= 1:+            candidate = BoundaryVersion(+                version.__replace__(pre=(kind, number - 1), dev=None),+                BoundaryKind.AFTER_POSTS,+            )+    elif version.dev >= 1:+        # 1.0.dev3 -> AFTER_LOCALS(1.0.dev2)+        candidate = BoundaryVersion(+            version.__replace__(dev=version.dev - 1), BoundaryKind.AFTER_LOCALS+        )+    elif version.dev == 0 and version.post is not None:+        # 1.0.post1.dev0 -> AFTER_LOCALS(1.0.post0); 1.0.post0.dev0 -> AFTER_LOCALS(1.0)+        base = (+            version.__replace__(post=None, dev=None)+            if version.post == 0+            else version.__replace__(post=version.post - 1, dev=None)+        )+        candidate = BoundaryVersion(base, BoundaryKind.AFTER_LOCALS)+
… 1820 more lines (truncated)
src/packaging/requirements.py +88 lines
--- +++ @@ -5,3 +5,3 @@ -from typing import Iterator+from typing import TYPE_CHECKING @@ -10,4 +10,7 @@ from .markers import Marker, _normalize_extra_values-from .specifiers import SpecifierSet+from .specifiers import InvalidSpecifier, SpecifierSet from .utils import canonicalize_name++if TYPE_CHECKING:+    from collections.abc import Iterator @@ -26,2 +29,4 @@     An invalid requirement was found, users should refer to PEP 508.++    .. versionadded:: 16.1     """@@ -36,2 +41,14 @@ +    .. versionadded:: 16.1++    .. versionchanged:: 22.0+        Added equality (``__eq__``) and hashing (``__hash__``) so requirements+        can be compared and stored in sets / dicts.++    .. versionchanged:: 23.2+        Equality and hashing began canonicalizing requirement names, so+        requirements whose names differ only by normalization (e.g.+        ``Requirement("Foo")`` vs ``Requirement("foo")``) now compare and hash+        equal.+     Instances are safe to serialize with :mod:`pickle`. They use a stable@@ -45,2 +62,12 @@         release.++    .. versionchanged:: 26.3++        The dedicated pickle support introduced in 26.2 did not preserve the+        specifier's explicit :attr:`~packaging.specifiers.SpecifierSet.prereleases`+        override; it is now included again.++        Equality and hashing normalize requirement names, extras, and+        equivalent specifiers. The string representation still preserves the+        parsed name and extras spelling.     """@@ -51,2 +78,4 @@     # TODO: Can we normalize the name and extra name?++    __slots__ = ("extras", "marker", "name", "specifier", "url") @@ -60,4 +89,7 @@         self.url: str | None = parsed.url or None-        self.extras: set[str] = set(parsed.extras or [])-        self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)+        self.extras: set[str] = set(parsed.extras)+        try:+            self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)+        except InvalidSpecifier as e:+            raise InvalidRequirement(str(e)) from e         self.marker: Marker | None = None@@ -85,6 +117,8 @@ -    def __getstate__(self) -> str:-        # Return the requirement string for compactness and stability.-        # Re-parsed on load to reconstruct all fields.-        return str(self)+    def __getstate__(self) -> tuple[str, bool | None]:+        # Return the requirement string for compactness and stability, paired+        # with the specifier's explicit prereleases override, which is not+        # captured by the string form. Re-parsed on load to reconstruct all+        # other fields.+        return (str(self), self.specifier._prereleases) @@ -92,18 +126,31 @@         if isinstance(state, str):-            # New format (26.2+): just the requirement string.-            try:-                tmp = Requirement(state)-            except InvalidRequirement as exc:-                raise TypeError(f"Cannot restore Requirement from {state!r}") from exc-            self.name = tmp.name-            self.url = tmp.url-            self.extras = tmp.extras-            self.specifier = tmp.specifier-            self.marker = tmp.marker+            # Format (26.2): just the requirement string.+            requirement_string: str = state+            prereleases: bool | None = None+        elif (+            isinstance(state, tuple)+            and len(state) == 2+            and isinstance(state[0], str)+            and (state[1] is None or isinstance(state[1], bool))+        ):+            # New format (26.3+): (requirement string, specifier prereleases).+            requirement_string, prereleases = state+        elif isinstance(state, dict) and state.keys() >= set(self.__slots__):+            # Old format (packaging <= 26.1, no __slots__): plain __dict__.+            for key in self.__slots__:+                setattr(self, key, state[key])             return-        if isinstance(state, dict):-            # Old format (packaging <= 26.1, no __slots__): plain __dict__.-            self.__dict__.update(state)-            return-        raise TypeError(f"Cannot restore Requirement from {state!r}")+        else:+            raise TypeError(f"Cannot restore Requirement from {state!r}")++        try:+            tmp = Requirement(requirement_string)+        except InvalidRequirement as exc:+            raise TypeError(f"Cannot restore Requirement from {state!r}") from exc+        self.name = tmp.name+        self.url = tmp.url+        self.extras = tmp.extras+        self.specifier = tmp.specifier+        self.specifier._prereleases = prereleases+        self.marker = tmp.marker @@ -116,3 +163,16 @@     def __hash__(self) -> int:-        return hash(tuple(self._iter_parts(canonicalize_name(self.name))))+        # Mirror __eq__ by hashing the canonical specifier object rather than+        # its raw string. ``_iter_parts`` yields ``str(self.specifier)``, which+        # is non-canonical, so trailing-zero-equivalent requirements such as+        # ``foo==1.0.0`` and ``foo==1.0.0.0`` (which compare equal) would+        # otherwise hash differently, breaking the hash/__eq__ invariant.+        return hash(+            (+                canonicalize_name(self.name),+                frozenset(canonicalize_name(e) for e in self.extras),+                self.specifier,+                self.url,+                self.marker,+            )+        ) @@ -122,5 +182,8 @@ +        # Extras must be normalized before comparison as per PEP 685.+        self_extras = frozenset(canonicalize_name(e) for e in self.extras)+        other_extras = frozenset(canonicalize_name(e) for e in other.extras)         return (             canonicalize_name(self.name) == canonicalize_name(other.name)-            and self.extras == other.extras+            and self_extras == other_extras             and self.specifier == other.specifier
src/packaging/specifiers.py +366 lines
--- +++ @@ -13,7 +13,3 @@ import abc-import enum-import functools-import itertools import re-import sys import typing@@ -24,5 +20,2 @@     Final,-    Iterable,-    Iterator,-    Sequence,     TypeVar,@@ -31,9 +24,28 @@ +from ._ranges import (+    FULL_RANGE,+    bounds_for_spec,+    coerce_version,+    filter_by_ranges,+    intersect_specifier_bounds,+    matches_bounds_only,+    ranges_are_prerelease_only,+    resolve_prereleases,+    trim_release,+) from .utils import canonicalize_version-from .version import InvalidVersion, Version--if sys.version_info >= (3, 10):-    from typing import TypeGuard  # pragma: no cover-elif TYPE_CHECKING:-    from typing_extensions import TypeGuard+from .version import Version++if TYPE_CHECKING:+    import sys+    from collections.abc import Iterable, Iterator, Sequence++    if sys.version_info >= (3, 10):+        from typing import TypeGuard+    else:+        from typing_extensions import TypeGuard++    from . import ranges+    from ._ranges import Interval+ @@ -67,276 +79,42 @@ UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion)-CallableOperator = Callable[[Version, str], bool]--# The smallest possible PEP 440 version. No valid version is less than this.-_MIN_VERSION: Final[Version] = Version("0.dev0")---def _trim_release(release: tuple[int, ...]) -> tuple[int, ...]:-    """Strip trailing zeros from a release tuple for normalized comparison."""-    end = len(release)-    while end > 1 and release[end - 1] == 0:-        end -= 1-    return release if end == len(release) else release[:end]---class _BoundaryKind(enum.Enum):-    """Where a boundary marker sits in the version ordering."""--    AFTER_LOCALS = enum.auto()  # after V+local, before V.post0-    AFTER_POSTS = enum.auto()  # after V.postN, before next release--[email protected]_ordering-class _BoundaryVersion:-    """A point on the version line between two real PEP 440 versions.--    Some specifier semantics imply boundaries between real versions:-    ``<=1.0`` includes ``1.0+local`` and ``>1.0`` excludes-    ``1.0.post0``.  No real :class:`Version` falls on those boundaries,-    so this class creates values that sort between the real versions-    on either side.--    Two kinds exist, shown relative to a base version V::--        V < V+local < AFTER_LOCALS(V) < V.post0 < AFTER_POSTS(V)--    ``AFTER_LOCALS`` sits after V and every V+local, but before-    V.post0.  Upper bound of ``<=V``, ``==V``, ``!=V``.--    ``AFTER_POSTS`` sits after every V.postN, but before the next-    release segment.  Lower bound of ``>V`` (final or pre-release V)-    to exclude post-releases per PEP 440.+++# Operators whose result is just a direct Version comparison, given a parsed+# item with no local. ``<=``/``==``/``!=`` need that no-local guard because+# PEP 440 strips locals on those; ``>=`` works regardless.+_DIRECT_COMPARE_OPS: dict[str, Callable[[Version, Version], bool]] = {+    ">=": Version.__ge__,+    "<=": Version.__le__,+    "==": Version.__eq__,+    "!=": Version.__ne__,+}+++def _fast_match(specifier: Specifier, parsed: Version) -> bool | None:+    """Match ``parsed`` against ``specifier`` without building a range.++    Handles ``>=``, ``<=``, ``==``, ``!=``, ``<``, ``>`` when the spec is+    not a wildcard and ``parsed`` has no local. Returns ``None`` when the+    range path must be used. Pre-release policy is left to the caller.     """--    __slots__ = ("_kind", "_trimmed_release", "version")--    def __init__(self, version: Version, kind: _BoundaryKind) -> None:-        self.version = version-        self._kind = kind-        self._trimmed_release = _trim_release(version.release)--    def _is_family(self, other: Version) -> bool:-        """Is ``other`` a version that this boundary sorts above?"""-        v = self.version-        if not (-            other.epoch == v.epoch-            and _trim_release(other.release) == self._trimmed_release-            and other.pre == v.pre+    op_str, ver_str = specifier._spec+    if ver_str.endswith(".*") or parsed.local is not None:+        return None++    direct_compare = _DIRECT_COMPARE_OPS.get(op_str)+    if direct_compare is not None:+        return direct_compare(parsed, specifier._require_spec_version(ver_str))++    if op_str in ("<", ">"):+        spec_v = specifier._require_spec_version(ver_str)+        # ``<V``/``>V`` carve out V's family (pre/dev/post); that only+        # matters when parsed shares V's epoch and trimmed release.+        # Otherwise a direct cmpkey comparison is correct.+        if parsed.epoch != spec_v.epoch or trim_release(parsed.release) != trim_release(+            spec_v.release         ):-            return False-        if self._kind == _BoundaryKind.AFTER_LOCALS:-            # Local family: exact same public version (any local label).-            return other.post == v.post and other.dev == v.dev-        # Post family: same base + any post-release (or identical).-        return other.dev == v.dev or other.post is not None--    def __eq__(self, other: object) -> bool:-        if isinstance(other, _BoundaryVersion):-            return self.version == other.version and self._kind == other._kind-        return NotImplemented--    def __lt__(self, other: _BoundaryVersion | Version) -> bool:-        if isinstance(other, _BoundaryVersion):-            if self.version != other.version:-                return self.version < other.version-            return self._kind.value < other._kind.value-        return not self._is_family(other) and self.version < other--    def __hash__(self) -> int:-        return hash((self.version, self._kind))--    def __repr__(self) -> str:-        return f"{self.__class__.__name__}({self.version!r}, {self._kind.name})"--[email protected]_ordering-class _LowerBound:-    """Lower bound of a version range.--    A version *v* of ``None`` means unbounded below (-inf).-    At equal versions, ``[v`` sorts before ``(v`` because an inclusive-    bound starts earlier.-    """--    __slots__ = ("inclusive", "version")--    def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None:-        self.version = version-        self.inclusive = inclusive--    def __eq__(self, other: object) -> bool:-        if not isinstance(other, _LowerBound):-            return NotImplemented  # pragma: no cover-        return self.version == other.version and self.inclusive == other.inclusive--    def __lt__(self, other: _LowerBound) -> bool:-        if not isinstance(other, _LowerBound):  # pragma: no cover-            return NotImplemented-        # -inf < anything (except -inf).-        if self.version is None:-            return other.version is not None-        if other.version is None:-            return False-        if self.version != other.version:-            return self.version < other.version-        # [v < (v: inclusive starts earlier.-        return self.inclusive and not other.inclusive--    def __hash__(self) -> int:-        return hash((self.version, self.inclusive))--    def __repr__(self) -> str:-        bracket = "[" if self.inclusive else "("-        return f"<{self.__class__.__name__} {bracket}{self.version!r}>"--[email protected]_ordering-class _UpperBound:-    """Upper bound of a version range.--    A version *v* of ``None`` means unbounded above (+inf).-    At equal versions, ``v)`` sorts before ``v]`` because an exclusive-    bound ends earlier.-    """--    __slots__ = ("inclusive", "version")--    def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None:-        self.version = version-        self.inclusive = inclusive--    def __eq__(self, other: object) -> bool:-        if not isinstance(other, _UpperBound):-            return NotImplemented  # pragma: no cover-        return self.version == other.version and self.inclusive == other.inclusive--    def __lt__(self, other: _UpperBound) -> bool:-        if not isinstance(other, _UpperBound):  # pragma: no cover-            return NotImplemented-        # Nothing < +inf (except +inf itself).-        if self.version is None:-            return False-        if other.version is None:-            return True-        if self.version != other.version:-            return self.version < other.version-        # v) < v]: exclusive ends earlier.-        return not self.inclusive and other.inclusive--    def __hash__(self) -> int:-        return hash((self.version, self.inclusive))--    def __repr__(self) -> str:-        bracket = "]" if self.inclusive else ")"
… 1096 more lines (truncated)
src/packaging/utils.py +85 lines
--- +++ @@ -7,5 +7,5 @@ import re-from typing import NewType, Tuple, Union, cast--from .tags import Tag, UnsortedTagsError, parse_tag+from typing import NewType, Union, cast++from .tags import InvalidTag, Tag, UnsortedTagsError, parse_tag from .version import InvalidVersion, Version, _TrimmedRelease@@ -30,3 +30,8 @@ -BuildTag = Union[Tuple[()], Tuple[int, str]]+BuildTag = Union[tuple[()], tuple[int, str]]+"""+A wheel build tag: an empty tuple, or a ``(build number, build tag suffix)`` pair.++.. versionadded:: 20.9+""" @@ -35,2 +40,4 @@ A :class:`typing.NewType` of :class:`str`, representing a normalized name.++.. versionadded:: 20.4 """@@ -41,2 +48,4 @@     An invalid distribution name; users should refer to the packaging user guide.++    .. versionadded:: 23.2     """@@ -47,2 +56,4 @@     An invalid wheel filename was found, users should refer to PEP 427.++    .. versionadded:: 20.9     """@@ -53,2 +64,4 @@     An invalid sdist filename was found, users should refer to the packaging user guide.++    .. versionadded:: 20.9     """@@ -60,5 +73,8 @@ )-_normalized_regex = re.compile(r"[a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9]", re.ASCII)+_normalized_regex = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*", re.ASCII) # PEP 427: The build number must start with a digit. _build_tag_regex = re.compile(r"(\d+)(.*)", re.ASCII)+# PEP 427: Valid characters for an escaped project name in a wheel filename.+# Requires at least one character so an empty project name is rejected.+_wheel_name_regex = re.compile(r"^[\w._]+\Z", re.UNICODE) @@ -89,2 +105,10 @@     'requests'++    .. versionadded:: 16.2++    .. versionchanged:: 20.4+       The return type was changed to :class:`NormalizedName`.++    .. versionchanged:: 23.2+       Added the *validate* keyword parameter.     """@@ -104,4 +128,9 @@     """-    Check if a name is already normalized (i.e. :func:`canonicalize_name` would-    roundtrip to the same value).+    Check if a name is a normalized project name (i.e. a valid name that+    :func:`canonicalize_name` would roundtrip to the same value).++    The roundtrip only characterizes normalized names for *valid* names. A name+    must start and end with an ASCII letter or digit, which+    :func:`canonicalize_name` does not enforce: it leaves a leading or trailing+    hyphen in place, so such a name roundtrips without being normalized. @@ -109,3 +138,3 @@ -    >>> from packaging.utils import is_normalized_name+    >>> from packaging.utils import canonicalize_name, is_normalized_name     >>> is_normalized_name("requests")@@ -114,2 +143,8 @@     False+    >>> canonicalize_name("_not_legal")+    '-not-legal'+    >>> is_normalized_name("-not-legal")  # roundtrips, but not a valid name+    False++    .. versionadded:: 23.2     """@@ -147,2 +182,10 @@     '1.4'++    .. versionadded:: 17.1++    .. versionchanged:: 21.0+       The return type was narrowed to :class:`str`.++    .. versionchanged:: 22.0+       Added the *strip_trailing_zero* keyword parameter.     """@@ -198,4 +241,14 @@ +    .. versionadded:: 20.9++    .. versionchanged:: 23.2+       Raises :class:`InvalidWheelFilename` when the version component is invalid.+     .. versionadded:: 26.1        The *validate_order* parameter.++    .. versionchanged:: 26.3+       Raises :class:`InvalidWheelFilename` when an interpreter component is+       not an identifier, a tag set component is empty, or the project name is+       empty.     """@@ -216,3 +269,3 @@     # See PEP 427 for the rules on escaping the project name.-    if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:+    if "__" in name_part or _wheel_name_regex.match(name_part) is None:         raise InvalidWheelFilename(f"Invalid project name: {filename!r}")@@ -245,2 +298,6 @@         ) from None+    except InvalidTag:+        raise InvalidWheelFilename(+            f"Invalid wheel filename (invalid tag component): {filename!r}"+        ) from None     return (name, version, build, tags)@@ -257,4 +314,6 @@     :raises InvalidSdistFilename: If the filename does not end-        with an sdist extension (``.zip`` or ``.tar.gz``), or if it does not-        contain a dash separating the name and the version of the distribution.+        with an sdist extension (``.zip`` or ``.tar.gz``), if it does not+        contain a dash separating the name and the version of the distribution,+        if the project name is empty, or if the version portion is not a valid+        version. @@ -267,2 +326,13 @@     True++    .. versionadded:: 20.9++    .. versionchanged:: 21.0+       Added support for ``.zip`` source distributions.++    .. versionchanged:: 23.2+       Raises :class:`InvalidSdistFilename` when the version component is invalid.++    .. versionchanged:: 26.3+       Raises :class:`InvalidSdistFilename` on an empty project name. @@ -285,2 +355,6 @@         raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")+    if not name_part:+        raise InvalidSdistFilename(+            f"Invalid sdist filename (empty project name): {filename!r}"+        ) 
src/packaging/version.py +33 lines
--- +++ @@ -20,3 +20,2 @@     SupportsInt,-    Tuple,     TypedDict,@@ -69,9 +68,9 @@ -LocalType = Tuple[Union[int, str], ...]--CmpLocalType = Tuple[Tuple[int, str], ...]-CmpSuffix = Tuple[int, int, int, int, int, int]+LocalType = tuple[Union[int, str], ...]++CmpLocalType = tuple[tuple[int, str], ...]+CmpSuffix = tuple[int, int, int, int, int, int] CmpKey = Union[-    Tuple[int, Tuple[int, ...], CmpSuffix],-    Tuple[int, Tuple[int, ...], CmpSuffix, CmpLocalType],+    tuple[int, tuple[int, ...], CmpSuffix],+    tuple[int, tuple[int, ...], CmpSuffix, CmpLocalType], ]@@ -290,6 +289,11 @@         letter, number = value-        letter = normalize_pre(letter)-        if letter in {"a", "b", "rc"} and isinstance(number, int) and number >= 0:+        # The letter must be a string before it can be normalized.+        if (+            isinstance(letter, str)+            and (normalized := normalize_pre(letter)) in {"a", "b", "rc"}+            and isinstance(number, int)+            and number >= 0+        ):             # type checkers can't infer the Literal type here on letter-            return (letter, number)  # type: ignore[return-value]+            return (normalized, number)  # type: ignore[return-value]     msg = f"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}"@@ -413,5 +417,12 @@         """-        if _SIMPLE_VERSION_INDICATORS.issuperset(version):+        try:+            is_simple = _SIMPLE_VERSION_INDICATORS.issuperset(version)+        except TypeError:+            raise InvalidVersion(f"Invalid version: {version!r}") from None++        if is_simple:             try:                 self._release = tuple(map(int, version.split(".")))+            except AttributeError:+                raise InvalidVersion(f"Invalid version: {version!r}") from None             except ValueError:@@ -435,3 +446,6 @@         # Validate the version and parse it into pieces-        match = self._regex.fullmatch(version)+        try:+            match = self._regex.fullmatch(version)+        except TypeError:+            raise InvalidVersion(f"Invalid version: {version!r}") from None         if not match:@@ -1043,2 +1057,4 @@         1++        .. versionadded:: 20.0         """@@ -1054,2 +1070,4 @@         0++        .. versionadded:: 20.0         """@@ -1065,2 +1083,4 @@         0++        .. versionadded:: 20.0         """@@ -1081,2 +1101,3 @@             self._key_cache = version._key_cache+            self._hash_cache = version._hash_cache             return
tests/conftest.py +17 lines
--- +++ @@ -3,2 +3,19 @@ import sysconfig+import typing++import pytest++from packaging.markers import _cached_default_environment++if typing.TYPE_CHECKING:+    from collections.abc import Generator++[email protected](autouse=True)+def _clear_default_environment_cache() -> Generator[None, None, None]:+    # default_environment() is cached, so tests that patch platform/sys must run+    # against a fresh cache and must not leak their patched values to later tests.+    _cached_default_environment.cache_clear()+    yield+    _cached_default_environment.cache_clear() 
tests/property/strategies.py +190 lines
--- +++ @@ -6,2 +6,4 @@ +from typing import TYPE_CHECKING+ from hypothesis import settings@@ -11,2 +13,22 @@ from packaging.version import Version++if TYPE_CHECKING:+    from packaging.ranges import VersionRange+++def eq_versions_only(a: VersionRange, b: VersionRange) -> bool:+    """Compare two ranges by bounds and ``===`` literals only, ignoring the+    arbitrary-string flag and both pre-release slots.++    Complement preserves ``_admit_arbitrary`` (only the universal range+    admits non-version strings, never algebra), so ``r | ~r`` is never+    structurally equal to ``VersionRange.full()`` when neither ``r`` nor+    ``~r`` is empty. The configured override mirrors ``SpecifierSet.__and__``+    rather than pure Boolean algebra, and the opt-in region (``_pre_region``)+    is part of equality, so ``==`` distinguishes ranges that accept the same+    versions. Use this helper when the property is "same set of versions+    accepted".+    """+    return a._bounds == b._bounds and a._admit == b._admit and a._reject == b._reject+ @@ -67,3 +89,3 @@     """Generate a random PEP 440 version."""-    epoch = draw(st.sampled_from([None, 0, 1]))+    epoch = draw(st.sampled_from([None, 0, 1, 2, 3]))     num_segments = draw(st.integers(min_value=min_segments, max_value=4))@@ -111,7 +133,15 @@ @st.composite-def release_versions(draw: st.DrawFn, *, min_segments: int = 1) -> Version:-    """Generate a final release version (no pre/post/dev/local)."""+def release_versions(+    draw: st.DrawFn, *, min_segments: int = 1, allow_epoch: bool = False+) -> Version:+    """Generate a final release version (no pre/post/dev/local).++    With ``allow_epoch=True`` the release may carry a non-zero epoch, so a+    zero release becomes a non-zero-epoch zero family (e.g. ``1!0``).+    """     num_segments = draw(st.integers(min_value=min_segments, max_value=4))     release = tuple(draw(small_ints) for _ in range(num_segments))-    return Version(".".join(str(s) for s in release))+    epoch = draw(st.sampled_from([None, 1, 2])) if allow_epoch else None+    prefix = f"{epoch}!" if epoch else ""+    return Version(prefix + ".".join(str(s) for s in release)) @@ -134,4 +164,16 @@ @st.composite-def specifier_sets(draw: st.DrawFn) -> SpecifierSet:-    """Generate a random SpecifierSet from common operator/version pairs."""+def specifier_sets(+    draw: st.DrawFn,+    *,+    vary_prereleases: bool = False,+) -> SpecifierSet:+    """Random SpecifierSet over ``>= <= > < == !=`` and ``major.minor``.++    Narrow on purpose. Tests that need wildcards, locals, pre/post/dev+    on the RHS, epochs, or ``===`` should use :func:`rich_specifier_sets`.++    With ``vary_prereleases=True`` the configured pre-release policy is+    drawn from ``(None, True, False)``; otherwise it is left as ``None``+    (autodetect).+    """     num = draw(st.integers(min_value=1, max_value=3))@@ -143,3 +185,74 @@         parts.append(f"{op}{major}.{minor}")-    return SpecifierSet(",".join(parts))++    prereleases = (+        draw(st.sampled_from([None, True, False])) if vary_prereleases else None+    )++    return SpecifierSet(",".join(parts), prereleases=prereleases)+++_ordered_ops = st.sampled_from([">=", "<=", ">", "<"])+_equality_ops = st.sampled_from(["==", "!="])++[email protected]+def pep440_specifier_strings(+    draw: st.DrawFn,+    *,+    include_arbitrary: bool = False,+) -> str:+    """One specifier string covering the full PEP 440 surface.++    Includes pre/post/dev/local-bearing RHS versions, epochs, multi-+    segment release tuples, ``==V.*`` / ``!=V.*`` wildcards, and+    optionally ``===L``.+    """+    shape = draw(st.sampled_from(["ordered", "equality", "wildcard", "compatible"]))+    if include_arbitrary and draw(st.booleans()):+        shape = "arbitrary"++    if shape == "ordered":+        # ``>= <= > <`` reject ``+local`` on the RHS.+        return f"{draw(_ordered_ops)}{draw(pep440_versions(include_local=False))}"++    if shape == "equality":+        return f"{draw(_equality_ops)}{draw(pep440_versions())}"++    if shape == "wildcard":+        # ``==V.*`` / ``!=V.*`` take a release-only RHS; epochs reach the+        # epoch-zero family floor (``==1!0.*``).+        return f"{draw(_equality_ops)}{draw(release_versions(allow_epoch=True))}.*"++    if shape == "compatible":+        return f"~={draw(multi_segment_versions())}"++    # ``===L`` with a parseable literal. Unparsable literals like+    # ``===wat`` are skipped: De Morgan can fail when an unparsable+    # ``===`` interacts with a non-full rangelike, since the bound+    # universe is parseable Versions but the literal universe is+    # all strings.+    return f"==={draw(pep440_versions())}"++[email protected]+def rich_specifier_sets(+    draw: st.DrawFn,+    *,+    include_arbitrary: bool = False,+    vary_prereleases: bool = False,+) -> SpecifierSet:+    """1-3 specifiers from :func:`pep440_specifier_strings`, joined.++    With ``vary_prereleases=True`` the configured pre-release policy is drawn+    from ``(None, True, False)``; otherwise it is left as ``None`` (autodetect).+    """+    num = draw(st.integers(min_value=1, max_value=3))+    parts = [+        draw(pep440_specifier_strings(include_arbitrary=include_arbitrary))+        for _ in range(num)+    ]+    prereleases = (+        draw(st.sampled_from([None, True, False])) if vary_prereleases else None+    )+    return SpecifierSet(",".join(parts), prereleases=prereleases) @@ -162 +275,71 @@     return (_build(draw), _build(draw), _build(draw))+++# Bases for adjacency chains, one per family (final, post, dev, floor, epoch).+_ADJACENCY_BASES = [+    Version(v)+    for v in (+        "0",+        "1.0",+        "1.0.post0",+        "3.8",+        "1!0",+        "0.dev0",+        "1.0.dev0",+        "1!0.dev0",+        # Non-floor release-dev bases a ``!=W.*`` lead can abut (W just below).+        "2.dev0",+        "3.dev0",+    )+]++# Leads: a lower bound, a release-family wildcard the run can sit inside, or a+# ``!=W.*`` wildcard exclusion the dev run can abut (driving wildcard-then-dev-run).+_ADJACENCY_LEADS = [+    "",+    ">=0.dev0",+    ">=1.0",+    ">=1.0.post0",+    "==1.0.*",+    "==1!0.*",+    "==3.8.*",+    "==0.*",+    "!=0.*",+    "!=1.*",+    "!=2.*",+]+++def _next_adjacent(version: Version) -> Version:+    """The immediate successor of *version* and its local family.++    Independent of the production ``least_version_above`` so the strategy does+    not validate the encoder against itself: a dev release steps its dev; any+    other release steps to its next post at ``.dev0`` (``.post0.dev0`` for a+    final release, ``.post(N+1).dev0`` for a ``.postN`` release).+    """+    if version.dev is not None:+        return version.__replace__(dev=version.dev + 1, local=None)+    next_post = (version.post + 1) if version.post is not None else 0+    return version.__replace__(post=next_post, dev=0, local=None)++[email protected]+def adjacency_exclusion_sets(draw: st.DrawFn) -> SpecifierSet:+    """An optional lower/wildcard lead plus a run of adjacent exclusions.++    Excluding a version and several of its immediate successors removes a+    contiguous block whose canonical bounds are a single merged gap. When the+    lead and base line up, this drives the ``to_specifier_set`` ``!=`` chain,+    dev-run, wildcard-then-dev-run, and epoch floor-run recovery paths that the+    independent specifier strategies never reach by chance.+    """+    base = draw(st.sampled_from(_ADJACENCY_BASES))+    points = [base]+    for _ in range(draw(st.integers(min_value=0, max_value=4))):+        points.append(_next_adjacent(points[-1]))++    lead = draw(st.sampled_from(_ADJACENCY_LEADS))+    parts = ([lead] if lead else []) + [f"!={point}" for point in points]+    prereleases = draw(st.sampled_from([None, True, False]))+    return SpecifierSet(",".join(parts), prereleases=prereleases)
tests/property/test_ranges_cross_epoch.py +112 lines
--- +++ @@ -0,0 +1,112 @@+# This file is dual licensed under the terms of the Apache License, Version+# 2.0, and the BSD License. See the LICENSE file in the root of this repository+# for complete details.++"""Property tests for ``VersionRange`` algebra across distinct epochs.++PEP 440 epochs partition the version order into disjoint cohorts; an+``==1.0`` predicate in epoch 0 never overlaps an ``==1.0`` predicate in+epoch 1. The lattice laws still hold across cohorts, and round-tripping+through :meth:`to_specifier_set` must preserve the epoch on every side.+"""++from __future__ import annotations++from typing import TYPE_CHECKING++import pytest+from hypothesis import given++from .strategies import (+    SETTINGS,+    VERSION_POOL,+    pep440_versions,+    rich_specifier_sets,+)++if TYPE_CHECKING:+    from packaging.ranges import VersionRange+    from packaging.specifiers import SpecifierSet+    from packaging.version import Version++pytestmark = pytest.mark.property++# Cross-epoch + dev/MIN_VERSION boundary probes for the membership oracle.+_EPOCH_PROBES = [+    "0.5",+    "1.0",+    "1.0a1",+    "0.dev0",+    "1.dev0",+    "1.dev1",+    "1.dev2",+    "1!0.5",+    "1!1.0",+    "1!0.dev0",+    "2!0.5",+    "2!1.0",+    "3!1.0",+]+++def _mem_eq(a: VersionRange, b: VersionRange) -> bool:+    """``a`` and ``b`` accept the same versions across the probe sample."""+    probes = [str(v) for v in VERSION_POOL] + _EPOCH_PROBES+    return all((p in a) == (p in b) for p in probes)+++@given(a=rich_specifier_sets(), b=rich_specifier_sets())+@SETTINGS+def test_de_morgan_holds_cross_epoch(a: SpecifierSet, b: SpecifierSet) -> None:+    """De Morgan holds for ranges that may straddle different epochs.++    The minimal engine canonicalizes empty/MIN_VERSION regions, so the two+    sides can differ in bound representation; compare on the version set.+    """+    ra, rb = a.to_range(), b.to_range()+    assert _mem_eq((ra & rb).complement(), ra.complement() | rb.complement())+    assert _mem_eq((ra | rb).complement(), ra.complement() & rb.complement())+++@given(+    a=rich_specifier_sets(),+    b=rich_specifier_sets(),+    v=pep440_versions(),+)+@SETTINGS+def test_membership_consistent_across_epochs(+    a: SpecifierSet, b: SpecifierSet, v: Version+) -> None:+    """``v in (a & b)`` iff ``v in a`` and ``v in b`` regardless of epochs."""+    ra, rb = a.to_range(), b.to_range()+    assert (v in (ra & rb)) == ((v in ra) and (v in rb))+    assert (v in (ra | rb)) == ((v in ra) or (v in rb))+++@given(spec_set=rich_specifier_sets())+@SETTINGS+def test_single_set_round_trip_preserves_epoch(spec_set: SpecifierSet) -> None:+    """``to_specifier_set`` round-trips epochs when the single-set form exists.++    When the conversion returns a single set, feeding it back through+    ``to_range`` must accept exactly the same versions; in particular any+    cross-epoch boundary in the source survives.+    """+    r = spec_set.to_range()+    converted = r.to_specifier_set()+    if converted is None:+        return+    recovered = converted.to_range()+    # Membership on a cross-epoch probe set must round-trip.+    probes = [+        "0.5",+        "1.0",+        "1.0a1",+        "1!0.5",+        "1!1.0",+        "2!0.5",+        "2!1.0",+        "3!1.0",+    ]+    for probe in probes:+        assert (probe in r) == (probe in recovered)
pluggy pypi
1.6.0 1y ago incident on record
YANKBURST
latest 1.6.0 versions 24 maintainers 1
0.10.0
0.11.0
0.12.0
0.13.0
0.13.1
1.0.0
1.1.0
1.2.0
1.3.0
1.4.0
1.5.0
1.6.0
YANK
1.1.0 marked yanked (still downloadable)
high · registry-verified · 2023-06-19 · 3y ago
BURST
2 releases in 0m: 0.5.1, 0.5.2
info · registry-verified · 2018-04-15 · 8y ago
release diff 1.5.0 → 1.6.0
+2 added · -1 removed · ~30 modified
pyproject.toml +50 lines
--- +++ @@ -3,4 +3,4 @@   # sync with setup.py until we discard non-pep-517/518-  "setuptools>=45.0",-  "setuptools-scm[toml]>=6.2.3",+  "setuptools>=65.0",+  "setuptools-scm[toml]>=8.0", ]@@ -8,7 +8,52 @@ +[project]+name = "pluggy"+license = {text = "MIT"}+authors = [{name = "Holger Krekel", email = "[email protected]"}]+classifiers = [+  "Development Status :: 6 - Mature",+  "Intended Audience :: Developers",+  "License :: OSI Approved :: MIT License",+  "Operating System :: POSIX",+  "Operating System :: Microsoft :: Windows",+  "Operating System :: MacOS :: MacOS X",+  "Topic :: Software Development :: Testing",+  "Topic :: Software Development :: Libraries",+  "Topic :: Utilities",+  "Programming Language :: Python :: Implementation :: CPython",+  "Programming Language :: Python :: Implementation :: PyPy",+  "Programming Language :: Python :: 3",+  "Programming Language :: Python :: 3 :: Only",+  "Programming Language :: Python :: 3.9",+  "Programming Language :: Python :: 3.10",+  "Programming Language :: Python :: 3.11",+  "Programming Language :: Python :: 3.12",+  "Programming Language :: Python :: 3.13",+]+description = "plugin and hook calling mechanisms for python"+readme = {file = "README.rst", content-type = "text/x-rst"}+requires-python = ">=3.9"++dynamic = ["version"]+[project.optional-dependencies]+dev = ["pre-commit", "tox"]+testing = ["pytest", "pytest-benchmark", "coverage"]++[tool.setuptools]+packages = ["pluggy"]+package-dir =  {""="src"}+package-data = {"pluggy" = ["py.typed"]}+  [tool.ruff.lint]-select = [-    "I",  # isort+extend-select = [+  "I",  # isort+  "F","E", "W",+  "UP", "ANN", ]+extend-ignore = ["ANN401"]++[tool.ruff.lint.extend-per-file-ignores]+"testing/*.py" = ["ANN001", "ANN002", "ANN003",  "ANN201", "ANN202","ANN204" ,]+"docs/*.py" = ["ANN001", "ANN002", "ANN003",  "ANN201", "ANN202","ANN204" ,] @@ -23,3 +68,3 @@ [tool.setuptools_scm]-write_to = "src/pluggy/_version.py"+version_file = "src/pluggy/_version.py" 
scripts/release.py +6 lines
--- +++ @@ -14,3 +14,3 @@ -def create_branch(version):+def create_branch(version: str) -> Repo:     """Create a fresh branch from upstream/main"""@@ -38,3 +38,3 @@ -def pre_release(version):+def pre_release(version: str) -> None:     """Generates new docs, release announcements and creates a local tag."""@@ -49,3 +49,3 @@ -def changelog(version, write_out=False):+def changelog(version: str, write_out: bool = False) -> None:     if write_out:@@ -58,3 +58,3 @@ -def main():+def main() -> int:     init(autoreset=True)@@ -68,2 +68,4 @@         return 1+    else:+        return 0 
scripts/towncrier-draft-to-file.py +1 lines
--- +++ @@ -4,3 +4,3 @@ -def main():+def main() -> int:     """
setup.cfg +0 lines
--- +++ @@ -1,53 +1 @@-[metadata]-name = pluggy-description = plugin and hook calling mechanisms for python-long_description = file: README.rst-long_description_content_type = text/x-rst-license = MIT-platforms = unix, linux, osx, win32-author = Holger Krekel-author_email = [email protected]-url = https://github.com/pytest-dev/pluggy-classifiers = -	Development Status :: 6 - Mature-	Intended Audience :: Developers-	License :: OSI Approved :: MIT License-	Operating System :: POSIX-	Operating System :: Microsoft :: Windows-	Operating System :: MacOS :: MacOS X-	Topic :: Software Development :: Testing-	Topic :: Software Development :: Libraries-	Topic :: Utilities-	Programming Language :: Python :: Implementation :: CPython-	Programming Language :: Python :: Implementation :: PyPy-	Programming Language :: Python :: 3-	Programming Language :: Python :: 3 :: Only-	Programming Language :: Python :: 3.8-	Programming Language :: Python :: 3.9-	Programming Language :: Python :: 3.10-	Programming Language :: Python :: 3.11--[options]-packages = -	pluggy-python_requires = >=3.8-package_dir = -	=src-setup_requires = -	setuptools-scm--[options.extras_require]-dev = -	pre-commit-	tox-testing = -	pytest-	pytest-benchmark--[options.package_data]-pluggy = py.typed--[devpi:upload]-formats = sdist.tgz,bdist_wheel- [egg_info]
src/pluggy/__init__.py +1 lines
--- +++ @@ -1,8 +1 @@-try:-    from ._version import version as __version__-except ImportError:-    # broken installation, we don't even try-    # unknown only works because we do poor mans version compare-    __version__ = "unknown"- __all__ = [@@ -23,3 +16,2 @@ ]- from ._hooks import HookCaller@@ -35,2 +27,3 @@ from ._result import Result+from ._version import version as __version__ from ._warnings import PluggyTeardownRaisedWarning
src/pluggy/_callers.py +87 lines
--- +++ @@ -6,9 +6,7 @@ +from collections.abc import Generator+from collections.abc import Mapping+from collections.abc import Sequence from typing import cast-from typing import Generator-from typing import Mapping from typing import NoReturn-from typing import Sequence-from typing import Tuple-from typing import Union import warnings@@ -23,6 +21,34 @@ # Wrapping with a tuple is the fastest type-safe way I found to do it.-Teardown = Union[-    Tuple[Generator[None, Result[object], None], HookImpl],-    Generator[None, object, object],-]+Teardown = Generator[None, object, object]+++def run_old_style_hookwrapper(+    hook_impl: HookImpl, hook_name: str, args: Sequence[object]+) -> Teardown:+    """+    backward compatibility wrapper to run a old style hookwrapper as a wrapper+    """++    teardown: Teardown = cast(Teardown, hook_impl.function(*args))+    try:+        next(teardown)+    except StopIteration:+        _raise_wrapfail(teardown, "did not yield")+    try:+        res = yield+        result = Result(res, None)+    except BaseException as exc:+        result = Result(None, exc)+    try:+        teardown.send(result)+    except StopIteration:+        pass+    except BaseException as e:+        _warn_teardown_exception(hook_name, hook_impl, e)+        raise+    else:+        _raise_wrapfail(teardown, "has second yield")+    finally:+        teardown.close()+    return result.get_result() @@ -30,11 +56,8 @@ def _raise_wrapfail(-    wrap_controller: (-        Generator[None, Result[object], None] | Generator[None, object, object]-    ),+    wrap_controller: Generator[None, object, object],     msg: str, ) -> NoReturn:-    co = wrap_controller.gi_code+    co = wrap_controller.gi_code  # type: ignore[attr-defined]     raise RuntimeError(-        "wrap_controller at %r %s:%d %s"-        % (co.co_name, co.co_filename, co.co_firstlineno, msg)+        f"wrap_controller at {co.co_name!r} {co.co_filename}:{co.co_firstlineno} {msg}"     )@@ -49,3 +72,3 @@     msg += "For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning"  # noqa: E501-    warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=5)+    warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=6) @@ -66,3 +89,2 @@     exception = None-    only_new_style_wrappers = True     try:  # run impl and wrapper setup functions in a loop@@ -73,4 +95,5 @@                     args = [caller_kwargs[argname] for argname in hook_impl.argnames]-                except KeyError:-                    for argname in hook_impl.argnames:+                except KeyError as e:+                    # coverage bug - this is tested+                    for argname in hook_impl.argnames:  # pragma: no cover                         if argname not in caller_kwargs:@@ -78,15 +101,10 @@                                 f"hook call must provide argument {argname!r}"-                            )+                            ) from e                  if hook_impl.hookwrapper:-                    only_new_style_wrappers = False-                    try:-                        # If this cast is not valid, a type error is raised below,-                        # which is the desired response.-                        res = hook_impl.function(*args)-                        wrapper_gen = cast(Generator[None, Result[object], None], res)-                        next(wrapper_gen)  # first yield-                        teardowns.append((wrapper_gen, hook_impl))-                    except StopIteration:-                        _raise_wrapfail(wrapper_gen, "did not yield")+                    function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)++                    next(function_gen)  # first yield+                    teardowns.append(function_gen)+                 elif hook_impl.wrapper:@@ -110,73 +128,42 @@     finally:-        # Fast path - only new-style wrappers, no Result.-        if only_new_style_wrappers:-            if firstresult:  # first result hooks return a single value-                result = results[0] if results else None-            else:-                result = results+        if firstresult:  # first result hooks return a single value+            result = results[0] if results else None+        else:+            result = results -            # run all wrapper post-yield blocks-            for teardown in reversed(teardowns):-                try:-                    if exception is not None:-                        teardown.throw(exception)  # type: ignore[union-attr]-                    else:-                        teardown.send(result)  # type: ignore[union-attr]-                    # Following is unreachable for a well behaved hook wrapper.-                    # Try to force finalizers otherwise postponed till GC action.-                    # Note: close() may raise if generator handles GeneratorExit.-                    teardown.close()  # type: ignore[union-attr]-                except StopIteration as si:-                    result = si.value-                    exception = None-                    continue-                except BaseException as e:-                    exception = e-                    continue-                _raise_wrapfail(teardown, "has second yield")  # type: ignore[arg-type]+        # run all wrapper post-yield blocks+        for teardown in reversed(teardowns):+            try:+                if exception is not None:+                    try:+                        teardown.throw(exception)+                    except RuntimeError as re:+                        # StopIteration from generator causes RuntimeError+                        # even for coroutine usage - see #544+                        if (+                            isinstance(exception, StopIteration)+                            and re.__cause__ is exception+                        ):+                            teardown.close()+                            continue+                        else:+                            raise+                else:+                    teardown.send(result)+                # Following is unreachable for a well behaved hook wrapper.+                # Try to force finalizers otherwise postponed till GC action.+                # Note: close() may raise if generator handles GeneratorExit.+                teardown.close()+            except StopIteration as si:+                result = si.value+                exception = None+                continue+            except BaseException as e:+                exception = e+                continue+            _raise_wrapfail(teardown, "has second yield") -            if exception is not None:-                raise exception.with_traceback(exception.__traceback__)-            else:-                return result--        # Slow path - need to support old-style wrappers.-        else:-            if firstresult:  # first result hooks return a single value-                outcome: Result[object | list[object]] = Result(-                    results[0] if results else None, exception-                )-            else:-                outcome = Result(results, exception)--            # run all wrapper post-yield blocks-            for teardown in reversed(teardowns):-                if isinstance(teardown, tuple):-                    try:-                        teardown[0].send(outcome)-                    except StopIteration:-                        pass-                    except BaseException as e:-                        _warn_teardown_exception(hook_name, teardown[1], e)-                        raise-                    else:-                        _raise_wrapfail(teardown[0], "has second yield")-                else:-                    try:-                        if outcome._exception is not None:-                            teardown.throw(outcome._exception)-                        else:-                            teardown.send(outcome._result)-                        # Following is unreachable for a well behaved hook wrapper.-                        # Try to force finalizers otherwise postponed till GC action.-                        # Note: close() may raise if generator handles GeneratorExit.-                        teardown.close()-                    except StopIteration as si:-                        outcome.force_result(si.value)-                        continue-                    except BaseException as e:-                        outcome.force_exception(e)-                        continue-                    _raise_wrapfail(teardown, "has second yield")--            return outcome.get_result()+    if exception is not None:+        raise exception+    else:+        return result
src/pluggy/_hooks.py +21 lines
--- +++ @@ -6,2 +6,6 @@ +from collections.abc import Generator+from collections.abc import Mapping+from collections.abc import Sequence+from collections.abc import Set import inspect@@ -9,3 +13,2 @@ from types import ModuleType-from typing import AbstractSet from typing import Any@@ -14,9 +17,4 @@ from typing import final-from typing import Generator-from typing import List-from typing import Mapping from typing import Optional from typing import overload-from typing import Sequence-from typing import Tuple from typing import TYPE_CHECKING@@ -36,3 +34,3 @@     [str, Sequence["HookImpl"], Mapping[str, object], bool],-    Union[object, List[object]],+    Union[object, list[object]], ]@@ -304,3 +302,3 @@             func = func.__init__-        except AttributeError:+        except AttributeError:  # pragma: no cover - pypy special case             return (), ()@@ -309,3 +307,3 @@             func = getattr(func, "__call__", func)-        except Exception:+        except Exception:  # pragma: no cover - pypy special case             return (), ()@@ -317,3 +315,3 @@         )-    except TypeError:+    except TypeError:  # pragma: no cover         return (), ()@@ -349,3 +347,3 @@         implicit_names: tuple[str, ...] = ("self",)-    else:+    else:  # pragma: no cover         implicit_names = ("self", "obj")@@ -378,3 +376,3 @@ -_CallHistory = List[Tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]+_CallHistory = list[tuple[Mapping[str, object], Optional[Callable[[Any], None]]]] @@ -487,3 +485,4 @@                         for argname in self.spec.argnames-                        # Avoid self.spec.argnames - kwargs.keys() - doesn't preserve order.+                        # Avoid self.spec.argnames - kwargs.keys()+                        # it doesn't preserve order.                         if argname not in kwargs.keys()@@ -491,4 +490,4 @@                     warnings.warn(-                        "Argument(s) {} which are declared in the hookspec "-                        "cannot be found in this hook call".format(notincall),+                        f"Argument(s) {notincall} which are declared in the hookspec "+                        "cannot be found in this hook call",                         stacklevel=2,@@ -506,5 +505,5 @@         """-        assert (-            not self.is_historic()-        ), "Cannot directly call a historic hook - use call_historic instead."+        assert not self.is_historic(), (+            "Cannot directly call a historic hook - use call_historic instead."+        )         self._verify_all_args_are_provided(kwargs)@@ -547,5 +546,5 @@         :ref:`call_extra`."""-        assert (-            not self.is_historic()-        ), "Cannot directly call a historic hook - use call_historic instead."+        assert not self.is_historic(), (+            "Cannot directly call a historic hook - use call_historic instead."+        )         self._verify_all_args_are_provided(kwargs)@@ -610,3 +609,3 @@ -    def __init__(self, orig: HookCaller, remove_plugins: AbstractSet[_Plugin]) -> None:+    def __init__(self, orig: HookCaller, remove_plugins: Set[_Plugin]) -> None:         self._orig = orig
src/pluggy/_manager.py +33 lines
--- +++ @@ -2,2 +2,5 @@ +from collections.abc import Iterable+from collections.abc import Mapping+from collections.abc import Sequence import inspect@@ -8,5 +11,2 @@ from typing import Final-from typing import Iterable-from typing import Mapping-from typing import Sequence from typing import TYPE_CHECKING@@ -72,3 +72,3 @@ -    def __getattr__(self, attr: str, default=None):+    def __getattr__(self, attr: str, default: Any | None = None) -> Any:         return getattr(self._dist, attr, default)@@ -140,4 +140,4 @@             raise ValueError(-                "Plugin name already registered: %s=%s\n%s"-                % (plugin_name, plugin, self._name2plugin)+                "Plugin name already registered: "+                f"{plugin_name}={plugin}\n{self._name2plugin}"             )@@ -146,4 +146,4 @@             raise ValueError(-                "Plugin already registered under a different name: %s=%s\n%s"-                % (plugin_name, plugin, self._name2plugin)+                "Plugin already registered under a different name: "+                f"{plugin_name}={plugin}\n{self._name2plugin}"             )@@ -190,7 +190,7 @@             )-        except Exception:-            res = {}  # type: ignore[assignment]+        except Exception:  # pragma: no cover+            res = {}  # type: ignore[assignment] #pragma: no cover         if res is not None and not isinstance(res, dict):             # false positive-            res = None  # type:ignore[unreachable]+            res = None  # type:ignore[unreachable] #pragma: no cover         return res@@ -331,4 +331,4 @@                 hookimpl.plugin,-                "Plugin %r\nhook %r\nhistoric incompatible with yield/wrapper/hookwrapper"-                % (hookimpl.plugin_name, hook.name),+                f"Plugin {hookimpl.plugin_name!r}\nhook {hook.name!r}\n"+                "historic incompatible with yield/wrapper/hookwrapper",             )@@ -344,11 +344,6 @@                 hookimpl.plugin,-                "Plugin %r for hook %r\nhookimpl definition: %s\n"-                "Argument(s) %s are declared in the hookimpl but "-                "can not be found in the hookspec"-                % (-                    hookimpl.plugin_name,-                    hook.name,-                    _formatdef(hookimpl.function),-                    notinspec,-                ),+                f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"+                f"hookimpl definition: {_formatdef(hookimpl.function)}\n"+                f"Argument(s) {notinspec} are declared in the hookimpl but "+                "can not be found in the hookspec",             )@@ -366,6 +361,6 @@                 hookimpl.plugin,-                "Plugin %r for hook %r\nhookimpl definition: %s\n"+                f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"+                f"hookimpl definition: {_formatdef(hookimpl.function)}\n"                 "Declared as wrapper=True or hookwrapper=True "-                "but function is not a generator function"-                % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)),+                "but function is not a generator function",             )@@ -375,5 +370,5 @@                 hookimpl.plugin,-                "Plugin %r for hook %r\nhookimpl definition: %s\n"-                "The wrapper=True and hookwrapper=True options are mutually exclusive"-                % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)),+                f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"+                f"hookimpl definition: {_formatdef(hookimpl.function)}\n"+                "The wrapper=True and hookwrapper=True options are mutually exclusive",             )@@ -385,12 +380,12 @@         for name in self.hook.__dict__:-            if name[0] != "_":-                hook: HookCaller = getattr(self.hook, name)-                if not hook.has_spec():-                    for hookimpl in hook.get_hookimpls():-                        if not hookimpl.optionalhook:-                            raise PluginValidationError(-                                hookimpl.plugin,-                                "unknown hook %r in plugin %r"-                                % (name, hookimpl.plugin),-                            )+            if name[0] == "_":+                continue+            hook: HookCaller = getattr(self.hook, name)+            if not hook.has_spec():+                for hookimpl in hook.get_hookimpls():+                    if not hookimpl.optionalhook:+                        raise PluginValidationError(+                            hookimpl.plugin,+                            f"unknown hook {name!r} in plugin {hookimpl.plugin!r}",+                        ) 
src/pluggy/_result.py +9 lines
--- +++ @@ -12,4 +12,2 @@ from typing import Optional-from typing import Tuple-from typing import Type from typing import TypeVar@@ -17,3 +15,3 @@ -_ExcInfo = Tuple[Type[BaseException], BaseException, Optional[TracebackType]]+_ExcInfo = tuple[type[BaseException], BaseException, Optional[TracebackType]] ResultType = TypeVar("ResultType")@@ -30,3 +28,3 @@ -    __slots__ = ("_result", "_exception")+    __slots__ = ("_result", "_exception", "_traceback") @@ -40,2 +38,4 @@         self._exception = exception+        # Exception __traceback__ is mutable, this keeps the original.+        self._traceback = exception.__traceback__ if exception is not None else None @@ -48,3 +48,3 @@         else:-            return (type(exc), exc, exc.__traceback__)+            return (type(exc), exc, self._traceback) @@ -77,2 +77,3 @@         self._exception = None+        self._traceback = None @@ -87,2 +88,3 @@         self._exception = exception+        self._traceback = exception.__traceback__ if exception is not None else None @@ -96,2 +98,3 @@         exc = self._exception+        tb = self._traceback         if exc is None:@@ -99,3 +102,3 @@         else:-            raise exc.with_traceback(exc.__traceback__)+            raise exc.with_traceback(tb) 
src/pluggy/_tracing.py +2 lines
--- +++ @@ -6,6 +6,5 @@ +from collections.abc import Sequence from typing import Any from typing import Callable-from typing import Sequence-from typing import Tuple @@ -13,3 +12,3 @@ _Writer = Callable[[str], object]-_Processor = Callable[[Tuple[str, ...], Tuple[Any, ...]], object]+_Processor = Callable[[tuple[str, ...], tuple[Any, ...]], object] 
src/pluggy/_version.py +9 lines
--- +++ @@ -1,6 +1,11 @@-# file generated by setuptools_scm+# file generated by setuptools-scm # don't change, don't track in version control++__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]+ TYPE_CHECKING = False if TYPE_CHECKING:-    from typing import Tuple, Union+    from typing import Tuple+    from typing import Union+     VERSION_TUPLE = Tuple[Union[int, str], ...]@@ -14,3 +19,3 @@ -__version__ = version = '1.5.0'-__version_tuple__ = version_tuple = (1, 5, 0)+__version__ = version = '1.6.0'+__version_tuple__ = version_tuple = (1, 6, 0)
testing/benchmark.py +6 lines
--- +++ @@ -3,2 +3,4 @@ """++from typing import Any @@ -28,3 +30,3 @@ @pytest.fixture(params=[10, 100], ids="hooks={}".format)-def hooks(request):+def hooks(request: Any) -> list[object]:     return [hook for i in range(request.param)]@@ -33,3 +35,3 @@ @pytest.fixture(params=[10, 100], ids="wrappers={}".format)-def wrappers(request):+def wrappers(request: Any) -> list[object]:     return [wrapper for i in range(request.param)]@@ -37,3 +39,3 @@ -def test_hook_and_wrappers_speed(benchmark, hooks, wrappers):+def test_hook_and_wrappers_speed(benchmark, hooks, wrappers) -> None:     def setup():@@ -67,3 +69,3 @@ )-def test_call_hook(benchmark, plugins, wrappers, nesting):+def test_call_hook(benchmark, plugins, wrappers, nesting) -> None:     pm = PluginManager("example")
testing/conftest.py +1 lines
--- +++ @@ -16,3 +16,3 @@         def he_method1(self, arg: int) -> int:-            return arg + 1+            return arg + 1  # pragma: no cover 
testing/test_details.py +65 lines
--- +++ @@ -1,3 +1,6 @@+from importlib.metadata import distribution+ import pytest +import pluggy from pluggy import HookimplMarker@@ -22,3 +25,3 @@         def x1meth(self):-            pass+            pass  # pragma: no cover @@ -35,3 +38,3 @@         def x1meth(self):-            pass+            pass  # pragma: no cover @@ -39,3 +42,3 @@         def x1meth2(self):-            pass+            pass  # pragma: no cover @@ -43,3 +46,3 @@         def x1meth3(self):-            pass+            pass  # pragma: no cover @@ -77,3 +80,3 @@         def foo(self):-            pass+            pass  # pragma: no cover @@ -82,3 +85,3 @@         def foo(self):-            pass+            pass  # pragma: no cover @@ -138,6 +141,8 @@     class Module:-        pass+        x: DontTouchMe      module = Module()-    module.x = DontTouchMe()  # type: ignore[attr-defined]+    module.x = DontTouchMe()+    with pytest.raises(Exception, match="touch me"):+        module.x.broken @@ -156,3 +161,3 @@         def hello(self, arg1, arg2):-            pass+            pass  # pragma: no cover @@ -160,3 +165,3 @@         def herstory(self, arg1, arg2):-            pass+            pass  # pragma: no cover @@ -191 +196,51 @@     )+++def test_dist_facade_list_attributes() -> None:+    from pluggy._manager import DistFacade++    fc = DistFacade(distribution("pluggy"))+    res = dir(fc)+    assert res == sorted(res)+    assert set(res) - set(dir(fc._dist)) == {"_dist", "project_name"}+++def test_hookimpl_disallow_invalid_combination() -> None:+    decorator = hookspec(historic=True, firstresult=True)+    with pytest.raises(ValueError, match="cannot have a historic firstresult hook"):+        decorator(any)+++def test_hook_nonspec_call(pm: PluginManager) -> None:+    class Plugin:+        @hookimpl+        def a_hook(self, passed: str, missing: int) -> None:+            pass++    pm.register(Plugin())+    with pytest.raises(+        pluggy.HookCallError, match="hook call must provide argument 'missing'"+    ):+        pm.hook.a_hook(passed="a")+    pm.hook.a_hook(passed="a", missing="ok")+++def test_wrapper_runtimeerror_passtrough(pm: PluginManager) -> None:+    """+    ensure runtime-error passes trough a wrapper in case of exceptions+    """++    class Fail:+        @hookimpl+        def fail_late(self):+            raise RuntimeError("this is personal")++    class Plugin:+        @hookimpl(wrapper=True)+        def fail_late(self):+            yield++    pm.register(Plugin())+    pm.register(Fail())+    with pytest.raises(RuntimeError, match="this is personal"):+        pm.hook.fail_late()
testing/test_helpers.py +4 lines
--- +++ @@ -12,3 +12,3 @@     def f(x) -> None:-        i = 3  # noqa+        i = 3  # noqa #pragma: no cover @@ -16,3 +16,3 @@         def f(self, y) -> None:-            pass+            pass  # pragma: no cover @@ -20,3 +20,3 @@         def __call__(self, z) -> None:-            pass+            pass  # pragma: no cover @@ -98,3 +98,3 @@         def wrapper(*args, **kwargs):-            return func(*args, **kwargs)+            return func(*args, **kwargs)  # pragma: no cover 
testing/test_hookcaller.py +17 lines
--- +++ @@ -1,5 +1,4 @@+from collections.abc import Generator+from collections.abc import Sequence from typing import Callable-from typing import Generator-from typing import List-from typing import Sequence from typing import TypeVar@@ -65,3 +64,3 @@ -def funcs(hookmethods: Sequence[HookImpl]) -> List[Callable[..., object]]:+def funcs(hookmethods: Sequence[HookImpl]) -> list[Callable[..., object]]:     return [hookmethod.function for hookmethod in hookmethods]@@ -161,3 +160,3 @@     def he_method1():-        yield+        yield  # pragma: no cover @@ -165,3 +164,3 @@     def he_method1_fun():-        yield+        yield  # pragma: no cover @@ -169,3 +168,3 @@     def he_method1_middle():-        return+        return  # pragma: no cover @@ -173,3 +172,3 @@     def he_method3_fun():-        yield+        yield  # pragma: no cover @@ -177,3 +176,3 @@     def he_method3():-        yield+        yield  # pragma: no cover @@ -191,3 +190,3 @@     def he_method1():-        yield+        yield  # pragma: no cover @@ -195,3 +194,3 @@     def he_method2():-        yield+        yield  # pragma: no cover @@ -199,3 +198,3 @@     def he_method3():-        yield+        yield  # pragma: no cover @@ -209,3 +208,3 @@     def m1():-        yield+        yield  # pragma: no cover @@ -230,3 +229,3 @@     def m5():-        yield+        yield  # pragma: no cover @@ -246,3 +245,3 @@     def m8():-        yield+        yield  # pragma: no cover @@ -267,3 +266,3 @@     def m12():-        yield+        yield  # pragma: no cover @@ -408,3 +407,3 @@         def foo(self, arg: int, too, many, args) -> int:-            return arg + 1+            return arg + 1  # pragma: no cover @@ -418,3 +417,3 @@         def hello(self, arg: int) -> int:-            return arg + 1+            return arg + 1  # pragma: no cover 
testing/test_invocations.py +43 lines
--- +++ @@ -1,2 +1,3 @@-from typing import Iterator+from collections.abc import Iterator+from typing import Any @@ -135,3 +136,3 @@         def hello(self, arg):-            return arg + 1+            return arg + 1  # pragma: no cover @@ -328 +329,41 @@     assert [y for x in res for y in x] == [2, 3, 1]++[email protected](+    "kind",+    [+        pytest.param(hookimpl(wrapper=True), id="wrapper"),+        pytest.param(hookimpl(hookwrapper=True), id="legacy-wrapper"),+    ],+)+def test_wrappers_yield_twice_fails(pm: PluginManager, kind: Any) -> None:+    class Plugin:+        @kind+        def wrap(self):+            yield+            yield++    pm.register(Plugin())+    with pytest.raises(+        RuntimeError, match="wrap_controller at 'wrap'.* has second yield"+    ):+        pm.hook.wrap()++[email protected](+    "kind",+    [+        pytest.param(hookimpl(wrapper=True), id="wrapper"),+        pytest.param(hookimpl(hookwrapper=True), id="legacy-wrapper"),+    ],+)+def test_wrappers_yield_never_fails(pm: PluginManager, kind: Any) -> None:+    class Plugin:+        @kind+        def wrap(self):+            if False:+                yield  # type: ignore[unreachable]++    pm.register(Plugin())+    with pytest.raises(RuntimeError, match="wrap_controller at 'wrap'.* did not yield"):+        pm.hook.wrap()
testing/test_multicall.py +40 lines
--- +++ @@ -1,6 +1,4 @@+from collections.abc import Mapping+from collections.abc import Sequence from typing import Callable-from typing import List-from typing import Mapping-from typing import Sequence-from typing import Type from typing import Union@@ -24,3 +22,3 @@     firstresult: bool = False,-) -> Union[object, List[object]]:+) -> Union[object, list[object]]:     caller = _multicall@@ -59,3 +57,3 @@     def f(x):-        return x+        return x  # pragma: no cover @@ -252,3 +250,3 @@ @pytest.mark.parametrize("exc", [ValueError, SystemExit])-def test_hookwrapper_exception(exc: "Type[BaseException]") -> None:+def test_hookwrapper_exception(exc: type[BaseException]) -> None:     out = []@@ -322,3 +320,3 @@ @pytest.mark.parametrize("exc", [ValueError, SystemExit])-def test_wrapper_exception(exc: "Type[BaseException]") -> None:+def test_wrapper_exception(exc: type[BaseException]) -> None:     out = []@@ -335,3 +333,3 @@             out.append("m1 finish")-        return result+        return result  # pragma: no cover @@ -362,3 +360,3 @@         yield-        return 10+        return 10  # pragma: no cover @@ -388,3 +386,3 @@             yield-            out.append("m1 unreachable")+            out.append("m1 unreachable")  # pragma: no cover         except BaseException:@@ -418,2 +416,32 @@ [email protected]("has_hookwrapper", [True, False])+def test_wrapper_stopiteration_passtrough(has_hookwrapper: bool) -> None:+    out = []++    @hookimpl(wrapper=True)+    def wrap():+        out.append("wrap")+        try:+            yield+        finally:+            out.append("wrap done")++    @hookimpl(wrapper=not has_hookwrapper, hookwrapper=has_hookwrapper)+    def wrap_path2():+        yield++    @hookimpl+    def stop():+        out.append("stop")+        raise StopIteration++    with pytest.raises(StopIteration):+        try:+            MC([stop, wrap, wrap_path2], {})+        finally:+            out.append("finally")++    assert out == ["wrap", "stop", "wrap done", "finally"]++ def test_suppress_inner_wrapper_teardown_exc() -> None:@@ -433,3 +461,3 @@             yield-            out.append("m2 unreachable")+            out.append("m2 unreachable")  # pragma: no cover         except ValueError:
testing/test_pluginmanager.py +72 lines
--- +++ @@ -6,3 +6,2 @@ from typing import Any-from typing import List @@ -68,5 +67,7 @@                 return 42-            raise AttributeError()+            raise AttributeError(name)      a = A()+    a.test+     he_pm.register(a)@@ -129,3 +130,3 @@         def he_method_notexists(self):-            pass+            pass  # pragma: no cover @@ -143,3 +144,3 @@         def he_method1(self, qlwkje):-            pass+            pass  # pragma: no cover @@ -183,3 +184,3 @@         @hookimpl-        def he_method1(self): ...+        def he_method1(self): ...  # pragma: no cover @@ -202,2 +203,14 @@ +def test_unregister_blocked(pm: PluginManager) -> None:+    class Plugin:+        pass++    p = Plugin()+    pm.set_blocked("error")+    pm.register(p, "error")+    # bloked plugins can be unregistred many times atm+    pm.unregister(p, "error")+    pm.unregister(p, "error")++ def test_register_unknown_hooks(pm: PluginManager) -> None:@@ -213,4 +226,3 @@         @hookspec-        def he_method1(self, arg):-            pass+        def he_method1(self, arg): ... @@ -227,4 +239,3 @@         @hookspec(historic=True)-        def he_method1(self, arg):-            pass+        def he_method1(self, arg): ... @@ -376,3 +387,3 @@         def he_method1(self, arg):-            out.append(arg)+            out.append(arg)  # pragma: no cover @@ -393,3 +404,3 @@         def he_method1(self, arg):-            yield+            yield  # pragma: no cover @@ -428,2 +439,5 @@     pm.register(Plugin1())+    with pytest.raises(ZeroDivisionError):+        pm.hook.he_method1(arg="works")+     with pytest.raises(HookCallError):@@ -608,3 +622,3 @@ def test_add_tracefuncs(he_pm: PluginManager) -> None:-    out: List[Any] = []+    out: list[Any] = [] @@ -661,3 +675,3 @@     he_pm.register(api1())-    out: List[Any] = []+    out: list[Any] = []     he_pm.trace.root.setwriter(out.append)@@ -757 +771,46 @@         assert result == [4, 5, 3, 2, 1, 6]+++def test_check_pending_skips_underscore(pm: PluginManager) -> None:+    # todo: determine what we want to do with the namespace+    class Plugin:+        @hookimpl+        def _problem(self):+            pass++    pm.register(Plugin())+    pm.hook._problem()+    pm.check_pending()+++def test_check_pending_optionalhook(+    pm: PluginManager,+) -> None:+    class Plugin:+        @hookimpl(optionalhook=True)+        def a_hook(self, param):+            pass++    pm.register(Plugin())+    pm.hook.a_hook(param=1)+    pm.check_pending()+++def test_check_pending_nonspec_hook(+    pm: PluginManager,+) -> None:+    hookimpl = HookimplMarker("example")++    class Plugin:+        @hookimpl+        def a_hook(self, param):+            pass++    pm.register(Plugin())+    with pytest.raises(HookCallError, match="hook call must provide argument 'param'"):+        pm.hook.a_hook()++    with pytest.raises(+        PluginValidationError, match="unknown hook 'a_hook' in plugin .*"+    ):+        pm.check_pending()
testing/test_result.py +27 lines
--- +++ @@ -0,0 +1,27 @@+import traceback++from pluggy import Result+++def test_exceptions_traceback_doesnt_get_longer_and_longer() -> None:+    def bad() -> None:+        1 / 0++    result = Result.from_call(bad)++    try:+        result.get_result()+    except Exception as exc:+        tb1 = traceback.extract_tb(exc.__traceback__)++    try:+        result.get_result()+    except Exception as exc:+        tb2 = traceback.extract_tb(exc.__traceback__)++    try:+        result.get_result()+    except Exception as exc:+        tb3 = traceback.extract_tb(exc.__traceback__)++    assert len(tb1) == len(tb2) == len(tb3)
testing/test_tracer.py +1 lines
--- +++ @@ -1,3 +1 @@-from typing import List- import pytest@@ -15,3 +13,3 @@     log("hello")-    out: List[str] = []+    out: list[str] = []     rootlogger.setwriter(out.append)
pydantic pypi
2.13.4 3mo ago incident on record
YANK ×2BURST ×4
latest 2.13.4 versions 204 maintainers 1
2.12.1
2.12.2
2.12.3
2.12.4
2.12.5
1.10.25
1.10.26
2.13.0
2.13.1
2.13.2
2.13.3
2.13.4
YANK
1.10.3 marked yanked (still downloadable)
high · registry-verified · 2022-12-29 · 3y ago
YANK
2.12.1 marked yanked (still downloadable)
high · registry-verified · 2025-10-13 · 10mo ago
BURST
2 releases in 50m: 0.2, 0.2.1
info · registry-verified · 2017-06-07 · 9y ago
BURST
3 releases in 56m: 1.6.2, 1.7.4, 1.8.2
info · registry-verified · 2021-05-11 · 5y ago
BURST
2 releases in 4m: 1.10.11, 2.0.1
info · registry-verified · 2023-07-04 · 3y ago
BURST
2 releases in 59m: 2.11.8, 1.10.23
info · registry-verified · 2025-09-13 · 11mo ago
release diff 2.13.3 → 2.13.4
+0 added · -0 removed · ~10 modified
pydantic/_internal/_generate_schema.py +12 lines
--- +++ @@ -842,4 +842,13 @@                 if cls.__pydantic_root_model__:-                    # FIXME: should the common field metadata be used here?-                    inner_schema, _ = self._common_field_schema('root', fields['root'], decorators)+                    inner_schema, metadata = self._common_field_schema('root', fields['root'], decorators)+                    if cls.__doc__ and metadata.get('pydantic_js_updates', {}).get('description'):+                        # This is a bit of a leaky abstraction, but as the model docstring takes priority+                        # over the root field's description, we need to override it here. This can't be done+                        # in the JSON Schema generation logic because the metadata's `pydantic_js_updates` are+                        # applied last, and overrides any value previously set (so the description set from the+                        # docstring in `GenerateJsonSchema._update_class_schema()` is overridden):+                        update_core_metadata(+                            metadata, pydantic_js_updates={'description': inspect.cleandoc(cls.__doc__)}+                        )+                     inner_schema = apply_model_validators(inner_schema, model_validators, 'inner')@@ -854,2 +863,3 @@                         ref=model_ref,+                        metadata=metadata,                     )
pydantic/json_schema.py +0 lines
--- +++ @@ -1638,3 +1638,2 @@         from .main import BaseModel-        from .root_model import RootModel @@ -1666,4 +1665,2 @@             json_schema.setdefault('description', inspect.cleandoc(docstring))-        elif issubclass(cls, RootModel) and (root_description := cls.__pydantic_fields__['root'].description):-            json_schema.setdefault('description', root_description) 
pydantic/version.py +2 lines
--- +++ @@ -10,3 +10,3 @@ -VERSION = '2.13.3'+VERSION = '2.13.4' """The version of Pydantic.@@ -21,3 +21,3 @@ # Keep this in sync with the version constraint in the `pyproject.toml` dependencies:-_COMPATIBLE_PYDANTIC_CORE_VERSION = '2.46.3'+_COMPATIBLE_PYDANTIC_CORE_VERSION = '2.46.4' 
pyproject.toml +1 lines
--- +++ @@ -49,3 +49,3 @@     # Keep this in sync with the version in the `check_pydantic_core_version()` function:-    'pydantic-core==2.46.3',+    'pydantic-core==2.46.4',     'typing-inspection>=0.4.2',
tests/test_json_schema.py +32 lines
--- +++ @@ -5393,2 +5393,34 @@ +def test_root_model_annotated_root_type_parameterized() -> None:+    """https://github.com/pydantic/pydantic/issues/13123"""++    MyType = Annotated[str, Field(examples=['hello'], description='desc', deprecated=True)]++    class MyModel(RootModel[MyType]):+        pass++    assert MyModel.model_json_schema() == {+        'deprecated': True,+        'description': 'desc',+        'examples': ['hello'],+        'title': 'MyModel',+        'type': 'string',+    }+++def test_root_model_annotated_root_type() -> None:+    """https://github.com/pydantic/pydantic/issues/13123"""++    class MyModel(RootModel):+        root: Annotated[str, Field(examples=['hello'], description='desc', deprecated=True)]++    assert MyModel.model_json_schema() == {+        'deprecated': True,+        'description': 'desc',+        'examples': ['hello'],+        'title': 'MyModel',+        'type': 'string',+    }++ def test_type_adapter_json_schemas_title_description():
tests/test_main.py +1 lines
--- +++ @@ -2012,7 +2012,3 @@ def test_class_kwargs_custom_config():-    if platform.python_implementation() == 'PyPy':-        msg = r"__init_subclass__\(\) got an unexpected keyword argument 'some_config'"-    else:-        msg = r'__init_subclass__\(\) takes no keyword arguments'-    with pytest.raises(TypeError, match=msg):+    with pytest.raises(TypeError, match=r'__init_subclass__\(\) takes no keyword arguments'): 
tests/test_missing_sentinel.py +6 lines
--- +++ @@ -4,2 +4,3 @@ import pytest+import typing_extensions from annotated_types import Ge@@ -55,3 +56,7 @@ [email protected](reason="PEP 661 sentinels aren't picklable yet in the experimental typing-extensions implementation")[email protected](+    # Unreleased typing-extensions has the final sentinel implementation with pickle support:+    condition=not hasattr(typing_extensions, 'sentinel'),+    reason="PEP 661 sentinels aren't picklable yet in the experimental typing-extensions implementation",+) def test_missing_sentinel_pickle() -> None:
tests/test_pickle.py +25 lines
--- +++ @@ -8,3 +8,3 @@ from textwrap import dedent-from typing import Optional+from typing import TYPE_CHECKING, Optional @@ -17,6 +17,14 @@ -try:+IS_PYPY = sys.implementation.name == 'pypy' and sys.version_info >= (3, 11)++if TYPE_CHECKING:     import cloudpickle-except ImportError:-    cloudpickle = None+else:+    if not IS_PYPY:+        try:+            import cloudpickle+        except ImportError:+            cloudpickle = None+    else:+        cloudpickle = None @@ -24,6 +32,12 @@ -pytestmark = pytest.mark.skipif(cloudpickle is None, reason='cloudpickle is not installed')-+pytestmark = pytest.mark.skipif(+    cloudpickle is None,+    reason='cloudpickle is not installed, or tests are running with PyPy (https://github.com/cloudpipe/cloudpickle/issues/592).',+)++# Note: this xfail marker was used when cloudpickle was partially compatible with PyPy. Since PyPy 7.3.22, it isn't compatible+# at all (importing it fails), so all tests are skipped as per the module's `pytestmark`. We keep the xfail marker if this ever+# changes: cloudpickle_pypy_xfail = pytest.mark.xfail(-    condition=sys.implementation.name == 'pypy' and sys.version_info >= (3, 11),+    condition=IS_PYPY,     reason='Cloudpickle issue: - possibly https://github.com/cloudpipe/cloudpickle/issues/557',@@ -101,3 +115,6 @@         (ImportableModel, True),-        # Locally-defined model can only be pickled with cloudpickle.+        # Locally-defined model can only be pickle+        # # Note: this xfail marker was used when cloudpickle was partially compatible with PyPy. Since PyPy 7.3.22, it is completelyisn't compatible+        # # at all (importing it fails), so all tests are skipped as per the module's `pytestmark`. We keep the xfail marker if this ever+        # # changes:d with cloudpickle.         pytest.param(model_factory(), True, marks=cloudpickle_pypy_xfail),
pydantic-core pypi
2.48.0 15d ago incident on record
YANK ×3BURST
latest 2.48.0 versions 157 maintainers 1
2.41.5
2.42.0
2.43.0
2.44.0
2.45.0
2.46.0
2.46.1
2.46.2
2.46.3
2.46.4
2.47.0
2.48.0
YANK
2.41.3 marked yanked (still downloadable)
high · registry-verified · 2025-10-13 · 10mo ago
YANK
2.43.0 marked yanked (still downloadable)
high · registry-verified · 2026-03-27 · 4mo ago
YANK
2.44.0 marked yanked (still downloadable)
high · registry-verified · 2026-03-27 · 4mo ago
BURST
2 releases in 44m: 2.6.2, 2.6.3
info · registry-verified · 2023-08-23 · 2y ago
release diff 2.47.0 → 2.48.0
+6 added · -3 removed · ~63 modified
Cargo.toml +8 lines
--- +++ @@ -2,3 +2,3 @@ name = "pydantic-core"-version = "2.47.0"+version = "2.48.0" edition = "2024"@@ -29,5 +29,5 @@ # but needs a bit of work to make sure it's not used in the codebase-pyo3 = { version = "0.28", features = ["generate-import-lib", "num-bigint", "py-clone", "smallvec"] }+pyo3 = { version = "0.29.2", features = ["num-bigint", "py-clone", "smallvec"] } regex = "1.12.3"-lru = "0.16.3"+lru = "0.18.0" strum = { version = "0.27", features = ["derive"] }@@ -46,7 +46,7 @@ num-traits = "0.2.19"-uuid = "1.23.0"-jiter = { version = "0.14.0", features = ["python"] }+uuid = "1.23.2"+jiter = { version = "0.16.0", features = ["python"] } hex = "0.4.3" percent-encoding = "2.3.2"-hashbrown = { version = "0.16", default-features = false, features = ["inline-more"] }+hashbrown = { version = "0.17", default-features = false, features = ["inline-more"] } @@ -73,3 +73,3 @@ [dev-dependencies]-pyo3 = { version = "0.28", features = ["auto-initialize"] }+pyo3 = { version = "0.29", features = ["auto-initialize"] } @@ -78,3 +78,3 @@ # used where logic has to be version/distribution specific, e.g. pypy-pyo3-build-config = { version = "0.28" }+pyo3-build-config = { version = "0.29" } 
pyproject.toml +4 lines
--- +++ @@ -160,7 +160,8 @@     { file = "pyproject.toml" },-    { file = "setup.py" },-    { file = "setup.cfg" },     { file = "Cargo.toml" },     { file = "Cargo.lock" },-    { file = "**/*.rs" },+    { file = "build.rs" },+    { dir = ".cargo" },+    { dir = "src" },+    { dir = "python" },     { env = "MATURIN_PEP517_ARGS" },
python/pydantic_core/core_schema.py +197 lines
--- +++ @@ -12,2 +12,3 @@ from decimal import Decimal+from fractions import Fraction from re import Pattern@@ -836,2 +837,60 @@ +class FractionSchema(TypedDict, total=False):+    type: Required[Literal['fraction']]+    le: Fraction+    ge: Fraction+    lt: Fraction+    gt: Fraction+    strict: bool+    ref: str+    metadata: dict[str, Any]+    serialization: SerSchema+++def fraction_schema(+    *,+    le: Fraction | None = None,+    ge: Fraction | None = None,+    lt: Fraction | None = None,+    gt: Fraction | None = None,+    strict: bool | None = None,+    ref: str | None = None,+    metadata: dict[str, Any] | None = None,+    serialization: SerSchema | None = None,+) -> FractionSchema:+    """+    Returns a schema that matches a fraction value, e.g.:++    ```py+    from fractions import Fraction+    from pydantic_core import SchemaValidator, core_schema++    schema = core_schema.fraction_schema(le=Fraction(3, 4), ge=Fraction(1, 4))+    v = SchemaValidator(schema)+    assert v.validate_python('1/2') == Fraction(1, 2)+    ```++    Args:+        le: The value must be less than or equal to this number+        ge: The value must be greater than or equal to this number+        lt: The value must be strictly less than this number+        gt: The value must be strictly greater than this number+        strict: Whether the value should be a Fraction or a value that can be converted to a Fraction+        ref: optional unique identifier of the schema, used to reference the schema in other places+        metadata: Any other information you want to include with the schema, not used by pydantic-core+        serialization: Custom serialization schema+    """+    return _dict_not_none(+        type='fraction',+        gt=gt,+        ge=ge,+        lt=lt,+        le=le,+        strict=strict,+        ref=ref,+        metadata=metadata,+        serialization=serialization,+    )++ class ComplexSchema(TypedDict, total=False):@@ -1391,2 +1450,21 @@         type='missing-sentinel',+        metadata=metadata,+        serialization=serialization,+    )+++class EllipsisSchema(TypedDict, total=False):+    type: Required[Literal['ellipsis']]+    metadata: dict[str, Any]+    serialization: SerSchema+++def ellipsis_schema(+    metadata: dict[str, Any] | None = None,+    serialization: SerSchema | None = None,+) -> EllipsisSchema:+    """Returns a schema for the [`Ellipsis`][] literal."""++    return _dict_not_none(+        type='ellipsis',         metadata=metadata,@@ -3513,2 +3591,108 @@ +class NamedTupleField(TypedDict, total=False):+    type: Required[Literal['named-tuple-field']]+    name: Required[str]+    schema: Required[CoreSchema]+    validation_alias: str | list[str | int] | list[list[str | int]]+    metadata: dict[str, Any]+++def named_tuple_field(+    name: str,+    schema: CoreSchema,+    *,+    validation_alias: str | list[str | int] | list[list[str | int]] | None = None,+    metadata: dict[str, Any] | None = None,+) -> NamedTupleField:+    """+    Returns a schema for a named tuple field, e.g.:++    ```py+    from pydantic_core import core_schema++    field = core_schema.named_tuple_field(name='x', schema=core_schema.int_schema())+    ```++    Args:+        name: The name of the field+        schema: The schema to use for the field+        validation_alias: The alias(es) to use to find the field in the validation data, only used+            when validating from a dictionary or mapping+        metadata: Any other information you want to include with the schema, not used by pydantic-core+    """+    return _dict_not_none(+        type='named-tuple-field',+        name=name,+        schema=schema,+        validation_alias=validation_alias,+        metadata=metadata,+    )+++class NamedTupleSchema(TypedDict, total=False):+    type: Required[Literal['named-tuple']]+    cls: Required[type[Any]]+    fields: Required[list[NamedTupleField]]+    cls_name: str+    ref: str+    metadata: dict[str, Any]+    serialization: SerSchema+++def named_tuple_schema(+    cls: type[Any],+    fields: list[NamedTupleField],+    *,+    cls_name: str | None = None,+    ref: str | None = None,+    metadata: dict[str, Any] | None = None,+    serialization: SerSchema | None = None,+) -> NamedTupleSchema:+    """+    Returns a schema for a named tuple, e.g.:++    ```py+    from typing import NamedTuple++    from pydantic_core import SchemaValidator, core_schema++    class Point(NamedTuple):+        x: int+        y: int++    schema = core_schema.named_tuple_schema(+        Point,+        [+            core_schema.named_tuple_field(name='x', schema=core_schema.int_schema()),+            core_schema.named_tuple_field(name='y', schema=core_schema.int_schema()),+        ],+    )+    v = SchemaValidator(schema)+    assert v.validate_python((1, '2')) == Point(x=1, y=2)+    ```++    Fields are validated positionally when the input is a (named) tuple, list or JSON array,+    and by name when the input is a dictionary, mapping or JSON object. Instances of `cls`+    always revalidate. Strict mode is currently ignored, matching the behavior of the+    `'call'` core schema previously used for named tuples.++    Args:+        cls: The named tuple class, used to construct instances and perform instance checks+        fields: The fields to use for the named tuple, in order+        cls_name: The name to use in error locs, etc; this is useful for generics (default: `cls.__name__`)+        ref: optional unique identifier of the schema, used to reference the schema in other places+        metadata: Any other information you want to include with the schema, not used by pydantic-core+        serialization: Custom serialization schema+    """+    return _dict_not_none(+        type='named-tuple',+        cls=cls,+        fields=fields,+        cls_name=cls_name,+        ref=ref,+        metadata=metadata,+        serialization=serialization,+    )++ class ArgumentsParameter(TypedDict, total=False):@@ -4135,2 +4319,3 @@         | DecimalSchema+        | FractionSchema         | StringSchema@@ -4143,2 +4328,3 @@         | MissingSentinelSchema+        | EllipsisSchema         | EnumSchema@@ -4169,2 +4355,3 @@         | DataclassSchema+        | NamedTupleSchema         | ArgumentsSchema@@ -4194,2 +4381,3 @@     'decimal',+    'fraction',     'str',@@ -4202,2 +4390,3 @@     'missing-sentinel',+    'ellipsis',     'enum',@@ -4228,2 +4417,3 @@     'dataclass',+    'named-tuple',     'arguments',@@ -4241,3 +4431,5 @@ -CoreSchemaFieldType: TypeAlias = Literal['model-field', 'dataclass-field', 'typed-dict-field', 'computed-field']+CoreSchemaFieldType: TypeAlias = Literal[+    'model-field', 'dataclass-field', 'typed-dict-field', 'named-tuple-field', 'computed-field'+] @@ -4262,2 +4454,3 @@     'dataclass_exact_type',+    'named_tuple_type',     'default_factory_not_called',@@ -4304,2 +4497,3 @@     'missing_sentinel_error',+    'ellipsis_error',     'date_type',@@ -4349,2 +4543,4 @@     'decimal_whole_digits',+    'fraction_type',+    'fraction_parsing',     'complex_type',
tests/benchmarks/test_micro_benchmarks.py +34 lines
--- +++ @@ -41,3 +41,4 @@     @pytest.fixture(scope='class')-    def core_validator_fs(self):+    @classmethod+    def core_validator_fs(cls):         class CoreModel:@@ -83,3 +84,4 @@     @pytest.fixture(scope='class')-    def core_model_validator(self):+    @classmethod+    def core_model_validator(cls):         class CoreModel:@@ -569,3 +571,4 @@     @pytest.fixture(scope='class')-    def core_validator(self):+    @classmethod+    def core_validator(cls):         class CoreModel:@@ -583,3 +586,4 @@     @pytest.fixture(scope='class')-    def datetime_raw(self):+    @classmethod+    def datetime_raw(cls):         return datetime.now(timezone.utc) + timedelta(days=1)@@ -587,3 +591,4 @@     @pytest.fixture(scope='class')-    def datetime_str(self, datetime_raw):+    @classmethod+    def datetime_str(cls, datetime_raw):         return str(datetime_raw)@@ -591,3 +596,4 @@     @pytest.fixture(scope='class')-    def python_data_dict(self, datetime_raw):+    @classmethod+    def python_data_dict(cls, datetime_raw):         return {'dt': datetime_raw}@@ -595,3 +601,4 @@     @pytest.fixture(scope='class')-    def json_dict_data(self, datetime_str):+    @classmethod+    def json_dict_data(cls, datetime_str):         return json.dumps({'dt': datetime_str})@@ -633,3 +640,4 @@     @pytest.fixture(scope='class')-    def validator(self):+    @classmethod+    def validator(cls):         return SchemaValidator(core_schema.date_schema())@@ -714,3 +722,4 @@     @pytest.fixture(scope='class')-    def core_validator(self):+    @classmethod+    def core_validator(cls):         class CoreModel:@@ -728,3 +737,4 @@     @pytest.fixture(scope='class')-    def validator(self):+    @classmethod+    def validator(cls):         return SchemaValidator(core_schema.uuid_schema())@@ -732,3 +742,4 @@     @pytest.fixture(scope='class')-    def pydantic_validator(self):+    @classmethod+    def pydantic_validator(cls):         def to_UUID(v: Any) -> UUID:@@ -782,3 +793,4 @@     @pytest.fixture(scope='class')-    def uuid_raw(self):+    @classmethod+    def uuid_raw(cls):         return UUID('12345678-1234-5678-1234-567812345678')@@ -786,3 +798,4 @@     @pytest.fixture(scope='class')-    def uuid_str(self, uuid_raw):+    @classmethod+    def uuid_str(cls, uuid_raw):         return str(uuid_raw)@@ -790,3 +803,4 @@     @pytest.fixture(scope='class')-    def python_data_dict(self, uuid_raw):+    @classmethod+    def python_data_dict(cls, uuid_raw):         return {'u': uuid_raw}@@ -794,3 +808,4 @@     @pytest.fixture(scope='class')-    def json_dict_data(self, uuid_str):+    @classmethod+    def json_dict_data(cls, uuid_str):         return json.dumps({'u': uuid_str})@@ -1363,3 +1378,4 @@     @pytest.fixture(scope='class')-    def validator(self):+    @classmethod+    def validator(cls):         return SchemaValidator(core_schema.decimal_schema())@@ -1367,3 +1383,4 @@     @pytest.fixture(scope='class')-    def pydantic_validator(self):+    @classmethod+    def pydantic_validator(cls):         Decimal = decimal.Decimal
tests/benchmarks/test_serialization_micro.py +6 lines
--- +++ @@ -12,3 +12,4 @@     @pytest.fixture(scope='class')-    def core_schema(self):+    @classmethod+    def core_schema(cls):         class CoreModel:@@ -34,3 +35,4 @@     @pytest.fixture(scope='class')-    def core_validator(self, core_schema):+    @classmethod+    def core_validator(cls, core_schema):         return SchemaValidator(core_schema)@@ -38,3 +40,4 @@     @pytest.fixture(scope='class')-    def core_serializer(self, core_schema):+    @classmethod+    def core_serializer(cls, core_schema):         return SchemaSerializer(core_schema)
tests/serializers/test_bytes.py +1 lines
--- +++ @@ -171,3 +171,3 @@     # assert doesn't override serializer config-    # in V3, we can change the serialization settings provided to to_json to override model config settings,+    # in V3, we can change the serialization settings provided to the to_json function to override model config settings,     # but that'd be a breaking change
tests/serializers/test_datetime.py +57 lines
--- +++ @@ -1,2 +1,3 @@ from datetime import date, datetime, time, timedelta, timezone+from typing import Literal @@ -197,2 +198,58 @@ @pytest.mark.parametrize(+    ['dt', 'expected', 'expected_json', 'expected_key', 'mode'],+    [+        (datetime(2026, 1, 1, tzinfo=timezone.utc), 1767225600.0, b'1767225600.0', '1767225600', 'seconds'),+        (+            datetime(2026, 1, 1, tzinfo=timezone.utc),+            1767225600000.0,+            b'1767225600000.0',+            '1767225600000',+            'milliseconds',+        ),+        (datetime(2026, 1, 1, tzinfo=tz(hours=-5)), 1767243600.0, b'1767243600.0', '1767243600', 'seconds'),+        (+            datetime(2026, 1, 1, tzinfo=tz(hours=-5)),+            1767243600000.0,+            b'1767243600000.0',+            '1767243600000',+            'milliseconds',+        ),+        (datetime(2026, 1, 1, tzinfo=tz(hours=2, minutes=30)), 1767216600.0, b'1767216600.0', '1767216600', 'seconds'),+        (+            datetime(2026, 1, 1, 1, 1, 1, 23, tzinfo=tz(hours=-5)),+            1767247261.000023,+            b'1767247261.000023',+            '1767247261.000023',+            'seconds',+        ),+        (+            datetime(2026, 1, 1, 1, 1, 1, 23, tzinfo=tz(hours=-5)),+            1767247261000.023,+            b'1767247261000.023',+            '1767247261000.023',+            'milliseconds',+        ),+    ],+)+def test_config_datetime_tz_aware(+    dt: datetime, expected: float, expected_json: bytes, expected_key: str, mode: Literal['seconds', 'milliseconds']+):+    """https://github.com/pydantic/pydantic/issues/13423"""+    if mode == 'seconds':+        assert expected == dt.timestamp()++    s = SchemaSerializer(core_schema.datetime_schema(), config={'ser_json_temporal': mode})+    assert s.to_python(dt) == dt+    assert s.to_python(dt, mode='json') == expected+    assert s.to_json(dt) == expected_json++    key_s = SchemaSerializer(+        core_schema.dict_schema(core_schema.datetime_schema(), core_schema.str_schema()),+        config={'ser_json_temporal': mode},+    )+    assert key_s.to_python({dt: 'foo'}, mode='json') == {expected_key: 'foo'}+    assert key_s.to_json({dt: 'foo'}) == f'{{"{expected_key}":"foo"}}'.encode()++[email protected](     'dt,expected_to_python,expected_to_json,expected_to_python_dict,expected_to_json_dict,mode',
tests/test_build.py +0 lines
--- +++ @@ -6,7 +6,2 @@ from pydantic_core import core_schema as cs---def test_schema_as_string():-    v = SchemaValidator(cs.bool_schema())-    assert v.validate_python('tRuE') is True 
tests/test_docstrings.py +2 lines
--- +++ @@ -20,3 +20,3 @@ @pytest.mark.parametrize(-    'example', find_examples(str(PYDANTIC_CORE_DIR / 'python/pydantic_core/core_schema.py')), ids=str+    'example', list(find_examples(str(PYDANTIC_CORE_DIR / 'python/pydantic_core/core_schema.py'))), ids=str )@@ -35,3 +35,3 @@ @pytest.mark.skipif(CodeExample is None or sys.platform not in {'linux', 'darwin'}, reason='Only on linux and macos')[email protected]('example', find_examples(str(PYDANTIC_CORE_DIR / 'README.md')), ids=str)[email protected]('example', list(find_examples(str(PYDANTIC_CORE_DIR / 'README.md'))), ids=str) @pytest.mark.thread_unsafe  # TODO investigate why pytest_examples seems to be thread unsafe here
tests/test_errors.py +9 lines
--- +++ @@ -109,3 +109,3 @@ -    with pytest.raises(TypeError, match="argument 'context': 'list' object is not an instance of 'dict'"):+    with pytest.raises(TypeError, match="'list' object is not an instance of 'dict'"):         v.validate_python(42)@@ -269,2 +269,7 @@     ('dataclass_type', 'Input should be a dictionary or an instance of Foobar', {'class_name': 'Foobar'}),+    (+        'named_tuple_type',+        'Input should be a tuple, list, dictionary or an instance of Foobar',+        {'class_name': 'Foobar'},+    ),     (@@ -349,2 +354,3 @@     ('missing_sentinel_error', "Input should be the 'MISSING' sentinel", None),+    ('ellipsis_error', "Input should be the 'Ellipsis' literal", None),     ('date_type', 'Input should be a valid date', None),@@ -396,2 +402,4 @@     ('decimal_parsing', 'Input should be a valid decimal', None),+    ('fraction_type', 'Fraction input should be an integer, float, string or Fraction object', None),+    ('fraction_parsing', 'Input is not a valid fraction', None),     ('decimal_max_digits', 'Decimal input should have no more than 42 digits in total', {'max_digits': 42}),
tests/test_isinstance.py +1 lines
--- +++ @@ -2,6 +2,4 @@ -from pydantic_core import PydanticOmit, SchemaError, SchemaValidator, ValidationError, core_schema+from pydantic_core import SchemaValidator, ValidationError from pydantic_core import core_schema as cs--from .conftest import PyAndJson @@ -39,35 +37 @@     assert v.isinstance_python({'f': 'x', 'extra_field': '123'}, extra='forbid') is False---def test_internal_error():-    v = SchemaValidator(-        cs.model_schema(cls=int, schema=cs.model_fields_schema(fields={'f': cs.model_field(schema=cs.int_schema())}))-    )-    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):-        v.validate_python({'f': 123})--    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):-        v.validate_json('{"f": 123}')--    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):-        v.isinstance_python({'f': 123})---def test_omit(py_and_json: PyAndJson):-    def omit(v, info):-        if v == 'omit':-            raise PydanticOmit-        elif v == 'error':-            raise ValueError('error')-        else:-            return v--    v = py_and_json(core_schema.with_info_plain_validator_function(omit))-    assert v.validate_test('foo') == 'foo'-    if v.validator_type == 'python':-        assert v.isinstance_test('foo') is True--    if v.validator_type == 'python':-        assert v.isinstance_test('error') is False-    with pytest.raises(SchemaError, match='Uncaught Omit error, please check your usage of `default` validators.'):-        v.validate_test('omit')
tests/test_json.py +5 lines
--- +++ @@ -1,7 +1,5 @@-import json import platform-import re  import pytest-from dirty_equals import IsFloatNan, IsList+from dirty_equals import IsList @@ -19,195 +17,2 @@ )--from .conftest import Err--[email protected](-    'input_value,output_value',-    [('false', False), ('true', True), ('0', False), ('1', True), ('"yes"', True), ('"no"', False)],-)-def test_bool(input_value, output_value):-    v = SchemaValidator(core_schema.bool_schema())-    assert v.validate_json(input_value) == output_value--[email protected](-    'input_value',-    [-        pytest.param('[1, 2, 3]', id='[1, 2, 3]_list'),-        pytest.param(b'[1, 2, 3]', id='[1, 2, 3]_bytes'),-        pytest.param(bytearray(b'[1, 2, 3]'), id='[1, 2, 3]_bytearray'),-    ],-)-def test_input_types(input_value):-    v = SchemaValidator(core_schema.list_schema(items_schema=core_schema.int_schema()))-    assert v.validate_json(input_value) == [1, 2, 3]---def test_input_type_invalid():-    v = SchemaValidator(core_schema.list_schema(items_schema=core_schema.int_schema()))-    with pytest.raises(ValidationError, match=r'JSON input should be string, bytes or bytearray \[type=json_type,'):-        v.validate_json([])---def test_null():-    assert SchemaValidator(core_schema.none_schema()).validate_json('null') is None---def test_str():-    s = SchemaValidator(core_schema.str_schema())-    assert s.validate_json('"foobar"') == 'foobar'-    with pytest.raises(ValidationError, match=r'Input should be a valid string \[type=string_type,'):-        s.validate_json('false')-    with pytest.raises(ValidationError, match=r'Input should be a valid string \[type=string_type,'):-        s.validate_json('123')---def test_bytes():-    s = SchemaValidator(core_schema.bytes_schema())-    assert s.validate_json('"foobar"') == b'foobar'-    with pytest.raises(ValidationError, match=r'Input should be a valid bytes \[type=bytes_type,'):-        s.validate_json('false')-    with pytest.raises(ValidationError, match=r'Input should be a valid bytes \[type=bytes_type,'):-        s.validate_json('123')---# A number well outside of i64 range-_BIG_NUMBER_STR = '1' + ('0' * 40)--[email protected](-    'input_value,expected',-    [-        ('123', 123),-        ('"123"', 123),-        ('123.0', 123),-        ('"123.0"', 123),-        (_BIG_NUMBER_STR, int(_BIG_NUMBER_STR)),-        ('123.4', Err('Input should be a valid integer, got a number with a fractional part [type=int_from_float,')),-        ('"123.4"', Err('Input should be a valid integer, unable to parse string as an integer [type=int_parsing,')),-        ('"string"', Err('Input should be a valid integer, unable to parse string as an integer [type=int_parsing,')),-    ],-)-def test_int(input_value, expected):-    v = SchemaValidator(core_schema.int_schema())-    if isinstance(expected, Err):-        with pytest.raises(ValidationError, match=re.escape(expected.message)):-            v.validate_json(input_value)-    else:-        assert v.validate_json(input_value) == expected--[email protected](-    'input_value,expected',-    [-        ('123.4', 123.4),-        ('123.0', 123.0),-        ('123', 123.0),-        ('"123.4"', 123.4),-        ('"123.0"', 123.0),-        ('"123"', 123.0),-        ('"string"', Err('Input should be a valid number, unable to parse string as a number [type=float_parsing,')),-    ],-)-def test_float(input_value, expected):-    v = SchemaValidator(core_schema.float_schema())-    if isinstance(expected, Err):-        with pytest.raises(ValidationError, match=re.escape(expected.message)):-            v.validate_json(input_value)-    else:-        assert v.validate_json(input_value) == expected---def test_typed_dict():-    v = SchemaValidator(-        core_schema.typed_dict_schema(-            fields={-                'field_a': core_schema.typed_dict_field(schema=core_schema.str_schema()),-                'field_b': core_schema.typed_dict_field(schema=core_schema.int_schema()),-            }-        )-    )--    # language=json-    input_str = '{"field_a": "abc", "field_b": 1}'-    assert v.validate_json(input_str) == {'field_a': 'abc', 'field_b': 1}-    # language=json-    input_str = '{"field_a": "a", "field_a": "b", "field_b": 1}'-    assert v.validate_json(input_str) == {'field_a': 'b', 'field_b': 1}-    assert v.validate_json(input_str) == {'field_a': 'b', 'field_b': 1}---def test_float_no_remainder():-    v = SchemaValidator(core_schema.int_schema())-    assert v.validate_json('123.0') == 123---def test_error_loc():-    v = SchemaValidator(-        core_schema.typed_dict_schema(-            fields={-                'field_a': core_schema.typed_dict_field(-                    schema=core_schema.list_schema(items_schema=core_schema.int_schema())-                )-            },-            extras_schema=core_schema.int_schema(),-            extra_behavior='allow',-        )-    )--    # assert v.validate_json('{"field_a": [1, 2, "3"]}') == ({'field_a': [1, 2, 3]}, {'field_a'})--    with pytest.raises(ValidationError) as exc_info:-        v.validate_json('{"field_a": [1, 2, "wrong"]}')-    assert exc_info.value.errors(include_url=False) == [-        {-            'type': 'int_parsing',-            'loc': ('field_a', 2),-            'msg': 'Input should be a valid integer, unable to parse string as an integer',-            'input': 'wrong',-        }-    ]---def test_dict():-    v = SchemaValidator(-        core_schema.dict_schema(keys_schema=core_schema.int_schema(), values_schema=core_schema.int_schema())-    )-    assert v.validate_json('{"1": 2, "3": 4}') == {1: 2, 3: 4}--    # duplicate keys, the last value wins, like with python-    assert json.loads('{"1": 1, "1": 2}') == {'1': 2}-    assert v.validate_json('{"1": 1, "1": 2}') == {1: 2}---def test_dict_any_value():-    v = SchemaValidator(core_schema.dict_schema(keys_schema=core_schema.str_schema()))-    assert v.validate_json('{"1": 1, "2": "a", "3": null}') == {'1': 1, '2': 'a', '3': None}---def test_json_invalid():-    v = SchemaValidator(core_schema.bool_schema())--    with pytest.raises(ValidationError) as exc_info:-        v.validate_json('"foobar')-    assert exc_info.value.errors(include_url=False) == [-        {-            'type': 'json_invalid',-            'loc': (),-            'msg': 'Invalid JSON: EOF while parsing a string at line 1 column 7',-            'input': '"foobar',-            'ctx': {'error': 'EOF while parsing a string at line 1 column 7'},-        }-    ]-    with pytest.raises(ValidationError) as exc_info:-        v.validate_json('[1,\n2,\n3,]')-    assert exc_info.value.errors(include_url=False) == [-        {-            'type': 'json_invalid',-            'loc': (),-            'msg': 'Invalid JSON: trailing comma at line 3 column 3',-            'input': '[1,\n2,\n3,]',-            'ctx': {'error': 'trailing comma at line 3 column 3'},-        }-    ] @@ -375,9 +180,2 @@ -def test_inf_nan_allow():-    v = SchemaValidator(core_schema.float_schema(allow_inf_nan=True))-    assert v.validate_json('Infinity') == float('inf')-    assert v.validate_json('-Infinity') == float('-inf')-    assert v.validate_json('NaN') == IsFloatNan()-- def test_partial_parse():@@ -418,3 +216,3 @@     base_64_without_padding = 'bm8tcGFkZGluZw'-    assert v.validate_json(json.dumps(base_64_without_padding)) == b'no-padding'+    assert v.validate_json(f'"{base_64_without_padding}"') == b'no-padding' @@ -425,3 +223,3 @@     with pytest.raises(ValidationError) as exc_info:-        v.validate_json(json.dumps(wrong_input))+        v.validate_json(f'"{wrong_input}"')     assert exc_info.value.errors(include_url=False, include_context=False) == [@@ -457,3 +255,3 @@     with pytest.raises(ValidationError) as exc_info:-        v.validate_json(json.dumps(wrong_input))+        v.validate_json(f'"{wrong_input}"')     assert exc_info.value.errors(include_url=False, include_context=False) == [@@ -469,3 +267,3 @@     with pytest.raises(ValidationError) as exc_info:-        v.validate_json(json.dumps(wrong_input))+        v.validate_json(f'"{wrong_input}"')     assert exc_info.value.errors(include_url=False, include_context=False) == [
tests/test_misc.py +19 lines
--- +++ @@ -242 +242,20 @@         core_schema.foobar+++def test_internal_error():+    v = SchemaValidator(+        core_schema.model_schema(+            cls=int,+            schema=core_schema.model_fields_schema(+                fields={'f': core_schema.model_field(schema=core_schema.int_schema())}+            ),+        )+    )+    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):+        v.validate_python({'f': 123})++    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):+        v.validate_json('{"f": 123}')++    with pytest.raises(AttributeError, match="'int' object has no attribute '__dict__'"):+        v.isinstance_python({'f': 123})
tests/test_prebuilt.py +93 lines
--- +++ @@ -48,2 +48,95 @@     assert outer_serializer.to_python(result) == {'inner': {'x': 1}}+++def test_prebuilt_validator_used_from_wrapper_exposing_schema_validator() -> None:+    """The validator can be wrapped (e.g. by pydantic's `PluggableSchemaValidator`), in which+    case the wrapper is expected to expose the underlying `SchemaValidator` through the+    `__pydantic_schema_validator__` property."""++    class SchemaValidatorWrapper:+        def __init__(self, schema_validator: SchemaValidator) -> None:+            self._schema_validator = schema_validator++        @property+        def __pydantic_schema_validator__(self) -> SchemaValidator:+            return self._schema_validator++    class InnerModel:+        x: int++    inner_schema = core_schema.model_schema(+        InnerModel,+        schema=core_schema.model_fields_schema(+            {'x': core_schema.model_field(schema=core_schema.int_schema())},+        ),+    )++    InnerModel.__pydantic_complete__ = True  # pyright: ignore[reportAttributeAccessIssue]+    InnerModel.__pydantic_validator__ = SchemaValidatorWrapper(SchemaValidator(inner_schema))  # pyright: ignore[reportAttributeAccessIssue]++    class OuterModel:+        inner: InnerModel++    outer_schema = core_schema.model_schema(+        OuterModel,+        schema=core_schema.model_fields_schema(+            {+                'inner': core_schema.model_field(+                    schema=core_schema.model_schema(+                        InnerModel,+                        schema=core_schema.model_fields_schema(+                            # note, we use str schema here even though that's incorrect+                            # in order to verify that the prebuilt validator is used+                            # off of InnerModel with the correct int schema, not this str schema+                            {'x': core_schema.model_field(schema=core_schema.str_schema())},+                        ),+                    )+                )+            }+        ),+    )++    outer_validator = SchemaValidator(outer_schema)+    assert 'PrebuiltValidator' in repr(outer_validator)++    result = outer_validator.validate_python({'inner': {'x': 1}})+    assert result.inner.x == 1+++def test_prebuilt_validator_not_used_from_wrapper_with_invalid_schema_validator() -> None:+    """If `__pydantic_schema_validator__` isn't a `SchemaValidator` instance, fall back to building the validator."""++    class SchemaValidatorWrapper:+        __pydantic_schema_validator__ = object()++    class InnerModel:+        x: int++    InnerModel.__pydantic_complete__ = True  # pyright: ignore[reportAttributeAccessIssue]+    InnerModel.__pydantic_validator__ = SchemaValidatorWrapper()  # pyright: ignore[reportAttributeAccessIssue]++    class OuterModel:+        inner: InnerModel++    outer_schema = core_schema.model_schema(+        OuterModel,+        schema=core_schema.model_fields_schema(+            {+                'inner': core_schema.model_field(+                    schema=core_schema.model_schema(+                        InnerModel,+                        schema=core_schema.model_fields_schema(+                            {'x': core_schema.model_field(schema=core_schema.int_schema())},+                        ),+                    )+                )+            }+        ),+    )++    outer_validator = SchemaValidator(outer_schema)+    assert 'PrebuiltValidator' not in repr(outer_validator)++    result = outer_validator.validate_python({'inner': {'x': 1}})+    assert result.inner.x == 1 
tests/test_schema_functions.py +16 lines
--- +++ @@ -3,3 +3,3 @@ from enum import Enum-from typing import Any+from typing import Any, NamedTuple @@ -28,2 +28,6 @@     y: str+++class MyNamedTuple(NamedTuple):+    foo: int @@ -85,2 +89,3 @@     (core_schema.missing_sentinel_schema, args(), {'type': 'missing-sentinel'}),+    (core_schema.ellipsis_schema, args(), {'type': 'ellipsis'}),     (@@ -309,2 +314,11 @@     ),+    (+        core_schema.named_tuple_schema,+        args(MyNamedTuple, [{'name': 'foo', 'type': 'named-tuple-field', 'schema': {'type': 'int'}}]),+        {+            'type': 'named-tuple',+            'cls': MyNamedTuple,+            'fields': [{'name': 'foo', 'type': 'named-tuple-field', 'schema': {'type': 'int'}}],+        },+    ),     (core_schema.uuid_schema, args(), {'type': 'uuid'}),@@ -312,2 +326,3 @@     (core_schema.decimal_schema, args(multiple_of=5, gt=1.2), {'type': 'decimal', 'multiple_of': 5, 'gt': 1.2}),+    (core_schema.fraction_schema, args(), {'type': 'fraction'}),     (core_schema.complex_schema, args(), {'type': 'complex'}),
tests/test_typing.py +9 lines
--- +++ @@ -5,2 +5,4 @@ from typing import Any++import pytest @@ -179,9 +181,4 @@ def test_schema_validator_wrong() -> None:-    # use this instead of pytest.raises since pyright complains about input when pytest isn't installed-    try:+    with pytest.raises(SchemaError):         SchemaValidator({'type': 'bad'})  # type: ignore-    except SchemaError:-        pass-    else:-        raise AssertionError('SchemaValidator did not raise SchemaError') @@ -202,9 +199,4 @@ -    # use this instead of pytest.raises since pyright complains about input when pytest isn't installed-    try:+    with pytest.raises(TypeError, match='takes 1 positional argument but 2 were given'):         v.validate_python(1)-    except TypeError as exc:-        assert 'takes 1 positional argument but 2 were given' in str(exc)-    else:-        raise AssertionError('v.validate_python(1) did not raise TypeError') @@ -212,8 +204,4 @@ def test_type_error():-    try:+    with pytest.raises(KeyError, match="Invalid error type: 'foobar'"):         PydanticKnownError('foobar')  # type: ignore-    except KeyError as exc:-        assert str(exc) == '"Invalid error type: \'foobar\'"'-    else:-        raise AssertionError("PydanticKnownError('foobar') did not raise KeyError") @@ -268,6 +256,6 @@ -    try:+    with pytest.raises(ValidationError) as exc_info:         v.validate_python('not an int')-    except ValidationError as err:-        for details in err.errors(include_url=False):-            act_on_error_details(details)++    for details in exc_info.value.errors(include_url=False):+        act_on_error_details(details)
tests/test_tzinfo.py +181 lines
--- +++ @@ -1 +1,6 @@+"""Adapted from CPython `timezone` tests.++Original tests are located here https://github.com/python/cpython/blob/a0bb4a39d1ca10e4a75f50a9fbe90cc9db28d29e/Lib/test/datetimetester.py#L256+"""+ import copy@@ -4,3 +9,2 @@ import sys-import unittest from datetime import datetime, timedelta, timezone, tzinfo@@ -8,3 +12,6 @@ -from pydantic_core import SchemaValidator, TzInfo, core_schema+import pytest+from pydantic import TypeAdapter++from pydantic_core import TzInfo @@ -63,169 +70,172 @@ --def first_sunday_on_or_after(dt):-    days_to_go = 6 - dt.weekday()-    if days_to_go:-        dt += timedelta(days_to_go)-    return dt---DSTSTART = datetime(1, 4, 1, 2)-DSTEND = datetime(1, 10, 25, 1)---class TestTzInfo(unittest.TestCase):-    """Adapted from CPython `timezone` tests--    Original tests are located here https://github.com/python/cpython/blob/a0bb4a39d1ca10e4a75f50a9fbe90cc9db28d29e/Lib/test/datetimetester.py#L256-    """--    def setUp(self):-        self.ACDT = TzInfo(timedelta(hours=9.5).total_seconds())-        self.EST = TzInfo(-timedelta(hours=5).total_seconds())-        self.UTC = TzInfo(timedelta(0).total_seconds())-        self.DT = datetime(2010, 1, 1)--    def test_str(self):-        for tz in [self.ACDT, self.EST]:-            self.assertEqual(str(tz), tz.tzname(None))--    def test_constructor(self):-        for subminute in [timedelta(microseconds=1), timedelta(seconds=1)]:-            tz = TzInfo(subminute.total_seconds())-            self.assertNotEqual(tz.utcoffset(None) % timedelta(minutes=1), 0)-        # invalid offsets-        for invalid in [timedelta(1, 1), timedelta(1)]:-            self.assertRaises(ValueError, TzInfo, invalid.total_seconds())-            self.assertRaises(ValueError, TzInfo, -invalid.total_seconds())--        with self.assertRaises(TypeError):-            TzInfo(None)-        with self.assertRaises(TypeError):-            TzInfo(timedelta(seconds=42))-        with self.assertRaises(TypeError):-            TzInfo(ZERO, None)-        with self.assertRaises(TypeError):-            TzInfo(ZERO, 42)-        with self.assertRaises(TypeError):-            TzInfo(ZERO, 'ABC', 'extra')--    def test_inheritance(self):-        self.assertIsInstance(self.EST, tzinfo)--    def test_utcoffset(self):-        dummy = self.DT-        for h in [0, 1.5, 12]:-            offset = h * HOUR-            self.assertEqual(timedelta(seconds=offset), TzInfo(offset).utcoffset(dummy))-            self.assertEqual(timedelta(seconds=-offset), TzInfo(-offset).utcoffset(dummy))--        self.assertEqual(self.EST.utcoffset(''), timedelta(hours=-5))-        self.assertEqual(self.EST.utcoffset(5), timedelta(hours=-5))--    def test_dst(self):-        self.EST.dst('') is None-        self.EST.dst(5) is None--    def test_tzname(self):-        self.assertEqual('-05:00', TzInfo(-5 * HOUR).tzname(None))-        self.assertEqual('+09:30', TzInfo(9.5 * HOUR).tzname(None))-        self.assertEqual('-00:01', TzInfo(timedelta(minutes=-1).total_seconds()).tzname(None))-        # Sub-minute offsets:-        self.assertEqual('+01:06:40', TzInfo(timedelta(0, 4000).total_seconds()).tzname(None))-        self.assertEqual('-01:06:40', TzInfo(-timedelta(0, 4000).total_seconds()).tzname(None))-        self.assertEqual('+01:06:40', TzInfo(timedelta(0, 4000, 1).total_seconds()).tzname(None))-        self.assertEqual('-01:06:40', TzInfo(-timedelta(0, 4000, 1).total_seconds()).tzname(None))--        self.assertEqual(self.EST.tzname(''), '-05:00')-        self.assertEqual(self.EST.tzname(5), '-05:00')--    def test_fromutc(self):-        for tz in [self.EST, self.ACDT]:-            utctime = self.DT.replace(tzinfo=tz)-            local = tz.fromutc(utctime)-            self.assertEqual(local - utctime, tz.utcoffset(local))-            self.assertEqual(local, self.DT.replace(tzinfo=timezone.utc))--    def test_comparison(self):-        self.assertNotEqual(TzInfo(ZERO), TzInfo(HOUR))-        self.assertEqual(TzInfo(HOUR), TzInfo(HOUR))-        self.assertFalse(TzInfo(ZERO) < TzInfo(ZERO))-        self.assertIn(TzInfo(ZERO), {TzInfo(ZERO)})-        self.assertTrue(TzInfo(ZERO) is not None)-        self.assertFalse(TzInfo(ZERO) is None)--        tz = TzInfo(ZERO)-        self.assertTrue(tz == ALWAYS_EQ)-        self.assertFalse(tz != ALWAYS_EQ)-        self.assertTrue(tz < LARGEST)-        self.assertFalse(tz > LARGEST)-        self.assertTrue(tz <= LARGEST)-        self.assertFalse(tz >= LARGEST)-        self.assertFalse(tz < SMALLEST)-        self.assertTrue(tz > SMALLEST)-        self.assertFalse(tz <= SMALLEST)-        self.assertTrue(tz >= SMALLEST)--        # offset based comparison tests for tzinfo derived classes like datetime.timezone.-        utcdatetime = self.DT.replace(tzinfo=timezone.utc)-        self.assertTrue(tz == utcdatetime.tzinfo)-        estdatetime = self.DT.replace(tzinfo=timezone(-timedelta(hours=5)))-        self.assertTrue(self.EST == estdatetime.tzinfo)-        self.assertTrue(tz > estdatetime.tzinfo)--        if sys.platform == 'linux':-            try:-                europe_london = ZoneInfo('Europe/London')-            except ZoneInfoNotFoundError:-                # tz data not available-                pass-            else:-                self.assertFalse(tz == europe_london)-                with self.assertRaises(TypeError):-                    tz > europe_london--    def test_copy(self):-        for tz in self.ACDT, self.EST:-            tz_copy = copy.copy(tz)-            self.assertEqual(tz_copy, tz)--    def test_deepcopy(self):-        for tz in self.ACDT, self.EST:-            tz_copy = copy.deepcopy(tz)-            self.assertEqual(tz_copy, tz)--    def test_offset_boundaries(self):+ACDT = TzInfo(timedelta(hours=9.5).total_seconds())+EST = TzInfo(-timedelta(hours=5).total_seconds())+UTC = TzInfo(timedelta(0).total_seconds())+DT = datetime(2010, 1, 1)++[email protected]('tz', [ACDT, EST])+def test_str(tz):+    assert str(tz) == tz.tzname(None)+++def test_constructor():+    for subminute in [timedelta(microseconds=1), timedelta(seconds=1)]:+        tz = TzInfo(subminute.total_seconds())+        assert tz.utcoffset(None) % timedelta(minutes=1) != 0+    # invalid offsets+    for invalid in [timedelta(1, 1), timedelta(1)]:+        with pytest.raises(ValueError):+            TzInfo(invalid.total_seconds())+        with pytest.raises(ValueError):+            TzInfo(-invalid.total_seconds())++    with pytest.raises(TypeError):+        TzInfo(None)+    with pytest.raises(TypeError):+        TzInfo(timedelta(seconds=42))+    with pytest.raises(TypeError):+        TzInfo(ZERO, None)+    with pytest.raises(TypeError):+        TzInfo(ZERO, 42)+    with pytest.raises(TypeError):+        TzInfo(ZERO, 'ABC', 'extra')+++def test_inheritance():+    assert isinstance(EST, tzinfo)+++def test_utcoffset():+    dummy = DT+    for h in [0, 1.5, 12]:+        offset = h * HOUR+        assert timedelta(seconds=offset) == TzInfo(offset).utcoffset(dummy)+        assert timedelta(seconds=-offset) == TzInfo(-offset).utcoffset(dummy)++    assert EST.utcoffset('') == timedelta(hours=-5)+    assert EST.utcoffset(5) == timedelta(hours=-5)+++def test_dst():+    assert EST.dst('') is None+    assert EST.dst(5) is None+++def test_tzname():+    assert TzInfo(-5 * HOUR).tzname(None) == '-05:00'+    assert TzInfo(9.5 * HOUR).tzname(None) == '+09:30'+    assert TzInfo(timedelta(minutes=-1).total_seconds()).tzname(None) == '-00:01'+    # Sub-minute offsets:+    assert TzInfo(timedelta(0, 4000).total_seconds()).tzname(None) == '+01:06:40'+    assert TzInfo(-timedelta(0, 4000).total_seconds()).tzname(None) == '-01:06:40'+    assert TzInfo(timedelta(0, 4000, 1).total_seconds()).tzname(None) == '+01:06:40'+    assert TzInfo(-timedelta(0, 4000, 1).total_seconds()).tzname(None) == '-01:06:40'++    assert EST.tzname('') == '-05:00'+    assert EST.tzname(5) == '-05:00'++[email protected]('tz', [EST, ACDT])+def test_fromutc(tz):+    utctime = DT.replace(tzinfo=tz)+    local = tz.fromutc(utctime)+    assert local - utctime == tz.utcoffset(local)+    assert local == DT.replace(tzinfo=timezone.utc)+++def test_comparison():+    assert TzInfo(ZERO) != TzInfo(HOUR)+    assert TzInfo(HOUR) == TzInfo(HOUR)+    assert not TzInfo(ZERO) < TzInfo(ZERO)+    assert TzInfo(ZERO) in {TzInfo(ZERO)}+    assert TzInfo(ZERO) is not None++    tz = TzInfo(ZERO)+    assert tz == ALWAYS_EQ+    assert not tz != ALWAYS_EQ+    assert tz < LARGEST+    assert not tz > LARGEST+    assert tz <= LARGEST+    assert not tz >= LARGEST+    assert not tz < SMALLEST+    assert tz > SMALLEST+    assert not tz <= SMALLEST
… 131 more lines (truncated)
tests/validators/test_union.py +8 lines
--- +++ @@ -63,3 +63,4 @@     @pytest.fixture(scope='class')-    def schema_validator(self) -> SchemaValidator:+    @classmethod+    def schema_validator(cls) -> SchemaValidator:         return SchemaValidator(@@ -68,3 +69,3 @@                     core_schema.model_schema(-                        cls=self.ModelA,+                        cls=cls.ModelA,                         schema=core_schema.model_fields_schema(@@ -77,3 +78,3 @@                     core_schema.model_schema(-                        cls=self.ModelB,+                        cls=cls.ModelB,                         schema=core_schema.model_fields_schema(@@ -126,3 +127,4 @@     @pytest.fixture(scope='class')-    def schema_validator(self) -> SchemaValidator:+    @classmethod+    def schema_validator(cls) -> SchemaValidator:         return SchemaValidator(@@ -131,3 +133,3 @@                     core_schema.model_schema(-                        cls=self.ModelA,+                        cls=cls.ModelA,                         schema=core_schema.model_fields_schema(@@ -140,3 +142,3 @@                     core_schema.model_schema(-                        cls=self.ModelB,+                        cls=cls.ModelB,                         schema=core_schema.model_fields_schema(
tests/validators/test_uuid.py +1 lines
--- +++ @@ -40,3 +40,3 @@         # Invalid UUIDs-        ('not-a-valid-uuid', Err('Input should be a valid UUID, invalid character: found `n` at 1')),+        ('not-a-valid-uuid', Err('Input should be a valid UUID, invalid character: found `n` at 0')),         (
tests/validators/test_with_default.py +0 lines
--- +++ @@ -1,2 +1 @@-import os import platform@@ -5,3 +4,2 @@ from collections.abc import Callable-from dataclasses import dataclass from typing import Any@@ -12,3 +10,2 @@     ArgsKwargs,-    PydanticUndefined,     PydanticUseDefault,@@ -20,3 +17,2 @@ )-from pydantic_core._pydantic_core import SchemaSerializer @@ -820,152 +816,2 @@ [email protected](params=['model', 'typed_dict', 'dataclass', 'arguments_v3'])-def container_schema_builder(-    request: pytest.FixtureRequest,-) -> Callable[[dict[str, core_schema.CoreSchema]], core_schema.CoreSchema]:-    if request.param == 'model':-        return lambda fields: core_schema.model_schema(-            cls=type('Test', (), {}),-            schema=core_schema.model_fields_schema(-                fields={k: core_schema.model_field(schema=v) for k, v in fields.items()},-            ),-        )-    elif request.param == 'typed_dict':-        return lambda fields: core_schema.typed_dict_schema(-            fields={k: core_schema.typed_dict_field(schema=v) for k, v in fields.items()}-        )-    elif request.param == 'dataclass':-        return lambda fields: core_schema.dataclass_schema(-            cls=dataclass(type('Test', (), {})),-            schema=core_schema.dataclass_args_schema(-                'Test',-                fields=[core_schema.dataclass_field(name=k, schema=v) for k, v in fields.items()],-            ),-            fields=[k for k in fields.keys()],-        )-    elif request.param == 'arguments_v3':-        # TODO: open an issue for this-        raise pytest.xfail('arguments v3 does not yet support default_factory_takes_data properly')-    else:-        raise ValueError(f'Unknown container type {request.param}')---def test_default_factory_not_called_if_existing_error(container_schema_builder, pydantic_version) -> None:-    schema = container_schema_builder(-        {-            'a': core_schema.int_schema(),-            'b': core_schema.with_default_schema(-                schema=core_schema.int_schema(), default_factory=lambda data: data['a'], default_factory_takes_data=True-            ),-        }-    )-    v = SchemaValidator(schema)-    with pytest.raises(ValidationError) as e:-        v.validate_python({'a': 'not_an_int'})--    assert e.value.errors(include_url=False) == [-        {-            'type': 'int_parsing',-            'loc': ('a',),-            'msg': 'Input should be a valid integer, unable to parse string as an integer',-            'input': 'not_an_int',-        },-        {-            'input': PydanticUndefined,-            'loc': ('b',),-            'msg': 'The default factory uses validated data, but at least one validation error occurred',-            'type': 'default_factory_not_called',-        },-    ]--    include_urls = os.environ.get('PYDANTIC_ERRORS_INCLUDE_URL', '1') != 'false'--    expected = (-        f"""2 validation errors for {v.title}-a-  Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='not_an_int', input_type=str]"""-        + (-            f"""-    For further information visit https://errors.pydantic.dev/{pydantic_version}/v/int_parsing"""-            if include_urls-            else ''-        )-        + """-b-  The default factory uses validated data, but at least one validation error occurred [type=default_factory_not_called]"""-        + (-            f"""-    For further information visit https://errors.pydantic.dev/{pydantic_version}/v/default_factory_not_called"""-            if include_urls-            else ''-        )-    )--    assert str(e.value) == expected--    # repeat with the first field being a default which validates incorrectly--    schema = container_schema_builder(-        {-            'a': core_schema.with_default_schema(-                schema=core_schema.int_schema(), default='not_an_int', validate_default=True-            ),-            'b': core_schema.with_default_schema(-                schema=core_schema.int_schema(), default_factory=lambda data: data['a'], default_factory_takes_data=True-            ),-        }-    )-    v = SchemaValidator(schema)-    with pytest.raises(ValidationError) as e:-        v.validate_python({})--    assert e.value.errors(include_url=False) == [-        {-            'type': 'int_parsing',-            'loc': ('a',),-            'msg': 'Input should be a valid integer, unable to parse string as an integer',-            'input': 'not_an_int',-        },-        {-            'input': PydanticUndefined,-            'loc': ('b',),-            'msg': 'The default factory uses validated data, but at least one validation error occurred',-            'type': 'default_factory_not_called',-        },-    ]--    assert str(e.value) == expected---def test_default_factory_not_called_union_ok(container_schema_builder) -> None:-    schema_fail = container_schema_builder(-        {-            'a': core_schema.none_schema(),-            'b': core_schema.with_default_schema(-                schema=core_schema.int_schema(),-                default_factory=lambda data: data['a'],-                default_factory_takes_data=True,-            ),-        }-    )--    schema_ok = container_schema_builder(-        {-            'a': core_schema.int_schema(),-            'b': core_schema.with_default_schema(-                schema=core_schema.int_schema(),-                default_factory=lambda data: data['a'] + 1,-                default_factory_takes_data=True,-            ),-            # this is used to show that this union member was selected-            'c': core_schema.with_default_schema(schema=core_schema.int_schema(), default=3),-        }-    )--    schema = core_schema.union_schema([schema_fail, schema_ok])--    v = SchemaValidator(schema)-    s = SchemaSerializer(schema)-    assert s.to_python(v.validate_python({'a': 1}), mode='json') == {'a': 1, 'b': 2, 'c': 3}-- def test_default_validate_default_after_validator_field_name() -> None:
pytest pypi
9.1.1 2mo ago incident on record
YANKBURST ×3
latest 9.1.1 versions 192 maintainers 1
8.3.3
8.3.4
8.3.5
8.4.0
8.4.1
8.4.2
9.0.0
9.0.1
9.0.2
9.0.3
9.1.0
9.1.1
YANK
8.1.0 marked yanked (still downloadable)
high · registry-verified · 2024-03-03 · 2y ago
BURST
2 releases in 9m: 2.2.2, 2.2.3
info · registry-verified · 2012-02-06 · 14y ago
BURST
2 releases in 58m: 5.0.0, 4.6.4
info · registry-verified · 2019-06-29 · 7y ago
BURST
2 releases in 53m: 8.3.0, 8.3.1
info · registry-verified · 2024-07-20 · 2y ago
release diff 9.1.0 → 9.1.1
+1 added · -0 removed · ~24 modified
src/_pytest/_version.py +2 lines
--- +++ @@ -20,4 +20,4 @@ -__version__ = version = '9.1.0'-__version_tuple__ = version_tuple = (9, 1, 0)+__version__ = version = '9.1.1'+__version_tuple__ = version_tuple = (9, 1, 1) 
src/_pytest/config/__init__.py +9 lines
--- +++ @@ -647,14 +647,14 @@             anchor = absolutepath(invocation_dir / path)-             # Ensure we do not break if what appears to be an anchor             # is in fact a very long option (#10169, #11394).-            if safe_exists(anchor):-                anchors.append(anchor)-                # Let's also consider test* subdirs.-                if anchor.is_dir():-                    for x in anchor.glob("test*"):-                        if x.is_dir():-                            anchors.append(x)+            if not safe_exists(anchor):+                continue++            anchors.append(anchor)+            # Let's also consider test* subdirs.+            if anchor.is_dir():+                anchors.extend(x for x in anchor.glob("test*") if x.is_dir())         if not anchors:-            anchors = [invocation_dir]+            anchors.append(invocation_dir)+            anchors.extend(x for x in invocation_dir.glob("test*") if x.is_dir()) 
src/_pytest/fixtures.py +14 lines
--- +++ @@ -66,2 +66,3 @@ from _pytest.main import Session+from _pytest.mark import Mark from _pytest.mark import ParameterSet@@ -1900,2 +1901,7 @@         """Generate new tests based on parametrized fixtures used by the given metafunc"""++        def get_parametrize_mark_argnames(mark: Mark) -> Sequence[str]:+            args, _ = ParameterSet._parse_parametrize_args(*mark.args, **mark.kwargs)+            return args+         for argname in metafunc.fixturenames:@@ -1903,2 +1909,10 @@             fixture_defs = metafunc._arg2fixturedefs.get(argname, ())++            # If the test itself parametrizes using this argname, give it+            # precedence.+            if any(+                argname in get_parametrize_mark_argnames(mark)+                for mark in metafunc.definition.iter_markers("parametrize")+            ):+                continue 
src/_pytest/mark/structures.py +5 lines
--- +++ @@ -23,3 +23,2 @@ from .._code import getfslineno-from ..compat import deprecated from ..compat import NOTSET@@ -539,7 +538,9 @@     class _ParametrizeMarkDecorator(MarkDecorator):-        @overload  # type: ignore[override,no-overload-impl]-        def __call__(+        def __call__(  # type: ignore[override]             self,             argnames: str | Sequence[str],-            argvalues: Collection[ParameterSet | Sequence[object] | object],+            argvalues: Iterable[ParameterSet | Sequence[object] | object],+            # TODO(pytest10): Change to below after PARAMETRIZE_NON_COLLECTION_ITERABLE deprecation.+            #                 Overload doesn't work, see #14606.+            # argvalues: Collection[ParameterSet | Sequence[object] | object],             *,@@ -547,19 +548,2 @@             ids: Iterable[None | str | float | int | bool | _HiddenParam]-            | Callable[[Any], object | None]-            | None = ...,-            scope: ScopeName | None = ...,-        ) -> MarkDecorator: ...--        @overload-        @deprecated(-            "Passing a non-Collection iterable to the 'argvalues' parameter of @pytest.mark.parametrize is deprecated. "-            "Convert argvalues to a list or tuple.",-        )-        def __call__(-            self,-            argnames: str | Sequence[str],-            argvalues: Iterable[ParameterSet | Sequence[object] | object],-            *,-            indirect: bool | Sequence[str] = ...,-            ids: Iterable[None | str | float | int | bool]             | Callable[[Any], object | None]
src/_pytest/raises.py +1 lines
--- +++ @@ -1356,3 +1356,3 @@             for i_actual, actual in enumerate(actual_exceptions):-                if results.get_result(i_exp, i_actual) is None:+                if results.get_result(i_failed, i_actual) is None:                     # we print full repr of match target
testing/python/fixtures.py +56 lines
--- +++ @@ -1187,3 +1187,5 @@             import pytest+             values = []+             @pytest.fixture(scope='module', autouse=True)@@ -1191,2 +1193,3 @@                 values.append("module")+             @pytest.fixture(autouse=True)@@ -1198,6 +1201,8 @@ -            class TestClass(object):+            class TestClass:                 @pytest.fixture(scope="class", autouse=True)-                def setup_class(self):+                @classmethod+                def setup_class(cls):                     values.append("class")+                 @pytest.fixture(autouse=True)@@ -1205,7 +1210,15 @@                     values.append("method")+                 def test_method(self):                     pass+             def test_all():-                assert values == ["module", "function", "class",-                             "function", "method", "function"]+                assert values == [+                    "module",+                    "function",+                    "class",+                    "function",+                    "method",+                    "function",+                ]         """@@ -2469,3 +2482,4 @@                 @pytest.fixture(scope="class", autouse=True)-                def setup_teardown(self, item):+                @classmethod+                def setup_teardown(cls, item):                     values.append("setup-%d" % item)@@ -2622,2 +2636,28 @@         """+        )+        reprec = pytester.inline_run()+        reprec.assertoutcome(passed=2)++    def test_override_parametrized_fixture_with_indirect(+        self, pytester: Pytester+    ) -> None:+        """Make sure a parametrized argument can override a parametrized fixture.++        This was a regression introduced in the fix for #736.+        """+        pytester.makepyfile(+            """+            import pytest++            @pytest.fixture(params=["a"])+            def fixt(request):+                return request.param * 2++            def test_fixt(fixt):+                assert fixt == "aa"++            @pytest.mark.parametrize("fixt", ['b'], indirect=True)+            def test_indirect(fixt):+                assert fixt == "bb"+            """         )@@ -3248,7 +3288,8 @@             class TestClass(object):+                @pytest.fixture(scope="class", autouse=True)                 @classmethod-                @pytest.fixture(scope="class", autouse=True)-                def setup1(self, request, param1):+                def setup1(cls, request, param1):                     values.append(1)-                    request.addfinalizer(self.teardown1)+                    request.addfinalizer(cls.teardown1)+                 @classmethod@@ -3256,9 +3297,13 @@                     assert values.pop() == 1+                 @pytest.fixture(scope="class", autouse=True)-                def setup2(self, request, param1):+                @classmethod+                def setup2(cls, request, param1):                     values.append(2)-                    request.addfinalizer(self.teardown2)+                    request.addfinalizer(cls.teardown2)+                 @classmethod-                def teardown2(self):+                def teardown2(cls):                     assert values.pop() == 2+                 def test(self):
testing/python/metafunc.py +2 lines
--- +++ @@ -1745,3 +1745,4 @@                 @pytest.fixture(scope="class")-                def fixture(self, fixture):+                @classmethod+                def fixture(cls, fixture):                     pass
testing/python/raises_group.py +18 lines
--- +++ @@ -1352 +1352,19 @@         RaisesGroup((ValueError, IndexError))  # type: ignore[call-overload]+++def test_expected_matching_only_on_matching() -> None:+    """Regression test for #14220, logic error which caused the "which was+    paired with" message to appear for wrong pairs."""+    with (+        fails_raises_group(+            "\n"+            "1 matched exception. \n"+            "Too few exceptions raised!\n"+            "The following expected exceptions did not find a match:\n"+            "  ValueError\n"+            "  TypeError\n"+            "    It matches `TypeError()` which was paired with `TypeError`",+        ),+        RaisesGroup(TypeError, ValueError, TypeError),+    ):+        raise ExceptionGroup("", [TypeError()])
testing/test_conftest.py +22 lines
--- +++ @@ -440,2 +440,24 @@     result.stdout.fnmatch_lines(["*--xyz*"])+++def test_conftests_in_invocation_dir_tests_is_initial(pytester: Pytester) -> None:+    """An option registered in a conftest under ``test*`` subdir of the+    invocation dir is loaded as initial when no command-line arguments+    or `testpaths` are given (#14608).+    """+    pytester.makepyfile(+        **{+            "tests/conftest.py": """+                def pytest_addoption(parser):+                    parser.addoption("--db-url")+            """,+            "test_it.py": """+                def test_it(request):+                    assert request.config.getoption("--db-url") == "scheme://host/db"+            """,+        }+    )+    result = pytester.runpytest("--db-url", "scheme://host/db")+    assert result.ret == ExitCode.OK+    result.assert_outcomes(passed=1) 
testing/test_unittest.py +3 lines
--- +++ @@ -869,5 +869,7 @@             @pytest.fixture(scope="class", autouse=True)-            def perclass(self, request):+            @classmethod+            def perclass(cls, request):                 request.cls.hello = "world"                 {stmt}+             @pytest.fixture(scope="function", autouse=True)
testing/typing_checks.py +6 lines
--- +++ @@ -69,9 +69,2 @@ -# Test @pytest.mark.parametrize iterator argvalues deprecation.-# Will be complain about unused type ignore if doesn't work.[email protected]("x", iter(range(10)))  # type: ignore[deprecated]-def test_it(x: int) -> None:-    pass-- # Issue #14137.@@ -81 +74,7 @@     assert_type(custom_scope, ScopeName)+++# Issue #14606.[email protected]("x", [ImportError, AttributeError])+def check_mypy_bug_with_argvalues(x) -> None:+    pass
requests pypi
2.34.2 3mo ago incident on record
critical-tier YANK ×2BURST ×8
latest 2.34.2 versions 163 maintainers 1 critical-tier (snapshotted)
2.31.0
2.32.0
2.32.1
2.32.2
2.32.3
2.32.4
2.32.5
2.33.0
2.33.1
2.34.0
2.34.1
2.34.2
YANK
2.32.0 marked yanked (still downloadable)
high · registry-verified · 2024-05-20 · 2y ago
YANK
2.32.1 marked yanked (still downloadable)
high · registry-verified · 2024-05-20 · 2y ago
BURST
2 releases in 48m: 0.6.3, 0.6.4
info · registry-verified · 2011-10-14 · 14y ago
BURST
2 releases in 21m: 0.7.1, 0.7.2
info · registry-verified · 2011-10-23 · 14y ago
BURST
3 releases in 56m: 0.8.8, 0.8.9, 0.9.0
info · registry-verified · 2011-12-28 · 14y ago
BURST
2 releases in 11m: 1.0.1, 1.0.2
info · registry-verified · 2012-12-17 · 13y ago
BURST
2 releases in 2m: 2.0.0, 2.0.1
info · registry-verified · 2013-11-15 · 12y ago
BURST
2 releases in 15m: 2.9.2, 2.10.0
info · registry-verified · 2016-04-29 · 10y ago
BURST
2 releases in 20m: 2.17.2, 2.17.3
info · registry-verified · 2017-05-29 · 9y ago
BURST
2 releases in 0m: 2.24.0, 2.23.0
info · registry-verified · 2020-06-17 · 6y ago
release diff 2.34.1 → 2.34.2
+0 added · -0 removed · ~6 modified
src/requests/__version__.py +2 lines
--- +++ @@ -7,4 +7,4 @@ __url__ = "https://requests.readthedocs.io"-__version__ = "2.34.1"-__build__ = 0x023401+__version__ = "2.34.2"+__build__ = 0x023402 __author__ = "Kenneth Reitz"
src/requests/_types.py +1 lines
--- +++ @@ -111,3 +111,3 @@ -    HeadersType: TypeAlias = MutableMapping[str, str | bytes] | None+    HeadersType: TypeAlias = Mapping[str, str | bytes] | None 
src/requests/models.py +1 lines
--- +++ @@ -85,3 +85,2 @@ if TYPE_CHECKING:-    from collections.abc import MutableMapping     from http.cookiejar import CookieJar@@ -313,3 +312,3 @@     url: _t.UriType | None-    headers: MutableMapping[str, str | bytes]+    headers: Mapping[str, str | bytes]     files: _t.FilesType
s3transfer pypi
0.19.2 1mo ago incident on record
YANKINSTALL-EXEC
latest 0.19.2 versions 63 maintainers 1
0.13.0
0.13.1
0.14.0
0.15.0
0.16.0
0.16.1
0.17.0
0.17.1
0.18.0
0.19.0
0.19.1
0.19.2
YANK
0.8.1 marked yanked (still downloadable)
high · registry-verified · 2023-11-28 · 2y ago
INSTALL-EXEC
setup.py in sdist uses subprocess/exec (runs at pip install)
warn · snapshot-derived
release diff 0.19.1 → 0.19.2
+0 added · -0 removed · ~5 modified
s3transfer/__init__.py +1 lines
--- +++ @@ -147,3 +147,3 @@ __author__ = 'Amazon Web Services'-__version__ = '0.19.1'+__version__ = '0.19.2' 
s3transfer/crt.py +10 lines
--- +++ @@ -39,3 +39,3 @@ from botocore.config import Config-from botocore.exceptions import NoCredentialsError+from botocore.exceptions import InvalidConfigError, NoCredentialsError from botocore.utils import ArnParser, InvalidArnException@@ -145,2 +145,11 @@     if verify is not None:+        if isinstance(verify, str) and not verify.strip():+            raise InvalidConfigError(+                error_msg=(+                    'Invalid CA bundle: the configured value (ca_bundle, '+                    'AWS_CA_BUNDLE, REQUESTS_CA_BUNDLE, or verify) resolved '+                    'to an empty or whitespace-only string. Provide a valid '+                    'path to a CA bundle file.'+                )+            )         tls_ctx_options = TlsContextOptions()
tests/unit/test_crt.py +21 lines
--- +++ @@ -16,3 +16,7 @@ from botocore.credentials import Credentials, ReadOnlyCredentials-from botocore.exceptions import ClientError, NoCredentialsError+from botocore.exceptions import (+    ClientError,+    InvalidConfigError,+    NoCredentialsError,+) from botocore.session import Session@@ -368 +372,17 @@         assert mock_s3_crt_client.call_args[1]['enable_s3express'] is True++    def test_empty_verify_value_raises(self, mock_s3_crt_client):+        with pytest.raises(InvalidConfigError):+            s3transfer.crt.create_s3_crt_client('us-west-2', verify='')++    def test_whitespace_verify_value_raises(self, mock_s3_crt_client):+        with pytest.raises(InvalidConfigError):+            s3transfer.crt.create_s3_crt_client('us-west-2', verify='   ')++    def test_verify_false_disables_verification(self, mock_s3_crt_client):+        with (+            mock.patch('s3transfer.crt.TlsContextOptions') as mock_tls_options,+            mock.patch('s3transfer.crt.ClientTlsContext'),+        ):+            s3transfer.crt.create_s3_crt_client('us-west-2', verify=False)+        assert mock_tls_options.return_value.verify_peer is False
setuptools pypi
84.0.0 13d ago incident on record
critical-tier YANK ×9BURST ×35INSTALL-EXEC
latest 84.0.0 versions 625 maintainers 1 critical-tier (snapshotted)
80.7.1
80.8.0
80.9.0
75.3.3
80.10.1
80.10.2
81.0.0
75.3.4
82.0.0
82.0.1
83.0.0
84.0.0
YANK
59.1.0 marked yanked (still downloadable)
high · registry-verified · 2021-11-15 · 4y ago
YANK
60.3.0 marked yanked (still downloadable)
high · registry-verified · 2022-01-06 · 4y ago
YANK
69.3.0 marked yanked (still downloadable)
high · registry-verified · 2024-04-12 · 2y ago
YANK
69.4.0 marked yanked (still downloadable)
high · registry-verified · 2024-04-12 · 2y ago
YANK
71.0.1 marked yanked (still downloadable)
high · registry-verified · 2024-07-18 · 2y ago
YANK
72.0.0 marked yanked (still downloadable)
high · registry-verified · 2024-07-29 · 2y ago
YANK
75.9.0 marked yanked (still downloadable)
high · registry-verified · 2025-03-09 · 1y ago
YANK
80.3.0 marked yanked (still downloadable)
high · registry-verified · 2025-05-03 · 1y ago
YANK
80.7.0 marked yanked (still downloadable)
high · registry-verified · 2025-05-14 · 1y ago
BURST
2 releases in 21m: 0.9.2, 0.9.3
info · registry-verified · 2013-07-15 · 13y ago
BURST
2 releases in 3m: 1.1.2, 1.1.3
info · registry-verified · 2013-09-06 · 12y ago
BURST
4 releases in 3m: 3.1, 3.0, 3.0.1, 3.0.2
info · registry-verified · 2014-03-08 · 12y ago
BURST
2 releases in 15m: 3.5.2, 3.6
info · registry-verified · 2014-05-07 · 12y ago
BURST
2 releases in 17m: 3.7, 3.8
info · registry-verified · 2014-06-01 · 12y ago
BURST
2 releases in 0m: 4.0, 4.0.1
info · registry-verified · 2014-06-15 · 12y ago
BURST
2 releases in 28m: 8.1, 8.2
info · registry-verified · 2014-12-18 · 11y ago
BURST
2 releases in 59m: 12.0, 12.0.1
info · registry-verified · 2015-01-16 · 11y ago
BURST
2 releases in 14m: 12.0.2, 12.0.3
info · registry-verified · 2015-01-19 · 11y ago
BURST
2 releases in 26m: 20.8.0, 20.8.1
info · registry-verified · 2016-04-15 · 10y ago
BURST
2 releases in 8m: 22.0.1, 22.0.2
info · registry-verified · 2016-06-03 · 10y ago
BURST
2 releases in 25m: 22.0.4, 22.0.5
info · registry-verified · 2016-06-03 · 10y ago
BURST
2 releases in 9m: 24.1.1, 24.2.0
info · registry-verified · 2016-07-20 · 10y ago
BURST
2 releases in 2m: 25.0.0, 24.3.1
info · registry-verified · 2016-07-23 · 10y ago
BURST
2 releases in 52m: 25.1.5, 25.1.6
info · registry-verified · 2016-08-05 · 10y ago
BURST
2 releases in 11m: 25.3.0, 25.4.0
info · registry-verified · 2016-08-19 · 10y ago
BURST
2 releases in 41m: 27.0.0, 27.1.0
info · registry-verified · 2016-09-09 · 9y ago
BURST
2 releases in 10m: 28.8.1, 29.0.1
info · registry-verified · 2016-11-27 · 9y ago
BURST
2 releases in 23m: 30.2.1, 30.3.0
info · registry-verified · 2016-12-08 · 9y ago
BURST
2 releases in 19m: 36.6.1, 36.7.0
info · registry-verified · 2017-11-10 · 8y ago
BURST
2 releases in 48m: 38.0.0, 38.1.0
info · registry-verified · 2017-11-25 · 8y ago
BURST
2 releases in 7m: 38.6.1, 38.7.0
info · registry-verified · 2018-03-17 · 8y ago
BURST
2 releases in 16m: 40.1.1, 40.2.0
info · registry-verified · 2018-08-21 · 8y ago
BURST
2 releases in 5m: 41.3.0, 41.4.0
info · registry-verified · 2019-10-07 · 6y ago
BURST
3 releases in 19m: 44.1.0, 46.1.0, 46.1.1
info · registry-verified · 2020-03-21 · 6y ago
BURST
2 releases in 27m: 47.0.0, 47.1.0
info · registry-verified · 2020-05-28 · 6y ago
BURST
2 releases in 16m: 44.1.1, 47.1.1
info · registry-verified · 2020-05-29 · 6y ago
BURST
2 releases in 44m: 54.1.3, 54.2.0
info · registry-verified · 2021-03-22 · 5y ago
BURST
2 releases in 12m: 58.5.0, 58.5.1
info · registry-verified · 2021-11-03 · 4y ago
BURST
2 releases in 1m: 60.4.0, 60.5.0
info · registry-verified · 2022-01-08 · 4y ago
BURST
3 releases in 4m: 69.3.1, 69.4.1, 69.5.0
info · registry-verified · 2024-04-13 · 2y ago
BURST
2 releases in 51m: 74.1.3, 75.0.0
info · registry-verified · 2024-09-15 · 1y ago
BURST
2 releases in 8m: 75.3.1, 75.3.2
info · registry-verified · 2025-03-11 · 1y ago
BURST
2 releases in 19m: 80.6.0, 80.7.0
info · registry-verified · 2025-05-14 · 1y ago
BURST
2 releases in 56m: 75.3.4, 82.0.0
info · registry-verified · 2026-02-08 · 6mo ago
INSTALL-EXEC
setup.py in sdist uses install-hook, obfuscation (runs at pip install)
warn · snapshot-derived
release diff 83.0.0 → 84.0.0
+10 added · -3 removed · ~151 modified
+122 more files not shown
setuptools/_distutils/cmd.py +8 lines · 1 flagged
--- +++ @@ -14,3 +14,3 @@ from collections.abc import Callable, MutableSequence-from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, overload+from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast, overload @@ -104,3 +104,3 @@         # just to be safe.-        self.force = None+        self.force: bool | None = None @@ -316,3 +316,4 @@         """-        cmd_obj = self.distribution.get_command_obj(command, create)+        # TODO: Raise a more descriptive error when create=False or cmd_obj is None ?+        cmd_obj = cast(Command, self.distribution.get_command_obj(command, create))         cmd_obj.ensure_finalized()@@ -457,3 +458,3 @@ -        spawn(cmd, search_path)+        spawn(cmd) @@ -488,3 +489,3 @@     ) -> str:-        return archive_util.make_archive(+        return archive_util.make_archive(  # type: ignore[misc] # Mypy bailed out             base_name,@@ -516,3 +517,3 @@         if skip_msg is None:-            skip_msg = f"skipping {outfile} (inputs unchanged)"+            skip_msg = f"skipping {outfile!r} (inputs unchanged)" @@ -525,3 +526,3 @@         if exec_msg is None:-            exec_msg = "generating {} from {}".format(outfile, ', '.join(infiles))+            exec_msg = f"generating {outfile!r} from {', '.join(infiles)!r}" 
setuptools/_distutils/compilers/C/base.py +116 lines · 2 flagged
--- +++ @@ -10,2 +10,4 @@ import re+import shutil+import subprocess import sys@@ -23,19 +25,14 @@ -from ..._log import log-from ..._modified import newer_group-from ...dir_util import mkpath-from ...errors import (-    DistutilsModuleError,-    DistutilsPlatformError,-)-from ...file_util import move_file-from ...spawn import spawn-from ...util import execute, is_mingw, split_quoted-from .errors import (-    CompileError,-    LinkError,-    UnknownFileType,-)+from .._modified import newer_group+from .._util import split_quoted+from ..errors import PlatformError, UnknownFileType+from ..logging import get_logger+from ..platform import macos+from ..platform.detect import is_mingw+from .errors import CompileError, LinkError++log = get_logger(__name__)  if TYPE_CHECKING:+    from subprocess import _ENV     from typing import TypeAlias@@ -65,11 +62,15 @@ -    # 'compiler_type' is a class attribute that identifies this class.  It-    # keeps code that wants to know what kind of compiler it's dealing with-    # from having to import all possible compiler classes just to do an-    # 'isinstance'.  In concrete CCompiler subclasses, 'compiler_type'-    # should really, really be one of the keys of the 'compiler_class'-    # dictionary (see below -- used by the 'new_compiler()' factory-    # function) -- authors of new compiler interface classes are-    # responsible for updating 'compiler_class'!-    compiler_type: ClassVar[str] = None+    compiler_type: ClassVar[str]+    """+    Short name identifying the kind of compiler, so callers can tell+    compilers apart without importing every compiler class for an+    ``isinstance`` check. Set this in each concrete subclass; it's the key+    under which the class is registered by ``get_compilers()``.+    """++    description: ClassVar[str]+    """+    Human-readable description of the compiler, shown by ``show_compilers()``.+    Set this in each concrete subclass.+    """ @@ -81,3 +82,3 @@     #     class should have methods for the common ones.-    #   * can't completely override the include or library searchg+    #   * can't completely override the include or library search     #     path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2".@@ -123,3 +124,4 @@ -    include_dirs: list[str] = []+    # Not ClassVar: instances reassign these in __init__ and set_*_dirs.+    include_dirs: list[str] = []  # noqa: RUF012 # class-level default, overridden per instance     """@@ -128,3 +130,3 @@ -    library_dirs: list[str] = []+    library_dirs: list[str] = []  # noqa: RUF012 # class-level default, overridden per instance     """@@ -165,4 +167,23 @@ -        for key in self.executables.keys():+        for key in self.executables:             self.set_executable(key, self.executables[key])++    def initialize(self, plat_name: str | None = None) -> None:+        """Prepare the compiler for use, targeting the given platform.++        Most compilers configure themselves lazily on first use and so+        need no explicit initialization; for those this is a no-op. A+        compiler that must be initialized before use (e.g. MSVCCompiler,+        which resolves a Visual Studio environment) overrides this to+        honor ``plat_name`` when cross-compiling.+        """++    def configure_system(self) -> None:+        """Configure this compiler from the interpreter's build configuration.++        The default is a no-op; Unix-style compilers override this to apply+        the compiler, flag, and archiver settings that CPython recorded in+        sysconfig when it was built, so extensions build consistently with the+        interpreter.+        """ @@ -194,3 +215,3 @@ -        for key in kwargs:+        for key, value in kwargs.items():             if key not in self.executables:@@ -199,3 +220,3 @@                 )-            self.set_executable(key, kwargs[key])+            self.set_executable(key, value) @@ -208,7 +229,5 @@     def _find_macro(self, name):-        i = 0-        for defn in self.macros:+        for i, defn in enumerate(self.macros):             if defn[0] == name:                 return i-            i += 1         return None@@ -543,3 +562,3 @@         for source in sources:-            base, ext = os.path.splitext(source)+            _base, ext = os.path.splitext(source)             extlang = self.language_map.get(ext)@@ -575,3 +594,2 @@         """-        pass @@ -657,3 +675,2 @@         # should implement _compile().-        pass @@ -689,3 +706,2 @@         """-        pass @@ -1016,6 +1032,6 @@             output_dir = ''-        return list(+        return [             self._make_out_path(output_dir, strip_dir, src_name)             for src_name in source_filenames-        )+        ] @@ -1146,8 +1162,36 @@     ) -> None:-        execute(func, args, msg)+        if msg is None:+            msg = f"{func.__name__}{args!r}"+        log.info(msg)+        func(*args)++    def call(+        self,+        cmd: MutableSequence[bytes | str | os.PathLike[str]],+        *,+        env: _ENV | None = None,+        **kwargs,+    ) -> None:+        """Run 'cmd' in a subprocess, letting subprocess exceptions propagate."""+        log.info(subprocess.list2cmdline(cmd))+        subprocess.check_call(cmd, env=macos.inject_ver(env), **kwargs)      def spawn(-        self, cmd: MutableSequence[bytes | str | os.PathLike[str]], **kwargs+        self,+        cmd: MutableSequence[bytes | str | os.PathLike[str]],+        *,+        env: _ENV | None = None,+        **kwargs,     ) -> None:-        spawn(cmd, **kwargs)+        warnings.warn(+            "Compiler.spawn is deprecated; use Compiler.call instead.",+            DeprecationWarning,+            stacklevel=2,+        )+        # translation shared with distutils.spawn.spawn; imported late so the+        # clean `call` path stays free of the distutils dependency.+        from ...spawn import _translate_errors++        with _translate_errors(cmd):+            self.call(cmd, env=env, **kwargs) @@ -1166,6 +1210,7 @@     ) -> str | os.PathLike[str] | bytes | os.PathLike[bytes]:-        return move_file(src, dst)+        return shutil.move(src, dst)      def mkpath(self, name, mode=0o777):-        mkpath(name, mode)+        if name:+            os.makedirs(name, mode, exist_ok=True) @@ -1216,38 +1261,24 @@ -# Map compiler types to (module_name, class_name) pairs -- ie. where to-# find the code that implements an interface to this compiler.  (The module-# is assumed to be in the 'distutils' package.)-compiler_class = {-    'unix': ('unixccompiler', 'UnixCCompiler', "standard UNIX-style compiler"),-    'msvc': ('_msvccompiler', 'MSVCCompiler', "Microsoft Visual C++"),-    'cygwin': (-        'cygwinccompiler',-        'CygwinCCompiler',-        "Cygwin port of GNU C Compiler for Win32",-    ),-    'mingw32': (-        'cygwinccompiler',-        'Mingw32CCompiler',-        "Mingw32 port of GNU C Compiler for Win32",-    ),-    'bcpp': ('bcppcompiler', 'BCPPCompiler', "Borland C++ Compiler"),-    'zos': ('zosccompiler', 'zOSCCompiler', 'IBM XL C/C++ Compilers'),-}---def show_compilers() -> None:-    """Print list of available compilers (used by the "--help-compiler"-    options to "build", "build_ext", "build_clib").+def _concrete_compilers(cls: type[Compiler] | None = None):+    """Yield every subclass of ``cls`` (recursively)."""+    for subclass in (cls or Compiler).__subclasses__():+        yield subclass+        yield from _concrete_compilers(subclass)+++def get_compilers() -> dict[str, type[Compiler]]:+    """Map each compiler's short name (``compiler_type``) to its class.++    Imports the concrete compiler modules so their classes are defined, then+    collects every non-abstract ``Compiler`` subclass.     """-    # XXX this "knows" that the compiler option it's describing is-    # "--compiler", which just happens to be the case for the three-    # commands that use it.-    from distutils.fancy_getopt import FancyGetopt--    compilers = sorted(-        ("compiler=" + compiler, None, compiler_class[compiler][2])-        for compiler in compiler_class.keys()-    )-    pretty_printer = FancyGetopt(compilers)-    pretty_printer.print_help("List of available compilers:")+    # ensure the concrete compiler classes are imported and thus registered+    # as subclasses of Compiler
… 50 more lines (truncated)
setuptools/_distutils/compilers/C/cygwin.py +40 lines · 3 flagged
--- +++ @@ -14,18 +14,16 @@ import shlex+import subprocess import sys import warnings-from subprocess import check_output--from ...errors import (-    DistutilsExecError,-    DistutilsPlatformError,-)-from ...file_util import write_file-from ...sysconfig import get_config_vars-from ...version import LooseVersion, suppress_known_deprecation+from sysconfig import get_config_vars++import packaging.version++from ..errors import Error, PlatformError+from ..logging import get_logger+from ..platform.detect import is_mingw from . import unix-from .errors import (-    CompileError,-    Error,-)+from .errors import CompileError++log = get_logger(__name__) @@ -47,2 +45,3 @@     compiler_type = 'cygwin'+    description = "Cygwin port of GNU C Compiler for Win32"     obj_extension = ".o"@@ -80,6 +79,6 @@         self.set_executables(-            compiler=f'{self.cc} -mcygwin -O -Wall',-            compiler_so=f'{self.cc} -mcygwin -mdll -O -Wall',-            compiler_cxx=f'{self.cxx} -mcygwin -O -Wall',-            compiler_so_cxx=f'{self.cxx} -mcygwin -mdll -O -Wall',+            compiler=f'{self.cc} -mcygwin -O1 -Wall',+            compiler_so=f'{self.cc} -mcygwin -mdll -O1 -Wall',+            compiler_cxx=f'{self.cxx} -mcygwin -O1 -Wall',+            compiler_so_cxx=f'{self.cxx} -mcygwin -mdll -O1 -Wall',             linker_exe=f'{self.cc} -mcygwin',@@ -104,4 +103,3 @@         )-        with suppress_known_deprecation():-            return LooseVersion("11.2.0")+        return packaging.version.Version("11.2.0") @@ -112,4 +110,4 @@             try:-                self.spawn(["windres", "-i", src, "-o", obj])-            except DistutilsExecError as msg:+                self.call(["windres", "-i", src, "-o", obj])+            except (subprocess.CalledProcessError, OSError) as msg:                 raise CompileError(msg)@@ -118,3 +116,3 @@                 if self.detect_language(src) == 'c++':-                    self.spawn(+                    self.call(                         self.compiler_so_cxx@@ -125,6 +123,6 @@                 else:-                    self.spawn(+                    self.call(                         self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs                     )-            except DistutilsExecError as msg:+            except (subprocess.CalledProcessError, OSError) as msg:                 raise CompileError(msg)@@ -174,3 +172,3 @@             # name of dll to give the helper files the same base name-            (dll_name, dll_extension) = os.path.splitext(+            (dll_name, _dll_extension) = os.path.splitext(                 os.path.basename(output_filename)@@ -184,3 +182,4 @@             contents.extend(export_symbols)-            self.execute(write_file, (def_file, contents), f"writing {def_file}")+            log.info("writing %s", def_file)+            pathlib.Path(def_file).write_text('\n'.join(contents) + '\n') @@ -249,2 +248,3 @@     compiler_type = 'mingw32'+    description = "Mingw32 port of GNU C Compiler for Win32" @@ -259,6 +259,6 @@         self.set_executables(-            compiler=f'{self.cc} -O -Wall',-            compiler_so=f'{self.cc} -shared -O -Wall',-            compiler_so_cxx=f'{self.cxx} -shared -O -Wall',-            compiler_cxx=f'{self.cxx} -O -Wall',+            compiler=f'{self.cc} -O1 -Wall',+            compiler_so=f'{self.cc} -shared -O1 -Wall',+            compiler_so_cxx=f'{self.cxx} -shared -O1 -Wall',+            compiler_cxx=f'{self.cxx} -O1 -Wall',             linker_exe=f'{self.cc}',@@ -269,4 +269,11 @@ +    def configure_system(self) -> None:+        # Only apply the interpreter's Unix-style build configuration when+        # actually running under a mingw Python; on an MSVC Python those+        # settings don't apply.+        if is_mingw():+            super().configure_system()+     def runtime_library_dir_option(self, dir):-        raise DistutilsPlatformError(_runtime_library_dirs_msg)+        raise PlatformError(_runtime_library_dirs_msg) @@ -303,3 +310,3 @@ -    from distutils import sysconfig+    import sysconfig @@ -333,3 +340,3 @@     """Try to determine if the compiler that would be used is from cygwin."""-    out_string = check_output(shlex.split(cc) + ['-dumpmachine'])+    out_string = subprocess.check_output(shlex.split(cc) + ['-dumpmachine'])     return out_string.strip().endswith(b'cygwin')
setuptools/_distutils/compilers/C/msvc.py +104 lines · 6 flagged
--- +++ @@ -18,5 +18,6 @@ import subprocess-import unittest.mock as mock-import warnings-from collections.abc import Iterable+import tempfile+from collections.abc import Iterable, Iterator+from pathlib import Path+from typing import ClassVar @@ -27,15 +28,10 @@ -from ..._log import log-from ...errors import (-    DistutilsExecError,-    DistutilsPlatformError,-)-from ...util import get_host_platform, get_platform+from ..errors import PlatformError+from ..logging import get_logger+from ..platform.detect import get_host_platform, get_platform from . import base from .base import gen_lib_options-from .errors import (-    CompileError,-    LibError,-    LinkError,-)+from .errors import CompileError, LibError, LinkError++log = get_logger(__name__) @@ -135,3 +131,3 @@     if not best_dir:-        best_version, best_dir = _find_vc2015()+        _best_version, best_dir = _find_vc2015() @@ -155,3 +151,3 @@     if not vcvarsall:-        raise DistutilsPlatformError(+        raise PlatformError(             'Microsoft Visual C++ 14.0 or greater is required. '@@ -168,3 +164,3 @@         log.error(exc.output)-        raise DistutilsPlatformError(f"Error executing {exc.cmd}")+        raise PlatformError(f"Error executing {exc.cmd}") @@ -234,2 +230,66 @@ +_MAX_COMMAND_LENGTH = 2**15 - 1+"""+Windows limits a process command line to this many characters. See the+`CreateProcess documentation+<https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#parameters>`_.+"""+++def _response_file_content(args: Iterable[str]) -> str:+    r"""+    Render ``args`` as the content of a linker response file, one quoted+    argument per line.++    >>> print(_response_file_content(['/OUT:with space.dll', 'a.obj']))+    "/OUT:with space.dll"+    "a.obj"+    """+    return '\n'.join(f'"{arg}"' for arg in args)++[email protected]+def _wrap_link_command(*cmd: str) -> Iterator[list[str]]:+    r"""+    Yield ``cmd`` suitable for :meth:`Compiler.spawn`, honoring the Windows+    maximum command-line length (:data:`_MAX_COMMAND_LENGTH`).++    When ``cmd`` fits, yield it unchanged. Otherwise write the arguments to a+    temporary `response file+    <https://learn.microsoft.com/en-us/cpp/build/reference/linking?view=msvc-170#linker-command-files>`_+    and yield a command referencing it, removing the file once the command+    completes.++    Short commands pass through unchanged:++    >>> with _wrap_link_command('link.exe', 'a.obj') as spawn_cmd:+    ...     spawn_cmd+    ['link.exe', 'a.obj']++    Long commands are replaced by a reference to a response file, which is+    removed once the command completes:++    >>> import pathlib+    >>> args = ['/LIBPATH:' + 'x' * 100] * 400+    >>> with _wrap_link_command('link.exe', *args) as spawn_cmd:+    ...     spawn_cmd  # doctest: +ELLIPSIS+    ...     response_file = pathlib.Path(spawn_cmd[1][1:])+    ...     response_file.exists()+    ['link.exe', '@...rsp']+    True+    >>> response_file.exists()+    False+    """+    if len(subprocess.list2cmdline(cmd)) <= _MAX_COMMAND_LENGTH:+        yield list(cmd)+        return++    linker, *args = cmd+    with tempfile.TemporaryDirectory() as tmpdir:+        # utf-16 gives the linker an unambiguous, BOM-prefixed encoding.+        response_file = Path(tmpdir) / 'link.rsp'+        response_file.write_text(_response_file_content(args), encoding='utf-16')+        yield [linker, f'@{response_file}']++ class Compiler(base.Compiler):@@ -239,2 +299,3 @@     compiler_type = 'msvc'+    description = "Microsoft Visual C++" @@ -245,9 +306,9 @@     # though, so it's worth thinking about.-    executables = {}+    executables: ClassVar[dict] = {}      # Private class data (need to distinguish C from C++ source for compiler)-    _c_extensions = ['.c']-    _cpp_extensions = ['.cc', '.cpp', '.cxx']-    _rc_extensions = ['.rc']-    _mc_extensions = ['.mc']+    _c_extensions: ClassVar[list[str]] = ['.c']+    _cpp_extensions: ClassVar[list[str]] = ['.cc', '.cpp', '.cxx']+    _rc_extensions: ClassVar[list[str]] = ['.rc']+    _mc_extensions: ClassVar[list[str]] = ['.mc'] @@ -288,5 +349,3 @@         if plat_name not in _vcvars_names:-            raise DistutilsPlatformError(-                f"--plat-name must be one of {tuple(_vcvars_names)}"-            )+            raise PlatformError(f"--plat-name must be one of {tuple(_vcvars_names)}") @@ -296,3 +355,3 @@         if not vc_env:-            raise DistutilsPlatformError(+            raise PlatformError(                 "Unable to find a compatible Visual Studio installation."@@ -420,4 +479,4 @@                 try:-                    self.spawn([self.rc] + pp_opts + [output_opt, input_opt])-                except DistutilsExecError as msg:+                    self.call([self.rc] + pp_opts + [output_opt, input_opt])+                except (subprocess.CalledProcessError, OSError) as msg:                     raise CompileError(msg)@@ -440,3 +499,3 @@                     # first compile .MC to .RC and .H file-                    self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src])+                    self.call([self.mc, '-h', h_dir, '-r', rc_dir, src])                     base, _ = os.path.splitext(os.path.basename(src))@@ -444,5 +503,5 @@                     # then compile .RC to .RES file-                    self.spawn([self.rc, "/fo" + obj, rc_file])--                except DistutilsExecError as msg:+                    self.call([self.rc, "/fo" + obj, rc_file])++                except (subprocess.CalledProcessError, OSError) as msg:                     raise CompileError(msg)@@ -460,4 +519,4 @@             try:-                self.spawn(args)-            except DistutilsExecError as msg:+                self.call(args)+            except (subprocess.CalledProcessError, OSError) as msg:                 raise CompileError(msg)@@ -485,4 +544,4 @@                 log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args))-                self.spawn([self.lib] + lib_args)-            except DistutilsExecError as msg:+                self.call([self.lib] + lib_args)+            except (subprocess.CalledProcessError, OSError) as msg:                 raise LibError(msg)@@ -539,3 +598,3 @@             if export_symbols is not None:-                (dll_name, dll_ext) = os.path.splitext(+                (dll_name, _dll_ext) = os.path.splitext(                     os.path.basename(output_filename)@@ -554,4 +613,5 @@                 log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args))-                self.spawn([self.linker] + ld_args)-            except DistutilsExecError as msg:+                with _wrap_link_command(self.linker, *ld_args) as cmd:+                    self.call(cmd)+            except (subprocess.CalledProcessError, OSError) as msg:                 raise LinkError(msg)@@ -560,26 +620,5 @@ -    def spawn(self, cmd):+    def call(self, cmd, *, env=None, **kwargs):         env = dict(os.environ, PATH=self._paths)-        with self._fallback_spawn(cmd, env) as fallback:-            return super().spawn(cmd, env=env)-        return fallback.value--    @contextlib.contextmanager-    def _fallback_spawn(self, cmd, env):-        """-        Discovered in pypa/distutils#15, some tools monkeypatch the compiler,-        so the 'env' kwarg causes a TypeError. Detect this condition and-        restore the legacy, unsafe behavior.-        """-        bag = type('Bag', (), {})()-        try:-            yield bag-        except TypeError as exc:-            if "unexpected keyword argument 'env'" not in str(exc):-                raise-        else:-            return-        warnings.warn("Fallback spawn triggered. Please update distutils monkeypatch.")-        with mock.patch.dict('os.environ', env):-            bag.value = super().spawn(cmd)+        return super().call(cmd, env=env, **kwargs) @@ -593,3 +632,3 @@     def runtime_library_dir_option(self, dir):-        raise DistutilsPlatformError(+        raise PlatformError(             "don't know how to set runtime library search path for MSVC"@@ -612,4 +651,3 @@                     return libfile-        else:-            # Oops, didn't find it in *any* of 'dirs'-            return None+        # Oops, didn't find it in *any* of 'dirs'+        return None
setuptools/_distutils/compilers/C/unix.py +140 lines · 4 flagged
--- +++ @@ -21,18 +21,36 @@ import shlex+import subprocess import sys+import sysconfig from collections.abc import Iterable--from ... import sysconfig-from ..._log import log-from ..._macos_compat import compiler_fixup-from ..._modified import newer-from ...compat import consolidate_linker_args-from ...errors import DistutilsExecError+from typing import ClassVar++from jaraco.functools import pass_none++from .._modified import newer+from ..logging import get_logger+from ..platform import macos+from ..platform.macos import compiler_fixup from . import base from .base import _Macro, gen_lib_options, gen_preprocess_options-from .errors import (-    CompileError,-    LibError,-    LinkError,-)+from .errors import CompileError, LibError, LinkError++log = get_logger(__name__)+++def _require_config_vars(*names):+    values = sysconfig.get_config_vars(*names)+    missing = [+        name for name, value in zip(names, values, strict=False) if value is None+    ]+    assert not missing, f"Unexpected None in config vars: {missing}"+    return values+++@pass_none+def _add_flags(value: str, flag_type: str) -> str:+    """Append any ``$<flag_type>FLAGS`` from the environment to ``value``."""+    flags = os.environ.get(f'{flag_type}FLAGS')+    return f'{value} {flags}' if flags else value+ @@ -116,2 +134,3 @@     compiler_type = 'unix'+    description = "standard UNIX-style compiler" @@ -123,3 +142,3 @@     # Python extensions).-    executables = {+    executables: ClassVar[dict] = {         'preprocessor': None,@@ -146,3 +165,10 @@ -    src_extensions = [".c", ".C", ".cc", ".cxx", ".cpp", ".m"]+    src_extensions: ClassVar[list[str] | None] = [+        ".c",+        ".C",+        ".cc",+        ".cxx",+        ".cpp",+        ".m",+    ]     obj_extension = ".o"@@ -159,2 +185,84 @@         dylib_lib_format = "cyg%s%s"++    def configure_system(self) -> None:+        """Configure this compiler from the interpreter's build configuration.++        Applies the compiler, flag, and archiver settings CPython recorded in+        sysconfig when it was built -- honoring the usual environment-variable+        overrides (CC, CXX, CFLAGS, LDSHARED, AR, RANLIB, …) -- so extensions+        build consistently with the interpreter.+        """+        macos.customize_compiler(sysconfig.get_config_vars())++        (+            cc,+            cxx,+            cflags,+            ccshared,+            ldshared,+            ldcxxshared,+            shlib_suffix,+            ar,+            ar_flags,+        ) = _require_config_vars(+            'CC',+            'CXX',+            'CFLAGS',+            'CCSHARED',+            'LDSHARED',+            'LDCXXSHARED',+            'SHLIB_SUFFIX',+            'AR',+            'ARFLAGS',+        )++        cxxflags = cflags++        if 'CC' in os.environ:+            newcc = os.environ['CC']+            if 'LDSHARED' not in os.environ and ldshared.startswith(cc):+                # If CC is overridden, use that as the default command for+                # LDSHARED as well.+                ldshared = newcc + ldshared[len(cc) :]+            cc = newcc+        cxx = os.environ.get('CXX', cxx)+        ldshared = os.environ.get('LDSHARED', ldshared)+        ldcxxshared = os.environ.get('LDCXXSHARED', ldcxxshared)+        cpp = os.environ.get('CPP', cc + " -E")++        ldshared = _add_flags(ldshared, 'LD')+        ldcxxshared = _add_flags(ldcxxshared, 'LD')+        cflags = os.environ.get('CFLAGS', cflags)+        ldshared = _add_flags(ldshared, 'C')+        cxxflags = os.environ.get('CXXFLAGS', cxxflags)+        ldcxxshared = _add_flags(ldcxxshared, 'CXX')+        cpp = _add_flags(cpp, 'CPP')+        cflags = _add_flags(cflags, 'CPP')+        cxxflags = _add_flags(cxxflags, 'CPP')+        ldshared = _add_flags(ldshared, 'CPP')+        ldcxxshared = _add_flags(ldcxxshared, 'CPP')++        ar = os.environ.get('AR', ar)++        archiver = ar + ' ' + os.environ.get('ARFLAGS', ar_flags)+        cc_cmd = cc + ' ' + cflags+        cxx_cmd = cxx + ' ' + cxxflags++        self.set_executables(+            preprocessor=cpp,+            compiler=cc_cmd,+            compiler_so=cc_cmd + ' ' + ccshared,+            compiler_cxx=cxx_cmd,+            compiler_so_cxx=cxx_cmd + ' ' + ccshared,+            linker_so=ldshared,+            linker_so_cxx=ldcxxshared,+            linker_exe=cc,+            linker_exe_cxx=cxx,+            archiver=archiver,+        )++        if 'RANLIB' in os.environ and self.executables.get('ranlib', None):+            self.set_executables(ranlib=os.environ['RANLIB'])++        self.shared_lib_extension = shlib_suffix  # type: ignore[misc] # Assigning to ClassVar @@ -184,3 +292,3 @@         fixed_args = self._fix_compile_args(None, macros, include_dirs)-        ignore, macros, include_dirs = fixed_args+        _ignore, macros, include_dirs = fixed_args         pp_opts = gen_preprocess_options(macros, include_dirs)@@ -207,4 +315,4 @@         try:-            self.spawn(pp_args)-        except DistutilsExecError as msg:+            self.call(pp_args)+        except (subprocess.CalledProcessError, OSError) as msg:             raise CompileError(msg)@@ -216,8 +324,6 @@             if self.detect_language(src) == 'c++':-                self.spawn(-                    compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs-                )+                self.call(compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs)             else:-                self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs)-        except DistutilsExecError as msg:+                self.call(compiler_so + cc_args + [src, '-o', obj] + extra_postargs)+        except (subprocess.CalledProcessError, OSError) as msg:             raise CompileError(msg)@@ -233,3 +339,3 @@             self.mkpath(os.path.dirname(output_filename))-            self.spawn(self.archiver + [output_filename] + objects + self.objects)+            self.call(self.archiver + [output_filename] + objects + self.objects) @@ -242,4 +348,4 @@                 try:-                    self.spawn(self.ranlib + [output_filename])-                except DistutilsExecError as msg:+                    self.call(self.ranlib + [output_filename])+                except (subprocess.CalledProcessError, OSError) as msg:                     raise LibError(msg)@@ -306,4 +412,4 @@ -                self.spawn(linker + ld_args)-            except DistutilsExecError as msg:+                self.call(linker + ld_args)+            except (subprocess.CalledProcessError, OSError) as msg:                 raise LinkError(msg)@@ -338,6 +444,6 @@         if sys.platform[:6] == "darwin":-            from distutils.util import get_macosx_target_ver, split_version--            macosx_target_ver = get_macosx_target_ver()-            if macosx_target_ver and split_version(macosx_target_ver) >= [10, 5]:+            from ..platform import macos++            target_ver = macos.target_ver()+            if target_ver and [int(n) for n in target_ver.split('.')] >= [10, 5]:                 return "-Wl,-rpath," + dir@@ -356,3 +462,3 @@         if sysconfig.get_config_var("GNULD") == "yes":-            return consolidate_linker_args([+            return [                 # Force RUNPATH instead of RPATH@@ -360,3 +466,3 @@                 "-Wl,-rpath," + dir,-            ])+            ]         else:@@ -411,3 +517,3 @@             self.library_filename(lib, lib_type=type)-            for type in 'dylib xcode_stub shared static'.split()+            for type in ('dylib', 'xcode_stub', 'shared', 'static')         )
setuptools/_distutils/compilers/C/zos.py +21 lines · 1 flagged
--- +++ @@ -14,5 +14,6 @@ import os--from ... import sysconfig-from ...errors import DistutilsExecError+import subprocess+import sysconfig+from typing import ClassVar+ from . import unix@@ -105,5 +106,15 @@ class Compiler(unix.Compiler):-    src_extensions = ['.c', '.C', '.cc', '.cxx', '.cpp', '.m', '.s']-    _cpp_extensions = ['.cc', '.cpp', '.cxx', '.C']-    _asm_extensions = ['.s']+    compiler_type = 'zos'+    description = "IBM XL C/C++ Compilers"+    src_extensions: ClassVar[list[str] | None] = [+        '.c',+        '.C',+        '.cc',+        '.cxx',+        '.cpp',+        '.m',+        '.s',+    ]+    _cpp_extensions: ClassVar[list[str]] = ['.cc', '.cpp', '.cxx', '.C']+    _asm_extensions: ClassVar[list[str]] = ['.s'] @@ -141,3 +152,3 @@         self.zos_compiler = self._get_zos_compiler_name()-        sysconfig.customize_compiler(self)+        self.configure_system() @@ -158,4 +169,4 @@         try:-            self.spawn(compiler + local_args + [src, '-o', obj] + extra_postargs)-        except DistutilsExecError as msg:+            self.call(compiler + local_args + [src, '-o', obj] + extra_postargs)+        except (subprocess.CalledProcessError, OSError) as msg:             raise CompileError(msg)@@ -184,3 +195,3 @@         ldversion = sysconfig.get_config_var('LDVERSION')-        if sysconfig.python_build:+        if sysconfig.is_python_build():             side_deck_path = os.path.join(
setuptools/_distutils/core.py +7 lines · 1 flagged
--- +++ @@ -27,4 +27,5 @@ from .extension import Extension--__all__ = ['Distribution', 'Command', 'Extension', 'setup']+from .extension import _safe as extension_keywords  # noqa  # backwards compatibility++__all__ = ['Command', 'Distribution', 'Extension', 'setup'] @@ -76,21 +77,2 @@ -# Legal keyword arguments for the Extension constructor-extension_keywords = (-    'name',-    'sources',-    'include_dirs',-    'define_macros',-    'undef_macros',-    'library_dirs',-    'libraries',-    'runtime_library_dirs',-    'extra_objects',-    'extra_compile_args',-    'extra_link_args',-    'swig_opts',-    'export_symbols',-    'depends',-    'language',-)- @@ -129,3 +111,3 @@ -    global _setup_stop_after, _setup_distribution+    global _setup_distribution @@ -215,3 +197,3 @@         else:-            raise SystemExit("error: " + str(msg))+            raise SystemExit(f"error: {msg}") @@ -254,3 +236,3 @@ -    global _setup_stop_after, _setup_distribution+    global _setup_stop_after     _setup_stop_after = stop_after@@ -267,3 +249,3 @@                 code = f.read().replace(r'\r\n', r'\n')-                exec(code, g)+                exec(code, g)  # noqa: S102 # executing the setup script is the point         finally:
setuptools/_distutils/spawn.py +18 lines · 4 flagged
--- +++ @@ -8,5 +8,4 @@ +import contextlib import os-import platform-import shutil import subprocess@@ -14,48 +13,22 @@ import warnings-from collections.abc import Mapping, MutableSequence-from typing import TYPE_CHECKING, TypeVar, overload+from collections.abc import MutableSequence  from ._log import log-from .debug import DEBUG from .errors import DistutilsExecError -if TYPE_CHECKING:-    from subprocess import _ENV+[email protected]+def _translate_errors(cmd):+    """Reraise a subprocess failure running 'cmd' as a DistutilsExecError."""+    try:+        yield+    except OSError as exc:+        raise DistutilsExecError(f"command {cmd[0]!r} failed: {exc.args[-1]}") from exc+    except subprocess.CalledProcessError as err:+        raise DistutilsExecError(+            f"command {cmd[0]!r} failed with exit code {err.returncode}"+        ) from err  -_MappingT = TypeVar("_MappingT", bound=Mapping)---def _debug(cmd):-    """-    Render a subprocess command differently depending on DEBUG.-    """-    return cmd if DEBUG else cmd[0]---def _inject_macos_ver(env: _MappingT | None) -> _MappingT | dict[str, str | int] | None:-    if platform.system() != 'Darwin':-        return env--    from .util import MACOSX_VERSION_VAR, get_macosx_target_ver--    target_ver = get_macosx_target_ver()-    update = {MACOSX_VERSION_VAR: target_ver} if target_ver else {}-    return {**_resolve(env), **update}---@overload-def _resolve(env: None) -> os._Environ[str]: ...-@overload-def _resolve(env: _MappingT) -> _MappingT: ...-def _resolve(env: _MappingT | None) -> _MappingT | os._Environ[str]:-    return os.environ if env is None else env---def spawn(-    cmd: MutableSequence[bytes | str | os.PathLike[str]],-    search_path: bool = True,-    verbose: bool = False,-    env: _ENV | None = None,-) -> None:+def spawn(cmd: MutableSequence[bytes | str | os.PathLike[str]], **kwargs) -> None:     """Run another program, specified as a command list 'cmd', in a new process.@@ -64,8 +37,3 @@     cmd[0] is the program to run and cmd[1:] are the rest of its arguments.-    There is no way to run a program with a name different from that of its-    executable.--    If 'search_path' is true (the default), the system's executable-    search path will be used to find the program; otherwise, cmd[0]-    must be the exact path to the executable.+    Any keyword arguments are passed through to ``subprocess.check_call``. @@ -75,18 +43,4 @@     log.info(subprocess.list2cmdline(cmd))--    if search_path:-        executable = shutil.which(cmd[0])-        if executable is not None:-            cmd[0] = executable--    try:-        subprocess.check_call(cmd, env=_inject_macos_ver(env))-    except OSError as exc:-        raise DistutilsExecError(-            f"command {_debug(cmd)!r} failed: {exc.args[-1]}"-        ) from exc-    except subprocess.CalledProcessError as err:-        raise DistutilsExecError(-            f"command {_debug(cmd)!r} failed with exit code {err.returncode}"-        ) from err+    with _translate_errors(cmd):+        subprocess.check_call(cmd, **kwargs) 
setuptools/build_meta.py +8 lines · 1 flagged
--- +++ @@ -57,12 +57,12 @@ __all__ = [+    'SetupRequirementsError',+    '__legacy__',+    'build_editable',+    'build_sdist',+    'build_wheel',+    'get_requires_for_build_editable',     'get_requires_for_build_sdist',     'get_requires_for_build_wheel',+    'prepare_metadata_for_build_editable',     'prepare_metadata_for_build_wheel',-    'build_wheel',-    'build_sdist',-    'get_requires_for_build_editable',-    'prepare_metadata_for_build_editable',-    'build_editable',-    '__legacy__',-    'SetupRequirementsError', ]@@ -316,3 +316,3 @@         try:-            exec(code, locals())+            exec(code, locals())  # noqa: S102 # exec is intentional here         except SystemExit as e:
setuptools/extension.py +2 lines · 1 flagged
--- +++ @@ -23,4 +23,4 @@         # from (cython_impl) import build_ext-        __import__(cython_impl, fromlist=['build_ext']).build_ext-    except Exception:+        __import__(cython_impl, fromlist=['build_ext']).build_ext  # noqa: B018 # evaluated to trigger validation/side effect+    except Exception:  # noqa: BLE001 # intentional broad fallback         return False
setuptools/launch.py +2 lines · 1 flagged
--- +++ @@ -17,3 +17,3 @@     """-    __builtins__+    __builtins__  # noqa: B018 # evaluated to trigger validation/side effect     script_name = sys.argv[1]@@ -31,3 +31,3 @@     code = compile(norm_script, script_name, 'exec')-    exec(code, namespace)+    exec(code, namespace)  # noqa: S102 # exec is intentional here 
setuptools/tests/test_bdist_wheel.py +37 lines · 1 flagged
--- +++ @@ -191,24 +191,38 @@ -if sys.platform != "win32":-    # ABI3 extensions don't really work on Windows-    EXAMPLES["abi3extension-dist"] = {-        "setup.py": cleandoc(-            """-            from setuptools import Extension, setup--            setup(-                name="extension.dist",-                version="0.1",-                description="A testing distribution \N{SNOWMAN}",-                ext_modules=[-                    Extension(-                        name="extension", sources=["extension.c"], py_limited_api=True-                    )-                ],-            )-            """-        ),-        "setup.cfg": "[bdist_wheel]\npy_limited_api=cp32",-        "extension.c": "#define Py_LIMITED_API 0x03020000\n#include <Python.h>",-    }+def abi3extension_dist():+    if sys.platform == 'win32':+        # ABI3 extensions don't really work on Windows.+        return++    if sysconfig.get_config_var('Py_GIL_DISABLED'):+        # Free-threaded builds also reject Py_LIMITED_API for now.+        # See https://github.com/python/cpython/issues/146636 (PEP 803 / abi3t).+        return++    yield (+        'abi3extension-dist',+        {+            "setup.py": cleandoc(+                """+                from setuptools import Extension, setup++                setup(+                    name="extension.dist",+                    version="0.1",+                    description="A testing distribution \N{SNOWMAN}",+                    ext_modules=[+                        Extension(+                            name="extension", sources=["extension.c"], py_limited_api=True+                        )+                    ],+                )+                """+            ),+            "setup.cfg": "[bdist_wheel]\npy_limited_api=cp32",+            "extension.c": "#define Py_LIMITED_API 0x03020000\n#include <Python.h>",+        },+    )+++EXAMPLES.update(abi3extension_dist()) @@ -357,3 +371,3 @@             "dummy_dist-1.0.dist-info/licenses/" + fname-            for fname in {"licenses_dir/DUMMYFILE", "LICENSE"}+            for fname in ("licenses_dir/DUMMYFILE", "LICENSE")         }
_distutils_hack/__init__.py +1 lines
--- +++ @@ -120,3 +120,3 @@             mod = importlib.import_module('setuptools._distutils')-        except Exception:+        except Exception:  # noqa: BLE001 # intentional broad fallback             # There are a couple of cases where setuptools._distutils
pyproject.toml +6 lines
--- +++ @@ -12,3 +12,3 @@ name = "setuptools"-version = "83.0.0"+version = "84.0.0" authors = [@@ -131,3 +131,3 @@ 	-    # Exclude PyPy from type checks (python/mypy#20454 jaraco/skeleton#187)+	# Exclude PyPy from type checks (python/mypy#20454 jaraco/skeleton#187) 	"pytest-mypy >= 1.0.1; platform_python_implementation != 'PyPy'",@@ -216,2 +216,6 @@ "*" = ["ruff.toml"]+# Avoid shipping setuptools' own test suite in wheels (#5212)+"setuptools" = ["tests/*"]+"setuptools._distutils" = ["tests/*"]+"setuptools._distutils.compilers.C" = ["tests/*"] 
setuptools/__init__.py +4 lines
--- +++ @@ -33,5 +33,4 @@ __all__ = [-    'setup',+    'Command',     'Distribution',-    'Command',     'Extension',@@ -39,4 +38,5 @@     'SetuptoolsDeprecationWarning',+    'find_namespace_packages',     'find_packages',-    'find_namespace_packages',+    'setup', ]@@ -71,3 +71,3 @@                 cfg, _toml = super()._split_standard_project_metadata(filenames)-            except Exception:+            except Exception:  # noqa: BLE001 # intentional broad fallback                 return filenames, ()
setuptools/_discovery.py +2 lines
--- +++ @@ -12,3 +12,3 @@         markers = ()-    return set(+    return {         marker[2].value@@ -16,3 +16,3 @@         if isinstance(marker, tuple) and marker[0].value == 'extra'-    )+    } 
setuptools/_distutils/_modified.py +1 lines
--- +++ @@ -11,3 +11,2 @@ -from .compat.py39 import zip_strict from .errors import DistutilsFileError@@ -59,3 +58,3 @@     """-    newer_pairs = filter(splat(newer), zip_strict(sources, targets))+    newer_pairs = filter(splat(newer), zip(sources, targets, strict=True))     return tuple(map(list, zip(*newer_pairs, strict=False))) or ([], [])
setuptools/_distutils/archive_util.py +24 lines
--- +++ @@ -7,10 +7,7 @@ +import contextlib import os+from collections.abc import Callable+from types import ModuleType from typing import Literal, overload--try:-    import zipfile-except ImportError:-    zipfile = None- @@ -21,11 +18,11 @@ -try:-    from pwd import getpwnam-except ImportError:-    getpwnam = None--try:-    from grp import getgrnam-except ImportError:-    getgrnam = None+zipfile: ModuleType | None = None+with contextlib.suppress(ImportError):+    import zipfile++grp: ModuleType | None = None+pwd: ModuleType | None = None+with contextlib.suppress(ImportError):+    import grp+    import pwd @@ -34,6 +31,6 @@     """Returns a gid, given a group name."""-    if getgrnam is None or name is None:+    if grp is None or name is None:         return None     try:-        result = getgrnam(name)+        result = grp.getgrnam(name)     except KeyError:@@ -47,6 +44,6 @@     """Returns an uid, given a user name."""-    if getpwnam is None or name is None:+    if pwd is None or name is None:         return None     try:-        result = getpwnam(name)+        result = pwd.getpwnam(name)     except KeyError:@@ -89,3 +86,3 @@     # flags for compression program, each element of list will be an argument-    if compress is not None and compress not in compress_ext.keys():+    if compress is not None and compress not in compress_ext:         raise ValueError(@@ -116,7 +113,6 @@ -    tar = tarfile.open(archive_name, f'w|{tar_compression[compress]}')-    try:+    with tarfile.open(  # type: ignore[call-overload] # Dynamic mode+        archive_name, f'w|{tar_compression[compress]}'+    ) as tar:         tar.add(base_dir, filter=_set_uid_gid)-    finally:-        tar.close() @@ -187,3 +183,5 @@ -ARCHIVE_FORMATS = {+ARCHIVE_FORMATS: dict[+    str, tuple[Callable[..., str], list[tuple[str, str | None]], str]+] = {     'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),@@ -262,3 +260,3 @@ -    kwargs: dict[str, bool | None] = {}+    kwargs: dict[str, str | bool | None] = {} 
setuptools/_distutils/ccompiler.py +17 lines
--- +++ @@ -8,5 +8,5 @@     gen_preprocess_options,+    get_compilers,     get_default_compiler,     new_compiler,-    show_compilers, )@@ -26 +26,17 @@ CCompiler = base.Compiler+++def show_compilers() -> None:+    """Print list of available compilers (used by the "--help-compiler"+    options to "build", "build_ext", "build_clib").+    """+    # XXX this "knows" that the compiler option it's describing is+    # "--compiler", which just happens to be the case for the three+    # commands that use it.+    from .fancy_getopt import FancyGetopt++    compilers = sorted(+        ("compiler=" + name, None, cls.description)+        for name, cls in get_compilers().items()+    )+    FancyGetopt(compilers).print_help("List of available compilers:")
setuptools/_distutils/command/__init__.py +12 lines
--- +++ @@ -6,14 +6,2 @@ __all__ = [-    'build',-    'build_py',-    'build_ext',-    'build_clib',-    'build_scripts',-    'clean',-    'install',-    'install_lib',-    'install_headers',-    'install_scripts',-    'install_data',-    'sdist',     'bdist',@@ -21,3 +9,15 @@     'bdist_rpm',+    'build',+    'build_clib',+    'build_ext',+    'build_py',+    'build_scripts',     'check',+    'clean',+    'install',+    'install_data',+    'install_headers',+    'install_lib',+    'install_scripts',+    'sdist', ]
setuptools/_distutils/command/_framework_compat.py +12 lines
--- +++ @@ -25,14 +25,14 @@ -schemes = dict(-    osx_framework_library=dict(-        stdlib='{installed_base}/{platlibdir}/python{py_version_short}',-        platstdlib='{platbase}/{platlibdir}/python{py_version_short}',-        purelib='{homebrew_prefix}/lib/python{py_version_short}/site-packages',-        platlib='{homebrew_prefix}/{platlibdir}/python{py_version_short}/site-packages',-        include='{installed_base}/include/python{py_version_short}{abiflags}',-        platinclude='{installed_platbase}/include/python{py_version_short}{abiflags}',-        scripts='{homebrew_prefix}/bin',-        data='{homebrew_prefix}',-    )-)+schemes = {+    'osx_framework_library': {+        'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}',+        'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}',+        'purelib': '{homebrew_prefix}/lib/python{py_version_short}/site-packages',+        'platlib': '{homebrew_prefix}/{platlibdir}/python{py_version_short}/site-packages',+        'include': '{installed_base}/include/python{py_version_short}{abiflags}',+        'platinclude': '{installed_platbase}/include/python{py_version_short}{abiflags}',+        'scripts': '{homebrew_prefix}/bin',+        'data': '{homebrew_prefix}',+    }+} 
setuptools/_distutils/command/bdist.py +7 lines
--- +++ @@ -50,3 +50,5 @@ -    user_options = [+    user_options: ClassVar[+        list[tuple[str, str, str]] | list[tuple[str, str | None, str]]+    ] = [         ('bdist-base=', 'b', "temporary directory for creating built distributions"),@@ -55,4 +57,6 @@             'p',-            "platform name to embed in generated filenames "-            f"[default: {get_platform()}]",+            (+                "platform name to embed in generated filenames "+                f"[default: {get_platform()}]"+            ),         ),
setuptools/_distutils/command/bdist_dumb.py +8 lines
--- +++ @@ -20,3 +20,5 @@ -    user_options = [+    user_options: ClassVar[+        list[tuple[str, str, str]] | list[tuple[str, str | None, str]]+    ] = [         ('bdist-dir=', 'd', "temporary directory for creating the distribution"),@@ -25,4 +27,6 @@             'p',-            "platform name to embed in generated filenames "-            f"[default: {get_platform()}]",+            (+                "platform name to embed in generated filenames "+                f"[default: {get_platform()}]"+            ),         ),@@ -59,3 +63,3 @@ -    default_format = {'posix': 'gztar', 'nt': 'zip'}+    default_format: ClassVar[dict[str, str]] = {'posix': 'gztar', 'nt': 'zip'} 
setuptools/_distutils/command/bdist_rpm.py +23 lines
--- +++ @@ -26,3 +26,5 @@ -    user_options = [+    user_options: ClassVar[+        list[tuple[str, str, str]] | list[tuple[str, str | None, str]]+    ] = [         ('bdist-base=', None, "base directory for creating built distributions"),@@ -31,4 +33,6 @@             None,-            "base directory for creating RPMs (defaults to \"rpm\" under "-            "--bdist-base; must be specified for RPM 2)",+            (+                "base directory for creating RPMs (defaults to \"rpm\" under "+                "--bdist-base; must be specified for RPM 2)"+            ),         ),@@ -42,4 +46,6 @@             None,-            "path to Python interpreter to hard-code in the .spec file "-            "[default: \"python\"]",+            (+                "path to Python interpreter to hard-code in the .spec file "+                "[default: \"python\"]"+            ),         ),@@ -48,4 +54,6 @@             None,-            "hard-code the exact path to the current Python interpreter in "-            "the .spec file",+            (+                "hard-code the exact path to the current Python interpreter in "+                "the .spec file"+            ),         ),@@ -63,4 +71,6 @@             None,-            "name of the (Linux) distribution to which this "-            "RPM applies (*not* the name of the module distribution!)",+            (+                "name of the (Linux) distribution to which this "+                "RPM applies (*not* the name of the module distribution!)"+            ),         ),@@ -72,4 +82,6 @@             None,-            "RPM \"vendor\" (eg. \"Joe Blow <[email protected]>\") "-            "[default: maintainer or author from setup script]",+            (+                "RPM \"vendor\" (eg. \"Joe Blow <[email protected]>\") "+                "[default: maintainer or author from setup script]"+            ),         ),
setuptools/_distutils/command/build.py +5 lines
--- +++ @@ -10,3 +10,3 @@ from collections.abc import Callable-from typing import ClassVar+from typing import Any, ClassVar @@ -21,3 +21,5 @@ -    user_options = [+    user_options: ClassVar[+        list[tuple[str, str, str]] | list[tuple[str, str | None, str]]+    ] = [         ('build-base=', 'b', "base directory for build library"),@@ -150,3 +152,3 @@ -    sub_commands = [+    sub_commands: ClassVar[list[tuple[str, Callable[[Any], bool] | None]]] = [         ('build_py', has_pure_modules),
urllib3 pypi
2.7.0 3mo ago incident on record
critical-tier YANK ×4BURST ×3
latest 2.7.0 versions 108 maintainers 1 critical-tier (snapshotted)
2.2.2
1.26.19
1.26.20
2.2.3
2.3.0
2.4.0
2.5.0
2.6.0
2.6.1
2.6.2
2.6.3
2.7.0
YANK
1.25 marked yanked (still downloadable)
high · registry-verified · 2019-04-22 · 7y ago
YANK
1.25.1 marked yanked (still downloadable)
high · registry-verified · 2019-04-24 · 7y ago
YANK
2.0.0 marked yanked (still downloadable)
high · registry-verified · 2023-04-26 · 3y ago
YANK
2.0.1 marked yanked (still downloadable)
high · registry-verified · 2023-04-30 · 3y ago
BURST
2 releases in 2m: 1.9.1, 1.10
info · registry-verified · 2014-12-14 · 11y ago
BURST
2 releases in 0m: 1.26.17, 2.0.6
info · registry-verified · 2023-10-02 · 2y ago
BURST
2 releases in 0m: 2.0.7, 1.26.18
info · registry-verified · 2023-10-17 · 2y ago
release diff 2.6.3 → 2.7.0
+0 added · -0 removed · ~40 modified
+9 more files not shown
src/urllib3/connection.py +4 lines · 2 flagged
--- +++ @@ -533,4 +533,4 @@             "HTTPConnection.request_chunked() is deprecated and will be removed "-            "in urllib3 v2.1.0. Instead use HTTPConnection.request(..., chunked=True).",-            category=DeprecationWarning,+            "in urllib3 v3.0. Instead use HTTPConnection.request(..., chunked=True).",+            category=FutureWarning,             stacklevel=2,@@ -699,5 +699,5 @@             "HTTPSConnection.set_cert() is deprecated and will be removed "-            "in urllib3 v2.1.0. Instead provide the parameters to the "+            "in urllib3 v3.0. Instead provide the parameters to the "             "HTTPSConnection constructor.",-            category=DeprecationWarning,+            category=FutureWarning,             stacklevel=2,
src/urllib3/connectionpool.py +23 lines · 1 flagged
--- +++ @@ -218,4 +218,4 @@             # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.-            # We cannot know if the user has added default socket options, so we cannot replace the-            # list.+            # Defaulting `socket_options` to an empty list avoids it defaulting to+            # ``HTTPConnection.default_socket_options``.             self.conn_kw.setdefault("socket_options", [])@@ -704,4 +704,11 @@         """-        parsed_url = parse_url(url)-        destination_scheme = parsed_url.scheme+        # Ensure that the URL we're connecting to is properly encoded+        if url.startswith("/"):+            # URLs starting with / are inherently schemeless.+            url = to_str(_encode_target(url))+            destination_scheme = None+        else:+            parsed_url = parse_url(url)+            destination_scheme = parsed_url.scheme+            url = to_str(parsed_url.url) @@ -719,8 +726,2 @@             raise HostChangedError(self, url, retries)--        # Ensure that the URL we're connecting to is properly encoded-        if url.startswith("/"):-            url = to_str(_encode_target(url))-        else:-            url = to_str(parsed_url.url) @@ -897,2 +898,14 @@                 headers = HTTPHeaderDict(headers)._prepare_for_method_change()++            # Strip headers marked as unsafe to forward to the redirected location.+            # Check remove_headers_on_redirect to avoid a potential network call within+            # self.is_same_host() which may use socket.gethostbyname() in the future.+            if retries.remove_headers_on_redirect and not self.is_same_host(+                redirect_location+            ):+                new_headers = headers.copy()  # type: ignore[union-attr]+                for header in headers:+                    if header.lower() in retries.remove_headers_on_redirect:+                        new_headers.pop(header, None)+                headers = new_headers 
src/urllib3/contrib/socks.py +1 lines · 1 flagged
--- +++ @@ -143,3 +143,3 @@                     )-            else:+            else:  # Defensive: see https://github.com/urllib3/urllib3/pull/3728#pullrequestreview-3816302703                 raise NewConnectionError(
src/urllib3/exceptions.py +2 lines · 1 flagged
--- +++ @@ -157,4 +157,4 @@             "The 'pool' property is deprecated and will be removed "-            "in urllib3 v2.1.0. Use 'conn' instead.",-            DeprecationWarning,+            "in urllib3 v3.0. Use 'conn' instead.",+            FutureWarning,             stacklevel=2,
src/urllib3/fields.py +14 lines · 9 flagged
--- +++ @@ -47,3 +47,3 @@     .. deprecated:: 2.0.0-        Will be removed in urllib3 v2.1.0. This is not valid for+        Will be removed in urllib3 v3.0. This is not valid for         ``multipart/form-data`` header parameters.@@ -53,6 +53,6 @@     warnings.warn(-        "'format_header_param_rfc2231' is deprecated and will be "-        "removed in urllib3 v2.1.0. This is not valid for "+        "'format_header_param_rfc2231' is insecure, deprecated and will be "+        "removed in urllib3 v3.0. This is not valid for "         "multipart/form-data header parameters.",-        DeprecationWarning,+        FutureWarning,         stacklevel=2,@@ -106,3 +106,3 @@         ``format_header_param``. The old names will be removed in-        urllib3 v2.1.0.+        urllib3 v3.0.     """@@ -120,3 +120,3 @@         Renamed to :func:`format_multipart_header_param`. Will be-        removed in urllib3 v2.1.0.+        removed in urllib3 v3.0.     """@@ -127,4 +127,4 @@         "'format_multipart_header_param'. The old name will be "-        "removed in urllib3 v2.1.0.",-        DeprecationWarning,+        "removed in urllib3 v3.0.",+        FutureWarning,         stacklevel=2,@@ -138,3 +138,3 @@         Renamed to :func:`format_multipart_header_param`. Will be-        removed in urllib3 v2.1.0.+        removed in urllib3 v3.0.     """@@ -145,4 +145,4 @@         "'format_multipart_header_param'. The old name will be "-        "removed in urllib3 v2.1.0.",-        DeprecationWarning,+        "removed in urllib3 v3.0.",+        FutureWarning,         stacklevel=2,@@ -167,3 +167,3 @@         The ``header_formatter`` parameter is deprecated and will-        be removed in urllib3 v2.1.0.+        be removed in urllib3 v3.0.     """@@ -190,4 +190,4 @@                 "The 'header_formatter' parameter is deprecated and "-                "will be removed in urllib3 v2.1.0.",-                DeprecationWarning,+                "will be removed in urllib3 v3.0.",+                FutureWarning,                 stacklevel=2,
src/urllib3/poolmanager.py +9 lines · 2 flagged
--- +++ @@ -330,4 +330,4 @@                 "The 'strict' parameter is no longer needed on Python 3+. "-                "This will raise an error in urllib3 v2.1.0.",-                DeprecationWarning,+                "This will raise an error in urllib3 v3.0.",+                FutureWarning,             )@@ -438,6 +438,6 @@                 "URLs without a scheme (ie 'https://') are deprecated and will raise an error "-                "in a future version of urllib3. To avoid this DeprecationWarning ensure all URLs "+                "in urllib3 v3.0. To avoid this FutureWarning ensure all URLs "                 "start with 'https://' or 'http://'. Read more in this issue: "                 "https://github.com/urllib3/urllib3/issues/2920",-                category=DeprecationWarning,+                category=FutureWarning,                 stacklevel=2,@@ -546,5 +546,6 @@ -        resp1 = proxy.request("GET", "https://google.com/")-        resp2 = proxy.request("GET", "https://httpbin.org/")-+        resp1 = proxy.request("GET", "http://google.com/")+        resp2 = proxy.request("GET", "http://httpbin.org/")++        # One pool was shared by both plain HTTP requests.         print(len(proxy.pools))@@ -555,2 +556,3 @@ +        # A separate pool was added for each HTTPS target.         print(len(proxy.pools))
src/urllib3/response.py +35 lines · 1 flagged
--- +++ @@ -665,3 +665,3 @@     # Compatibility methods for `io` module-    def readinto(self, b: bytearray) -> int:+    def readinto(self, b: bytearray | memoryview[int]) -> int:         temp = self.read(len(b))@@ -757,2 +757,3 @@         self._body = None+        self._uncached_read_occurred = False         self._fp: _HttplibHTTPResponse | None = None@@ -799,9 +800,10 @@         try:-            self.read(-                # Do not spend resources decoding the content unless-                # decoding has already been initiated.-                decode_content=self._has_decoded_content,-            )+            self._raw_read()         except (HTTPError, OSError, BaseSSLError, HTTPException):             pass+        if self._has_decoded_content:+            # `_raw_read` skips decompression, so we should clean up the+            # decoder to avoid keeping unnecessary data in memory.+            self._decoded_buffer = BytesQueueBuffer()+            self._decoder = None @@ -828,3 +830,3 @@         Obtain the number of bytes pulled over the wire so far. May differ from-        the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``+        the amount of content returned by :meth:`HTTPResponse.read`         if bytes are encoded on the wire (e.g, compressed).@@ -910,8 +912,4 @@             except BaseSSLError as e:-                # FIXME: Is there a better way to differentiate between SSLErrors?-                if "read operation timed out" not in str(e):-                    # SSL errors related to framing/MAC get wrapped and reraised here-                    raise SSLError(e) from e--                raise ReadTimeoutError(self._pool, None, "Read timed out.") from e  # type: ignore[arg-type]+                # SSL errors related to framing/MAC get wrapped and reraised here+                raise SSLError(e) from e @@ -968,7 +966,3 @@ -        The known cases:-          * CPython < 3.9.7 because of a bug-            https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900.-          * urllib3 injected with pyOpenSSL-backed SSL-support.-          * CPython < 3.10 only when `amt` does not fit 32-bit int.+        This happens to urllib3 injected with pyOpenSSL-backed SSL-support.         """@@ -983,3 +977,3 @@             )-        ) and (util.IS_PYOPENSSL or sys.version_info < (3, 10)):+        ) and util.IS_PYOPENSSL:             if read1:@@ -1100,3 +1094,7 @@ -            if self._decoder and self._decoder.has_unconsumed_tail:+            if (+                self._decoder+                and self._decoder.has_unconsumed_tail+                and len(self._decoded_buffer) < amt+            ):                 decoded_data = self._decode(@@ -1112,2 +1110,4 @@         data = self._raw_read(amt)+        if not cache_content:+            self._uncached_read_occurred = True @@ -1124,3 +1124,9 @@             data = self._decode(data, decode_content, flush_decoder)-            if cache_content:+            # It's possible that there is buffered decoded data after a+            # partial read.+            if decode_content and len(self._decoded_buffer) > 0:+                self._decoded_buffer.put(data)+                data = self._decoded_buffer.get_all()++            if cache_content and not self._uncached_read_occurred:                 self._body = data@@ -1212,2 +1218,3 @@         data = self._raw_read(amt, read1=True)+        self._uncached_read_occurred = True         if not decode_content or data is None:@@ -1248,2 +1255,5 @@         """+        if amt == 0:+            return+         if self.chunked and self.supports_chunked_reads():@@ -1407,3 +1417,5 @@ -            if amt and amt < 0:+            if amt == 0:+                return+            elif amt and amt < 0:                 # Negative numbers and `None` should be treated the same,@@ -1418,2 +1430,3 @@                     self._update_chunk_length()+                    self._uncached_read_occurred = True                     if self.chunk_left == 0:
src/urllib3/util/ssl_.py +11 lines · 1 flagged
--- +++ @@ -29,34 +29,4 @@ -def _is_bpo_43522_fixed(-    implementation_name: str,-    version_info: _TYPE_VERSION_INFO,-    pypy_version_info: _TYPE_VERSION_INFO | None,-) -> bool:-    """Return True for CPython 3.9.3+ or 3.10+ and PyPy 7.3.8+ where-    setting SSLContext.hostname_checks_common_name to False works.--    Outside of CPython and PyPy we don't know which implementations work-    or not so we conservatively use our hostname matching as we know that works-    on all implementations.--    https://github.com/urllib3/urllib3/issues/2192#issuecomment-821832963-    https://foss.heptapod.net/pypy/pypy/-/issues/3539-    """-    if implementation_name == "pypy":-        # https://foss.heptapod.net/pypy/pypy/-/issues/3129-        return pypy_version_info >= (7, 3, 8)  # type: ignore[operator]-    elif implementation_name == "cpython":-        major_minor = version_info[:2]-        micro = version_info[2]-        return (major_minor == (3, 9) and micro >= 3) or major_minor >= (3, 10)-    else:  # Defensive:-        return False-- def _is_has_never_check_common_name_reliable(     openssl_version: str,-    openssl_version_number: int,-    implementation_name: str,-    version_info: _TYPE_VERSION_INFO,-    pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool:@@ -65,12 +35,4 @@     is_openssl = openssl_version.startswith("OpenSSL ")-    # Before fixing OpenSSL issue #14579, the SSL_new() API was not copying hostflags-    # like X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, which tripped up CPython.-    # https://github.com/openssl/openssl/issues/14579-    # This was released in OpenSSL 1.1.1l+ (>=0x101010cf)-    is_openssl_issue_14579_fixed = openssl_version_number >= 0x101010CF--    return is_openssl and (-        is_openssl_issue_14579_fixed-        or _is_bpo_43522_fixed(implementation_name, version_info, pypy_version_info)-    )++    return is_openssl @@ -100,5 +62,5 @@         OPENSSL_VERSION,-        OPENSSL_VERSION_NUMBER,         PROTOCOL_TLS,         PROTOCOL_TLS_CLIENT,+        VERIFY_X509_PARTIAL_CHAIN,         VERIFY_X509_STRICT,@@ -112,14 +74,7 @@ -    # Needed for Python 3.9 which does not define this-    VERIFY_X509_PARTIAL_CHAIN = getattr(ssl, "VERIFY_X509_PARTIAL_CHAIN", 0x80000)--    # Setting SSLContext.hostname_checks_common_name = False didn't work before CPython-    # 3.9.3, and 3.10 (but OK on PyPy) or OpenSSL 1.1.1l++    # Setting SSLContext.hostname_checks_common_name = False didn't work with+    # LibreSSL, check details in the used function.     if HAS_NEVER_CHECK_COMMON_NAME and not _is_has_never_check_common_name_reliable(         OPENSSL_VERSION,-        OPENSSL_VERSION_NUMBER,-        sys.implementation.name,-        sys.version_info,-        sys.pypy_version_info if sys.implementation.name == "pypy" else None,  # type: ignore[attr-defined]-    ):  # Defensive: for Python < 3.9.3+    ):  # Defensive:         HAS_NEVER_CHECK_COMMON_NAME = False@@ -144,3 +99,3 @@     PROTOCOL_TLS_CLIENT = 16  # type: ignore[assignment, misc]-    VERIFY_X509_PARTIAL_CHAIN = 0x80000+    VERIFY_X509_PARTIAL_CHAIN = 0x80000  # type: ignore[assignment,misc]     VERIFY_X509_STRICT = 0x20  # type: ignore[assignment, misc]@@ -291,4 +246,4 @@                 "'ssl_version' option is deprecated and will be "-                "removed in urllib3 v2.6.0. Instead use 'ssl_minimum_version'",-                category=DeprecationWarning,+                "removed in urllib3 v3.0. Instead use 'ssl_minimum_version'",+                category=FutureWarning,                 stacklevel=2,@@ -296,8 +251,6 @@ -    # PROTOCOL_TLS is deprecated in Python 3.10 so we always use PROTOCOL_TLS_CLIENT     context = SSLContext(PROTOCOL_TLS_CLIENT)-     if ssl_minimum_version is not None:         context.minimum_version = ssl_minimum_version-    else:  # Python <3.10 defaults to 'MINIMUM_SUPPORTED' so explicitly set TLSv1.2 here+    else:  # pyOpenSSL defaults to 'MINIMUM_SUPPORTED' so explicitly set TLSv1.2 here         context.minimum_version = TLSVersion.TLSv1_2@@ -361,6 +314,3 @@ -    try:-        context.hostname_checks_common_name = False-    except AttributeError:  # Defensive: for CPython < 3.9.3; for PyPy < 7.3.8-        pass+    context.hostname_checks_common_name = False 
test/contrib/emscripten/test_emscripten.py +61 lines · 2 flagged
--- +++ @@ -33,3 +33,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int, prefer_jspi: bool) -> None:  # type: ignore[no-untyped-def]@@ -68,3 +68,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int, https_port: int, prefer_jspi: bool) -> None:  # type: ignore[no-untyped-def]@@ -78,3 +78,5 @@         resp = http.request("GET", f"http://{host}:{port}/")-        assert resp.data.decode("utf-8") == "Dummy server!"+        # ensure that the response is cached and can be read multiple times+        for _ in range(2):+            assert resp.data.decode("utf-8") == "Dummy server!" @@ -137,3 +139,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -158,3 +160,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -179,3 +181,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -196,3 +198,3 @@ def test_404(selenium_coverage: typing.Any, testserver_http: PyodideServerInfo) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -220,3 +222,3 @@ ) -> None:-    @run_in_pyodide()  # type: ignore[misc]+    @run_in_pyodide()  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -312,3 +314,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int, connection_cls: str) -> None:  # type: ignore[no-untyped-def]@@ -336,3 +338,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -376,3 +378,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -420,3 +422,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -604,3 +606,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -635,3 +637,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -676,3 +678,3 @@ ) -> None:-    @run_in_pyodide(packages=["micropip"])  # type: ignore[misc]+    @run_in_pyodide(packages=["micropip"])  # type: ignore[untyped-decorator]     async def test_fn(@@ -704,3 +706,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -820,3 +822,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -864,3 +866,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -884,3 +886,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -905,3 +907,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -940,3 +942,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage: typing.Any, host: str, port: int) -> None:@@ -961,3 +963,3 @@ -    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage: typing.Any, host: str, port: int) -> None:@@ -1002,3 +1004,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int, https_port: int) -> None:  # type: ignore[no-untyped-def]@@ -1102,2 +1104,5 @@         assert len(all_data.decode("utf-8")) == 17825792+        # ensure that the content is not cached+        assert response._body is None+        assert response.data == b"" @@ -1149,2 +1154,30 @@ +def test_cache_content_ignored_during_and_after_partial_read(+    selenium_coverage: typing.Any, testserver_http: PyodideServerInfo+) -> None:+    @run_in_pyodide+    def pyodide_test(selenium, host, port):  # type: ignore[no-untyped-def]+        from urllib3.connection import HTTPConnection+        from urllib3.response import BaseHTTPResponse++        conn = HTTPConnection(host, port)+        conn.request("GET", f"http://{host}:{port}/dripfeed", preload_content=False)+        response = conn.getresponse()+        assert isinstance(response, BaseHTTPResponse)+        # read some of the data but not all of it+        data = response.read(32768, cache_content=True)+        assert len(data) == 32768+        # check that the cached content is empty+        assert response._body is None+        # ensure the rest of the data is not cached either+        data += response.read(cache_content=True)+        assert len(data) == 17825792+        assert response._body is None+        assert response.data == b""++    pyodide_test(+        selenium_coverage, testserver_http.http_host, testserver_http.http_port+    )++ @pytest.mark.node_without_jspi@@ -1156,3 +1189,3 @@ -    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -1183,3 +1216,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -1206,3 +1239,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -1250,3 +1283,3 @@ ) -> None:-    @run_in_pyodide  # type: ignore[misc]+    @run_in_pyodide  # type: ignore[untyped-decorator]     def pyodide_test(selenium_coverage, host: str, port: int) -> None:  # type: ignore[no-untyped-def]@@ -1282,3 +1315,3 @@ -@run_in_pyodide  # type: ignore[misc]+@run_in_pyodide  # type: ignore[untyped-decorator] def test_pool_no_port(selenium_coverage: typing.Any) -> None:
test/test_connection.py +7 lines · 1 flagged
--- +++ @@ -302,10 +302,10 @@ -        # When dropping support for Python 3.9, this can be rewritten to parenthesized-        # context managers-        with mock.patch("urllib3.util.connection.create_connection"):-            with mock.patch(+        with (+            mock.patch("urllib3.util.connection.create_connection"),+            mock.patch(                 "urllib3.connection._HTTPConnection.putheader"-            ) as http_client_putheader:-                conn = HTTPConnection("")-                conn.request("GET", "/headers", headers=headers, chunked=chunked)+            ) as http_client_putheader,+        ):+            conn = HTTPConnection("")+            conn.request("GET", "/headers", headers=headers, chunked=chunked) 
test/test_connectionpool.py +22 lines · 1 flagged
--- +++ @@ -594 +594,23 @@                     pool._make_request(conn, "", "", timeout=timeout)++    @pytest.mark.parametrize(+        "path",+        [+            "//v:h",+            "//host:8080/path",+            "//host/path",+            "//v:h?key=val",+            "/",+        ],+    )+    def test_paths_arent_parsed_as_urls(self, path: str) -> None:+        """See https://github.com/urllib3/urllib3/issues/3352."""+        with HTTPConnectionPool(host="localhost", port=80) as pool:+            with patch.object(+                pool, "_make_request", return_value=HTTPResponse(status=200)+            ) as mock_request:+                pool.urlopen("GET", path)++            # Verify the URL isn't mangled+            actual_url = mock_request.call_args[0][2]+            assert actual_url == path
test/test_exceptions.py +2 lines · 1 flagged
--- +++ @@ -79,3 +79,3 @@         err = NewConnectionError(HTTPConnection("localhost"), "test")-        with pytest.warns(DeprecationWarning) as records:+        with pytest.warns(FutureWarning) as records:             err_pool = err.pool@@ -85,3 +85,3 @@             "The 'pool' property is deprecated and will be removed "-            "in urllib3 v2.1.0. Use 'conn' instead."+            "in urllib3 v3.0. Use 'conn' instead."         )
test/test_fields.py +4 lines · 4 flagged
--- +++ @@ -74,3 +74,3 @@     ) -> None:-        with pytest.deprecated_call(match=r"urllib3 v2\.1\.0"):+        with pytest.deprecated_call(match=r"urllib3 v3\.0"):             param = format_header_param_rfc2231("filename", value)@@ -80,6 +80,6 @@     def test_format_header_param_html5_deprecated(self) -> None:-        with pytest.deprecated_call(match=r"urllib3 v2\.1\.0"):+        with pytest.deprecated_call(match=r"urllib3 v3\.0"):             param2 = format_header_param_html5("filename", "name") -        with pytest.deprecated_call(match=r"urllib3 v2\.1\.0"):+        with pytest.deprecated_call(match=r"urllib3 v3\.0"):             param1 = format_header_param("filename", "name")@@ -113,3 +113,3 @@     def test_from_tuples_rfc2231(self) -> None:-        with pytest.deprecated_call(match=r"urllib3 v2\.1\.0"):+        with pytest.deprecated_call(match=r"urllib3 v3\.0"):             field = RequestField.from_tuples(
test/test_poolmanager.py +6 lines · 2 flagged
--- +++ @@ -263,3 +263,3 @@     def test_deprecated_no_scheme(self, connection_from_host: mock.MagicMock) -> None:-        # Don't actually make a network connection, just verify the DeprecationWarning+        # Don't actually make a network connection, just verify the FutureWarning         connection_from_host.side_effect = ConnectionError("Not attempting connection")@@ -267,3 +267,3 @@ -        with pytest.warns(DeprecationWarning) as records:+        with pytest.warns(FutureWarning) as records:             with pytest.raises(ConnectionError):@@ -273,3 +273,3 @@             "URLs without a scheme (ie 'https://') are deprecated and will raise an error "-            "in a future version of urllib3. To avoid this DeprecationWarning ensure all URLs "+            "in urllib3 v3.0. To avoid this FutureWarning ensure all URLs "             "start with 'https://' or 'http://'. Read more in this issue: "@@ -279,3 +279,3 @@         assert len(records) == 1-        assert isinstance(records[0].message, DeprecationWarning)+        assert isinstance(records[0].message, FutureWarning)         assert records[0].message.args[0] == msg@@ -293,3 +293,3 @@         }-        with pytest.warns(DeprecationWarning) as records:+        with pytest.warns(FutureWarning) as records:             p.connection_from_context(context)@@ -298,3 +298,3 @@             "The 'strict' parameter is no longer needed on Python 3+. "-            "This will raise an error in urllib3 v2.1.0."+            "This will raise an error in urllib3 v3.0."         )
test/test_ssl.py +3 lines · 1 flagged
--- +++ @@ -72,7 +72,3 @@         else:-            # Needed for Python 3.9 which does not define this-            assert not (-                context.verify_flags-                & getattr(ssl, "VERIFY_X509_PARTIAL_CHAIN", 0x80000)-            )+            assert not (context.verify_flags & ssl.VERIFY_X509_PARTIAL_CHAIN)             assert not (context.verify_flags & ssl.VERIFY_X509_STRICT)@@ -241,5 +237,5 @@         with pytest.warns(-            DeprecationWarning,+            FutureWarning,             match=r"'ssl_version' option is deprecated and will be removed in "-            r"urllib3 v2\.6\.0\. Instead use 'ssl_minimum_version'",+            r"urllib3 v3\.0\. Instead use 'ssl_minimum_version'",         ):
test/with_dummyserver/test_connectionpool.py +3 lines · 1 flagged
--- +++ @@ -498,3 +498,3 @@             with warnings.catch_warnings():-                warnings.simplefilter("error", DeprecationWarning)+                warnings.simplefilter("error", FutureWarning)                 pool.request("GET", "/redirect", fields={"target": "/"})@@ -1100,6 +1100,6 @@ -            with pytest.warns(DeprecationWarning) as w:+            with pytest.warns(FutureWarning) as w:                 conn.request_chunked("GET", "/headers")  # type: ignore[attr-defined]             assert len(w) == 1 and str(w[0].message) == (-                "HTTPConnection.request_chunked() is deprecated and will be removed in urllib3 v2.1.0. "+                "HTTPConnection.request_chunked() is deprecated and will be removed in urllib3 v3.0. "                 "Instead use HTTPConnection.request(..., chunked=True)."
test/with_dummyserver/test_https.py +11 lines · 5 flagged
--- +++ @@ -763,5 +763,5 @@                 cmgr = pytest.warns(-                    DeprecationWarning,+                    FutureWarning,                     match=r"'ssl_version' option is deprecated and will be removed "-                    r"in urllib3 v2\.6\.0\. Instead use 'ssl_minimum_version'",+                    r"in urllib3 v3\.0\. Instead use 'ssl_minimum_version'",                 )@@ -773,3 +773,3 @@         conn = VerifiedHTTPSConnection(self.host, self.port)-        with pytest.warns(DeprecationWarning) as w:+        with pytest.warns(FutureWarning) as w:             conn.set_cert()@@ -777,3 +777,3 @@         assert len(w) == 1 and str(w[0].message) == (-            "HTTPSConnection.set_cert() is deprecated and will be removed in urllib3 v2.1.0. "+            "HTTPSConnection.set_cert() is deprecated and will be removed in urllib3 v3.0. "             "Instead provide the parameters to the HTTPSConnection constructor."@@ -789,3 +789,3 @@         conn = HTTPSConnection(self.host, self.port, ssl_context=ssl_context)-        with pytest.warns(DeprecationWarning) as w:+        with pytest.warns(FutureWarning) as w:             conn.set_cert()@@ -797,3 +797,3 @@         assert len(w) == 1 and str(w[0].message) == (-            "HTTPSConnection.set_cert() is deprecated and will be removed in urllib3 v2.1.0. "+            "HTTPSConnection.set_cert() is deprecated and will be removed in urllib3 v3.0. "             "Instead provide the parameters to the HTTPSConnection constructor."@@ -830,3 +830,3 @@             with contextlib.closing(https_pool._get_conn()) as conn:-                with pytest.warns(DeprecationWarning) as w:+                with pytest.warns(FutureWarning) as w:                     conn.connect()@@ -834,3 +834,3 @@         assert len(w) >= 1-        assert any(x.category == DeprecationWarning for x in w)+        assert any(x.category == FutureWarning for x in w)         assert any(@@ -839,3 +839,3 @@                 "'ssl_version' option is deprecated and will be removed in "-                "urllib3 v2.6.0. Instead use 'ssl_minimum_version'"+                "urllib3 v3.0. Instead use 'ssl_minimum_version'"             )@@ -1144,5 +1144,5 @@         with pytest.warns(-            DeprecationWarning,+            FutureWarning,             match=r"'ssl_version' option is deprecated and will be removed in "-            r"urllib3 v2\.6\.0\. Instead use 'ssl_minimum_version'",+            r"urllib3 v3\.0\. Instead use 'ssl_minimum_version'",         ):
test/with_dummyserver/test_proxy_poolmanager.py +72 lines · 1 flagged
--- +++ @@ -39,2 +39,3 @@ from urllib3.poolmanager import ProxyManager, proxy_from_url+from urllib3.util.retry import RequestHistory from urllib3.util.ssl_ import create_urllib3_context@@ -301,2 +302,73 @@             assert r._pool.host != self.http_host_alt++    _sensitive_headers = {+        "Authorization": "foo",+        "Proxy-Authorization": "bar",+        "Cookie": "foo=bar",+    }++    @pytest.mark.parametrize(+        "sensitive_headers",+        (_sensitive_headers, {k.lower(): v for k, v in _sensitive_headers.items()}),+        ids=("capitalized", "lowercase"),+    )+    def test_cross_host_redirect_remove_headers_via_proxy_manager(+        self, sensitive_headers: dict[str, str]+    ) -> None:+        headers_url = f"{self.http_url_alt}/headers"+        initial_url = f"{self.http_url}/redirect?target={headers_url}"+        with proxy_from_url(self.proxy_url) as proxy_mgr:+            r = proxy_mgr.request(+                "GET", initial_url, headers=sensitive_headers, retries=1+            )+            assert r.status == 200+            assert r.retries is not None+            assert r.retries.history == (+                RequestHistory(+                    method="GET",+                    url=initial_url,+                    error=None,+                    status=303,+                    redirect_location=headers_url,+                ),+            )+            data = r.json()+            for header in sensitive_headers:+                assert header not in data++    @pytest.mark.parametrize(+        "sensitive_headers",+        (_sensitive_headers, {k.lower(): v for k, v in _sensitive_headers.items()}),+        ids=("capitalized", "lowercase"),+    )+    def test_cross_host_redirect_remove_headers_via_pool(+        self, sensitive_headers: dict[str, str]+    ) -> None:+        headers_url = f"{self.http_url_alt}/headers"+        initial_url = f"{self.http_url}/redirect?target={headers_url}"+        with proxy_from_url(self.proxy_url) as proxy_mgr:+            pool = proxy_mgr.connection_from_url(self.http_url)+            r = pool.urlopen(+                "GET",+                initial_url,+                headers=sensitive_headers,+                retries=1,+                redirect=True,+                assert_same_host=False,+                preload_content=True,+            )+            assert r.status == 200+            assert r.retries is not None+            assert r.retries.history == (+                RequestHistory(+                    method="GET",+                    url=initial_url,+                    error=None,+                    status=303,+                    redirect_location=headers_url,+                ),+            )+            data = r.json()+            for header in sensitive_headers:+                assert header not in data 
dummyserver/asgi_proxy.py +1 lines
--- +++ @@ -58,2 +58,3 @@                 url=scope["path"],+                params=scope["query_string"].decode(),                 headers=list(scope["headers"]),
dummyserver/testcase.py +2 lines
--- +++ @@ -31,3 +31,3 @@             b = sock.recv(chunks)-        except (TimeoutError, socket.timeout):+        except TimeoutError:             continue@@ -104,3 +104,3 @@                         break-                    except (TimeoutError, socket.timeout):+                    except TimeoutError:                         continue
pyproject.toml +35 lines
--- +++ @@ -3,3 +3,3 @@ [build-system]-requires = ["hatchling>=1.27.0,<2", "hatch-vcs>=0.4.0,<0.6.0", "setuptools-scm>=8,<10"]+requires = ["hatchling>=1.27.0,<2", "hatch-vcs>=0.4.0,<0.6.0", "setuptools-scm>=8,<11"] build-backend = "hatchling.build"@@ -27,3 +27,2 @@   "Programming Language :: Python :: 3",-  "Programming Language :: Python :: 3.9",   "Programming Language :: Python :: 3.10",@@ -40,3 +39,3 @@ ]-requires-python = ">=3.9"+requires-python = ">=3.10" dynamic = ["version"]@@ -59,3 +58,3 @@ [dependency-groups]-dev = [+dev-base = [     "anyio[trio]>=4.8.0",@@ -63,3 +62,2 @@     "coverage>=7.8.0",-    "cryptography>=44.0.2",     "h2>=4.1.0",@@ -67,4 +65,2 @@     "hypercorn",-    "idna>=3.10",-    "pyopenssl>=25.0.0",     "pysocks>=1.7.1",@@ -77,4 +73,23 @@     "towncrier>=24.8.0",+    "trio>=0.27.0",+]+dev = [+    {include-group = "dev-base"},+    "cryptography>=44.0.2",+    "idna>=3.10",+    "pyopenssl>=25.0.0",     "trustme>=1.2.1",-    "trio>=0.27.0",+]+dev-min-pyopenssl = [+    {include-group = "dev-base"},+    # 19.0.0 (2019-01-21) was the first version to support OpenSSL 1.1.1.+    # The following versions of pyOpenSSL and cryptography are documented+    # as the minimum supported ones in our docs.+    "pyopenssl==19.0.0",+    "cryptography==2.3",+    # We document 2.1 as the minimum supported version of idna from+    # cryptography, but 2.8 is the minimum needed for tests because of anyio.+    "idna==2.8",+    # The last version of trustme to support cryptography < 3.1.+    "trustme==0.9.0", ]@@ -98,3 +113,3 @@     "build>=1.2.2.post1",-    "pytest-pyodide>=0.58.4 ; python_full_version >= '3.10'",+    "pytest-pyodide>=0.58.4",     "selenium>=4.27.1",@@ -164,3 +179,3 @@     # https://github.com/SeleniumHQ/selenium/issues/14686-    '''default:setting remote_server_addr in RemoteConnection\(\) is deprecated, set in ClientConfig instance instead:DeprecationWarning'''+    '''default:setting remote_server_addr in RemoteConnection\(\) is deprecated, set in ClientConfig instance instead:FutureWarning''' ]@@ -194,2 +209,12 @@ package = true+conflicts = [+  [+    {group = "dev"},+    {group = "dev-min-pyopenssl"},+  ],+  [+    {group = "dev-min-pyopenssl"},+    {group = "mypy"},+  ],+] 
src/urllib3/_base_connection.py +3 lines
--- +++ @@ -8,3 +8,5 @@ -_TYPE_BODY = typing.Union[bytes, typing.IO[typing.Any], typing.Iterable[bytes], str]+_TYPE_BODY = typing.Union[+    bytes, typing.IO[typing.Any], typing.Iterable[bytes | str], str+] 
src/urllib3/_collections.py +0 lines
--- +++ @@ -358,3 +358,2 @@         elif isinstance(other, typing.Iterable):-            other = typing.cast(typing.Iterable[tuple[str, str]], other)             for key, value in other:
src/urllib3/_version.py +8 lines
--- +++ @@ -1,3 +1,4 @@-# file generated by setuptools-scm+# file generated by vcs-versioning # don't change, don't track in version control+from __future__ import annotations @@ -12,22 +13,11 @@ -TYPE_CHECKING = False-if TYPE_CHECKING:-    from typing import Tuple-    from typing import Union--    VERSION_TUPLE = Tuple[Union[int, str], ...]-    COMMIT_ID = Union[str, None]-else:-    VERSION_TUPLE = object-    COMMIT_ID = object- version: str __version__: str-__version_tuple__: VERSION_TUPLE-version_tuple: VERSION_TUPLE-commit_id: COMMIT_ID-__commit_id__: COMMIT_ID+__version_tuple__: tuple[int | str, ...]+version_tuple: tuple[int | str, ...]+commit_id: str | None+__commit_id__: str | None -__version__ = version = '2.6.3'-__version_tuple__ = version_tuple = (2, 6, 3)+__version__ = version = '2.7.0'+__version_tuple__ = version_tuple = (2, 7, 0) 
src/urllib3/contrib/emscripten/response.py +5 lines
--- +++ @@ -38,2 +38,3 @@         self._body = None+        self._uncached_read_occurred = False         self._response = internal_response@@ -162,6 +163,9 @@                 data = self._response.body.read(amt)+                self._uncached_read_occurred = True             else:  # read all we can (and cache it)                 data = self._response.body.read()-                if cache_content:+                if cache_content and not self._uncached_read_occurred:                     self._body = data+                else:+                    self._uncached_read_occurred = True             if self.length_remaining is not None:
aiobotocore pypi
3.9.0 20d ago nominal
BURST ×2
latest 3.9.0 versions 136 maintainers 1
3.1.1
3.1.2
3.1.3
3.2.0
3.2.1
3.3.0
3.4.0
3.5.0
3.6.0
3.7.0
3.8.0
3.9.0
BURST
2 releases in 29m: 2.1.2, 2.5.2
info · registry-verified · 2023-07-07 · 3y ago
BURST
2 releases in 27m: 2.10.0, 2.11.0
info · registry-verified · 2024-01-19 · 2y ago
release diff 3.8.0 → 3.9.0
+76 added · -6 removed · ~38 modified
new files touching dangerous APIs: tests/botocore_tests/unit/retries/test_standard_retry_v2_1.py, tests/botocore_tests/unit/test_args.py, tests/botocore_tests/unit/test_credentials.py, tests/botocore_tests/unit/test_protocols.py, tests/botocore_tests/unit/test_signers.py, tests/botocore_tests/unit/test_utils.py
+70 more files not shown
aiobotocore/httpsession.py +66 lines · 4 flagged
--- +++ @@ -5,2 +5,3 @@ import socket+import ssl from concurrent.futures import CancelledError@@ -47,2 +48,23 @@ +class _ProxySSLTCPConnector(aiohttp.TCPConnector):+    """A TCPConnector that uses a separate SSL context for the proxy hop.++    aiohttp builds the proxy request with ``ssl=req.ssl``, so the proxy+    connection and the tunnelled endpoint connection would otherwise share one+    context — and the endpoint's client certificate would be offered to the+    proxy. urllib3 passes ``cert_file=None`` when wrapping the proxy socket, so+    botocore never does that; this keeps the two apart the same way.+    """++    def __init__(self, *args, proxy_ssl_context=None, **kwargs):+        super().__init__(*args, **kwargs)+        self._proxy_ssl_context = proxy_ssl_context++    def _update_proxy_auth_header_and_build_proxy_req(self, req):+        proxy_req = super()._update_proxy_auth_header_and_build_proxy_req(req)+        if self._proxy_ssl_context is not None:+            proxy_req._ssl = self._proxy_ssl_context+        return proxy_req++ class AIOHTTPSession:@@ -120,6 +142,7 @@         proxy_cert = proxies_settings.get('proxy_client_cert')-        if proxy_ca_bundle is None and proxy_cert is None:-            return None--        context = self._get_ssl_context()++        # The proxy connection gets the endpoint's verify settings but never+        # its client certificate: urllib3 passes cert_file=None when wrapping+        # the proxy socket, so only proxy_client_cert is offered to a proxy.+        context = self._build_verify_context()         try:@@ -128,3 +151,3 @@             # proxy tls negotiation when proxy_url is not an IP Address-            if not _is_ipaddress(url.host):+            if self._verify and not _is_ipaddress(url.host):                 context.check_hostname = True@@ -149,18 +172,9 @@ -    def _build_ssl_context(self, proxy_url):-        # Synchronous; only called via asyncio.to_thread when verify is truthy. (#1469)-        if proxy_url:-            ssl_context = self._setup_proxy_ssl_context(proxy_url)-            # TODO: add support for-            #    proxies_settings.get('proxy_use_forwarding_for_https')-        else:-            ssl_context = self._get_ssl_context()--        if ssl_context:-            if self._cert_file:-                ssl_context.load_cert_chain(-                    self._cert_file,-                    self._key_file,-                )-+    def _build_verify_context(self):+        # The endpoint's verify settings, without the client certificate.+        ssl_context = self._get_ssl_context()+        if self._verify:+            # urllib3 disables this by default because it verifies the hostname+            # itself; aiohttp leaves it to the context.+            ssl_context.check_hostname = True             # inline self._setup_ssl_cert@@ -169,4 +183,22 @@                 ssl_context.load_verify_locations(ca_certs, None, None)-+        else:+            ssl_context.check_hostname = False+            ssl_context.verify_mode = ssl.CERT_NONE         return ssl_context++    def _build_ssl_contexts(self, proxy_url):+        # Synchronous SSL context construction. Caller runs off the event loop.+        # (#1469)+        ssl_context = self._build_verify_context()+        if self._cert_file:+            # urllib3 keeps sending the client certificate when cert_reqs is+            # CERT_NONE, so this is not conditional on verify.+            ssl_context.load_cert_chain(self._cert_file, self._key_file)++        # TODO: add support for+        #    proxies_settings.get('proxy_use_forwarding_for_https')+        proxy_ssl_context = (+            self._setup_proxy_ssl_context(proxy_url) if proxy_url else None+        )+        return ssl_context, proxy_ssl_context @@ -174,11 +206,15 @@         # TCPConnector binds the running loop, so build it here.-        # Dispatch blocking SSL file I/O to a thread only when verify is truthy. (#1469)-        ssl_context = (-            await asyncio.to_thread(self._build_ssl_context, proxy_url)-            if bool(self._verify)-            else None-        )-        return aiohttp.TCPConnector(+        # Dispatch blocking SSL file I/O to a thread. (#1469)+        if self._verify or self._cert_file or proxy_url:+            ssl_context, proxy_ssl_context = await asyncio.to_thread(+                self._build_ssl_contexts, proxy_url+            )+        else:+            ssl_context, proxy_ssl_context = self._build_ssl_contexts(+                proxy_url+            )+        return _ProxySSLTCPConnector(             limit=self._max_pool_connections,-            ssl=ssl_context or False,+            ssl=ssl_context,+            proxy_ssl_context=proxy_ssl_context,             **self._connector_args,
aiobotocore/httpxsession.py +334 lines · 6 flagged
--- +++ @@ -4,7 +4,8 @@ import io-import os import socket import ssl+import warnings from collections.abc import AsyncIterable, Iterable from concurrent.futures import CancelledError+from contextlib import AsyncExitStack from typing import TYPE_CHECKING, Any, cast@@ -19,8 +20,14 @@     HTTPClientError,+    InvalidProxiesConfigError,+    LocationParseError,+    ProxyConfiguration,     ProxyConnectionError,     ReadTimeoutError,+    _is_ipaddress,     create_urllib3_context,-    ensure_boolean,     get_cert_path,     logger,+    mask_proxy_url,+    parse_url,+    urlparse, )@@ -30,2 +37,3 @@ from aiobotocore._endpoint_helpers import _text+from aiobotocore._httpx import HTTPX_IS_LEGACY, httpx @@ -33,9 +41,71 @@ -try:-    import httpx-except ImportError:-    httpx = None-+if httpx is not None:+    # anyio is a dependency of both supported httpx implementations.+    import anyio.to_thread if TYPE_CHECKING:     from ssl import SSLContext++# Emit the legacy-httpx deprecation warning at most once per process. aiobotocore+# builds a fresh HttpxSession per client, and under a warning filter of 'always'+# an unguarded warning would fire on every instance.+_LEGACY_HTTPX_WARNED = False+_RAW_PROXY_TARGET = 'aiobotocore_raw_proxy_target'+++class _ProxyTargetExtensions(dict):+    """Apply the raw target to the endpoint request, but not CONNECT.++    HTTPcore constructs the endpoint request first and then reuses its+    extensions when constructing CONNECT. Its ``Request`` checks for target+    once during construction, so exposing it only on the first check keeps the+    raw S3 path on the endpoint request without replacing CONNECT's authority.+    """++    def __init__(self, extensions: dict, target: bytes):+        super().__init__(extensions, target=target)+        self._target_applied = False++    def __contains__(self, key):+        if key == 'target':+            if self._target_applied:+                return False+            self._target_applied = True+        return super().__contains__(key)+++if httpx is not None:++    class _ProxyTargetTransport(httpx.AsyncHTTPTransport):+        async def handle_async_request(self, request):+            target = request.extensions.pop(_RAW_PROXY_TARGET, None)+            if target is not None:+                # This is the last layer before HTTPcore constructs its+                # endpoint Request, followed by its CONNECT Request. Preserve+                # timeout and other HTTPX extensions while exposing target to+                # the first construction only.+                request.extensions = _ProxyTargetExtensions(+                    request.extensions, target+                )+            return await super().handle_async_request(request)+++def _find_ssl_error(exc: BaseException) -> ssl.SSLError | None:+    """Find an ``ssl.SSLError`` in ``exc``'s cause/context chain.++    A failed TLS handshake reaches us as+    ``httpx.ConnectError -> httpcore.ConnectError -> ssl.SSLError``, linked by+    ``__cause__`` then ``__context__``, so both links are followed rather than+    assuming a fixed depth.+    """+    seen: set[int] = set()+    unvisited: list[BaseException | None] = [exc]+    while unvisited:+        current = unvisited.pop()+        if current is None or id(current) in seen:+            continue+        seen.add(id(current))+        if isinstance(current, ssl.SSLError):+            return current+        unvisited += [current.__cause__, current.__context__]+    return None @@ -56,8 +126,19 @@             raise RuntimeError(-                "Using HttpxSession requires httpx to be installed"-            )-        if proxies or proxies_config:-            raise NotImplementedError(-                "Proxy support not implemented with httpx as backend."-            )+                "Using HttpxSession requires httpx2 (or httpx) to be installed"+            )+        global _LEGACY_HTTPX_WARNED+        if HTTPX_IS_LEGACY and not _LEGACY_HTTPX_WARNED:+            _LEGACY_HTTPX_WARNED = True+            warnings.warn(+                "aiobotocore's httpx backend now prefers httpx2, Pydantic's "+                "maintained fork of httpx. The legacy 'httpx' package is "+                "deprecated as a backend; install httpx2 (e.g. "+                "aiobotocore[httpx2]) to migrate.",+                DeprecationWarning,+                stacklevel=2,+            )++        self._proxy_config = ProxyConfiguration(+            proxies=proxies, proxies_settings=proxies_config+        ) @@ -71,3 +152,4 @@         # TODO: neither this nor AIOHTTPSession handles socket_options-        self._session: httpx.AsyncClient | None = None+        self._entered = False+        self._proxy_ssl_contexts: dict[str, SSLContext]         conn_timeout: float | None@@ -122,48 +204,201 @@ +    def _build_verify_context(self) -> SSLContext:+        # The endpoint's verify settings, without the client certificate.+        ssl_context = self._get_ssl_context()+        if self._verify:+            # urllib3 disables this by default because it verifies the hostname+            # itself; httpcore leaves it to the context.+            ssl_context.check_hostname = True+            ca_certs = get_cert_path(self._verify)+            if ca_certs:+                ssl_context.load_verify_locations(ca_certs, None, None)+        else:+            ssl_context.check_hostname = False+            ssl_context.verify_mode = ssl.CERT_NONE+        return ssl_context+     def _build_ssl_context(self) -> SSLContext:         # Synchronous SSL context construction. Caller runs off the event loop.-        ssl_context = self._get_ssl_context()-        ca_certs = get_cert_path(self._verify)-        if ca_certs:-            ssl_context.load_verify_locations(ca_certs, None, None)-        return ssl_context--    async def __aenter__(self):-        assert not self._session--        # Build the SSL context off the event loop on first entry — only when-        # verify is truthy and an explicit ssl_context wasn't supplied. (#1469)-        if self._verify is True or isinstance(self._verify, str):-            self._verify = await asyncio.to_thread(self._build_ssl_context)--        limits = httpx.Limits(-            max_connections=self._max_pool_connections,-            keepalive_expiry=self._connector_args['keepalive_timeout'],-        )--        # TODO [httpx]: I put logic here to minimize diff / accidental downstream-        # consequences - but can probably put this logic in __init__-        if self._cert_file and self._key_file is None:-            cert = self._cert_file-        elif self._cert_file:-            cert = (self._cert_file, self._key_file)-        else:-            cert = None--        self._session = httpx.AsyncClient(-            timeout=self._timeout, limits=limits, cert=cert-        )-        return self--    async def __aexit__(self, exc_type, exc_val, exc_tb):-        if self._session:-            await self._session.__aexit__(exc_type, exc_val, exc_tb)-            self._session = None-            self._connector = None--    def _get_ssl_context(self) -> SSLContext:-        ssl_context = create_urllib3_context()+        ssl_context = self._build_verify_context()         if self._cert_file:+            # urllib3 keeps sending the client certificate when cert_reqs is+            # CERT_NONE, so this is not conditional on verify.             ssl_context.load_cert_chain(self._cert_file, self._key_file)         return ssl_context++    def _clone_verify_context(self, source: SSLContext) -> SSLContext:+        """Copy endpoint verification settings without its client cert."""+        context = self._get_ssl_context()+        context.options = source.options+        context.minimum_version = source.minimum_version+        context.maximum_version = source.maximum_version+        context.verify_flags = source.verify_flags+        context.verify_mode = source.verify_mode+        context.check_hostname = source.check_hostname+        ca_certs = source.get_ca_certs(binary_form=True)+        if ca_certs:+            cadata = ''.join(+                ssl.DER_cert_to_PEM_cert(cert) for cert in ca_certs+            )+            context.load_verify_locations(cadata=cadata)+        return context++    def _setup_proxy_ssl_context(self, proxy_url: str) -> SSLContext:+        proxies_settings = self._proxy_config.settings+        proxy_ca_bundle = proxies_settings.get('proxy_ca_bundle')+        proxy_cert = proxies_settings.get('proxy_client_cert')++        # The proxy connection gets the endpoint's verify settings but never+        # its client certificate: urllib3 passes cert_file=None when wrapping+        # the proxy socket, so only proxy_client_cert is offered to a proxy.+        context = (+            self._clone_verify_context(self._verify)+            if isinstance(self._verify, ssl.SSLContext)+            else self._build_verify_context()+        )+        try:+            url = parse_url(proxy_url)+            # urllib3 disables this by default but we need it for proper+            # proxy tls negotiation when proxy_url is not an IP Address+            if context.verify_mode != ssl.CERT_NONE and not _is_ipaddress(+                url.host+            ):+                context.check_hostname = True+            if proxy_ca_bundle is not None:+                context.load_verify_locations(cafile=proxy_ca_bundle)++            if isinstance(proxy_cert, tuple):
… 217 more lines (truncated)
tests/botocore_tests/unit/retries/test_standard_retry_v2_1.py +552 lines · 3 flagged
--- +++ @@ -0,0 +1,552 @@+"""Temporary test suite for new updated retry behavior.++Ported from botocore's tests/unit/retries/test_standard_retry_v2_1.py. Tests+exercising RetryHandler.needs_retry are converted to async because aiobotocore+overrides that method on AioRetryHandler. Pure-sync tests (ExponentialBackoff,+RetryQuotaChecker, env var resolution) are kept synchronous because the+underlying classes are reused unchanged from botocore.++NEW_RETRIES_ENABLED is patched in both botocore.retries.standard (where the+sync helpers read it) and aiobotocore.retries.standard (where the async+overrides read their own imported copy).+"""++import unittest+import unittest.mock as mock+from collections import Counter++import pytest+from botocore import configprovider+from botocore.awsrequest import AWSResponse+from botocore.exceptions import ReadTimeoutError+from botocore.retries import quota, standard++from aiobotocore.retries import standard as aio_standard+++class BaseEnvVar(unittest.TestCase):+    def setUp(self):+        self.environ = {}+        self.environ_patch = mock.patch('os.environ', self.environ)+        self.environ_patch.start()++    def tearDown(self):+        self.environ_patch.stop()++[email protected]('botocore.retries.standard.NEW_RETRIES_ENABLED', True)+class TestExponentialBackoff(unittest.TestCase):+    def setUp(self):+        self.random = lambda: 1+        self.backoff = standard.ExponentialBackoff(+            max_backoff=20, random=self.random+        )++    def test_range_of_exponential_backoff(self):+        backoffs = [+            self.backoff.delay_amount(standard.RetryContext(attempt_number=i))+            for i in range(1, 12)+        ]+        # Note that we're capped at 20 which is our max backoff.+        # Cap kicks in at attempt 10+        self.assertEqual(+            backoffs, [0.05, 0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4, 12.8, 20, 20]+        )++    def test_exponential_backoff_with_jitter(self):+        backoff = standard.ExponentialBackoff()+        backoffs = [+            backoff.delay_amount(standard.RetryContext(attempt_number=3))+            for i in range(10)+        ]+        # For attempt number 3, we should have a max value of 0.2 (0.05 * 2 ^ 2),+        # so we can assert all the backoff values are within that range.+        # 0.05 is the default non-throttling scale+        for x in backoffs:+            self.assertTrue(0 <= x <= 0.2)++    def test_uniform_rand_dist_on_max_attempts(self):+        backoff = standard.ExponentialBackoff()+        num_datapoints = 10_000+        backoffs = [+            backoff.delay_amount(standard.RetryContext(attempt_number=10))+            for i in range(num_datapoints)+        ]+        self._assert_looks_like_uniform_distribution(backoffs)++    def _assert_looks_like_uniform_distribution(self, backoffs):+        histogram = Counter(int(el) for el in backoffs)+        expected_value = len(backoffs) / len(histogram)+        # This is an arbitrarily chosen tolerance, but we're being fairly+        # lenient here and giving a 20% tolerance.  We're only interested+        # in cases where it's obviously broken and not a uniform distribution.+        tolerance = 0.20+        low = expected_value - (expected_value * tolerance)+        high = expected_value + (expected_value * tolerance)+        out_of_range = [+            str(i) for i in histogram.values() if not low <= i <= high+        ]+        if out_of_range:+            raise AssertionError(+                "Backoff values outside of uniform distribution range "+                f"({low} - {high}): {', '.join(out_of_range)}"+            )++[email protected]('botocore.retries.standard.NEW_RETRIES_ENABLED', True)+class TestRetryQuotaChecker(unittest.TestCase):+    def setUp(self):+        self.quota = quota.RetryQuota(500)+        self.throttling_detector = standard.ThrottlingErrorDetector(+            standard.RetryEventAdapter()+        )+        self.quota_checker = standard.RetryQuotaChecker(+            self.quota, self.throttling_detector+        )+        self.request_context = {}++    def create_context(+        self,+        is_timeout_error=False,+        status_code=200,+        is_throttling_error=False,+    ):+        caught_exception = None+        parsed_response = {}+        if is_timeout_error:+            caught_exception = ReadTimeoutError(endpoint_url='https://foo')+        if is_throttling_error:+            status_code = 400+            parsed_response = {'Error': {'Code': 'Throttling'}}+        http_response = AWSResponse(+            status_code=status_code, raw=None, headers={}, url='https://foo/'+        )+        context = standard.RetryContext(+            attempt_number=1,+            request_context=self.request_context,+            caught_exception=caught_exception,+            http_response=http_response,+            parsed_response=parsed_response,+        )+        return context++    def test_can_acquire_quota_for_throttling_error(self):+        self.assertTrue(+            self.quota_checker.acquire_retry_quota(+                self.create_context(is_throttling_error=True)+            )+        )+        self.assertEqual(self.request_context['retry_quota_capacity'], 5)++    def test_can_acquire_quota_non_timeout_error(self):+        self.assertTrue(+            self.quota_checker.acquire_retry_quota(self.create_context())+        )+        self.assertEqual(self.request_context['retry_quota_capacity'], 14)++    def test_can_acquire_quota_for_timeout_error(self):+        self.assertTrue(+            self.quota_checker.acquire_retry_quota(+                self.create_context(is_timeout_error=True)+            )+        )+        self.assertEqual(self.request_context['retry_quota_capacity'], 14)++    def test_can_release_quota_based_on_context_value_on_success(self):+        context = self.create_context()+        http_response = self.create_context(status_code=200).http_response+        self.assertTrue(self.quota_checker.acquire_retry_quota(context))+        self.assertEqual(self.quota.available_capacity, 486)+        self.quota_checker.release_retry_quota(+            context.request_context, http_response=http_response+        )+        self.assertEqual(self.quota.available_capacity, 500)++    def test_can_release_quota_when_succeed_after_throttling_error(self):+        context = self.create_context(is_throttling_error=True)+        http_response = self.create_context(status_code=200).http_response+        self.assertTrue(self.quota_checker.acquire_retry_quota(context))+        self.assertEqual(self.quota.available_capacity, 495)+        self.quota_checker.release_retry_quota(+            context.request_context, http_response=http_response+        )+        self.assertEqual(self.quota.available_capacity, 500)++    def test_dont_release_quota_if_all_retries_failed(self):+        context = self.create_context()+        http_response = self.create_context(status_code=500).http_response+        self.assertTrue(self.quota_checker.acquire_retry_quota(context))+        self.assertEqual(self.quota.available_capacity, 486)+        self.quota_checker.release_retry_quota(+            context.request_context, http_response=http_response+        )+        self.assertEqual(self.quota.available_capacity, 486)++    def test_can_release_default_quota_if_not_in_context(self):+        context = self.create_context()+        self.assertTrue(self.quota_checker.acquire_retry_quota(context))+        self.assertEqual(self.quota.available_capacity, 486)+        self.request_context.pop('retry_quota_capacity')+        self.quota_checker.release_retry_quota(+            context.request_context, context.http_response+        )+        self.assertEqual(self.quota.available_capacity, 487)++    def test_acquire_quota_fails(self):+        quota_checker = standard.RetryQuotaChecker(+            quota.RetryQuota(initial_capacity=14)+        )+        self.assertTrue(+            quota_checker.acquire_retry_quota(self.create_context())+        )+        self.request_context.pop('retry_quota_capacity')+        self.assertFalse(+            quota_checker.acquire_retry_quota(self.create_context())+        )+        self.assertNotIn('retry_quota_capacity', self.request_context)++    def test_quota_reached_adds_retry_metadata(self):+        quota_checker = standard.RetryQuotaChecker(+            quota.RetryQuota(initial_capacity=0)+        )+        context = self.create_context()+        self.assertFalse(quota_checker.acquire_retry_quota(context))+        self.assertEqual(+            context.get_retry_metadata(), {'RetryQuotaReached': True}+        )++    def test_single_failed_request_does_not_give_back_quota(self):+        context = self.create_context()+        http_response = self.create_context(status_code=400).http_response+        self.quota.acquire(50)+        self.assertEqual(self.quota.available_capacity, 450)+        self.quota_checker.release_retry_quota(+            context.request_context, http_response=http_response+        )+        self.assertEqual(self.quota.available_capacity, 450)++[email protected]('botocore.retries.standard.NEW_RETRIES_ENABLED', True)+class TestServiceSpecificRetriesSync(unittest.TestCase):+    def _make_retry_context(self, attempt, status_code, error_code=None):+        http_response = AWSResponse(+            status_code=status_code, raw=None, headers={}, url='https://foo/'+        )+        parsed_response = {}+        if error_code:+            parsed_response = {'Error': {'Code': error_code}}+        return standard.RetryContext(+            attempt_number=attempt,+            operation_model=mock.Mock(error_shapes=[]),+            http_response=http_response,+            parsed_response=parsed_response,+            request_context={},+        )++    def test_dynamodb_base_backoff_and_increased_retries(self):+        retry_quota_bucket = quota.RetryQuota()
… 305 more lines (truncated)
tests/botocore_tests/unit/test_args.py +290 lines · 1 flagged
--- +++ @@ -0,0 +1,290 @@+#!/usr/bin/env+# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.+#+# Licensed under the Apache License, Version 2.0 (the "License"). You+# may not use this file except in compliance with the License. A copy of+# the License is located at+#+# http://aws.amazon.com/apache2.0/+#+# or in the "license" file accompanying this file. This file is+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF+# ANY KIND, either express or implied. See the License for the specific+# language governing permissions and limitations under the License.+from botocore.client import ClientEndpointBridge+from botocore.configprovider import ConfigValueStore+from botocore.useragent import UserAgentString++from aiobotocore import args+from aiobotocore.config import AioConfig+from aiobotocore.credentials import AioCredentials+from aiobotocore.hooks import AioHierarchicalEmitter+from tests.botocore_tests import mock, unittest+++class TestEndpointResolverBuiltins(unittest.TestCase):+    def setUp(self):+        event_emitter = mock.Mock(AioHierarchicalEmitter)+        self.config_store = ConfigValueStore()+        user_agent_creator = UserAgentString(+            platform_name=None,+            platform_version=None,+            platform_machine=None,+            python_version=None,+            python_implementation=None,+            execution_env=None,+            crt_version=None,+        )+        self.args_create = args.AioClientArgsCreator(+            event_emitter=event_emitter,+            user_agent=None,+            response_parser_factory=None,+            loader=None,+            exceptions_factory=None,+            config_store=self.config_store,+            user_agent_creator=user_agent_creator,+        )+        self.bridge = ClientEndpointBridge(+            endpoint_resolver=mock.Mock(),+            scoped_config=None,+            client_config=AioConfig(),+            default_endpoint=None,+            service_signing_name=None,+            config_store=self.config_store,+        )+        # assume a legacy endpoint resolver that uses the builtin+        # endpoints.json file+        self.bridge.endpoint_resolver.uses_builtin_data = True++    def call_compute_endpoint_resolver_builtin_defaults(self, **overrides):+        defaults = {+            'region_name': 'ca-central-1',+            'service_name': 'fooservice',+            's3_disable_express_session_auth': False,+            's3_config': {},+            'endpoint_bridge': self.bridge,+            'client_endpoint_url': None,+            'legacy_endpoint_url': 'https://my.legacy.endpoint.com',+            'credentials': None,+            'account_id_endpoint_mode': 'preferred',+        }+        kwargs = {**defaults, **overrides}+        return self.args_create.compute_endpoint_resolver_builtin_defaults(+            **kwargs+        )++    def test_builtins_defaults(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults()+        self.assertEqual(bins['AWS::Region'], 'ca-central-1')+        self.assertEqual(bins['AWS::UseFIPS'], False)+        self.assertEqual(bins['AWS::UseDualStack'], False)+        self.assertEqual(bins['AWS::STS::UseGlobalEndpoint'], False)+        self.assertEqual(bins['AWS::S3::UseGlobalEndpoint'], False)+        self.assertEqual(bins['AWS::S3::Accelerate'], False)+        self.assertEqual(bins['AWS::S3::ForcePathStyle'], False)+        self.assertEqual(bins['AWS::S3::UseArnRegion'], True)+        self.assertEqual(bins['AWS::S3Control::UseArnRegion'], False)+        self.assertEqual(+            bins['AWS::S3::DisableMultiRegionAccessPoints'], False+        )+        self.assertEqual(bins['AWS::S3::DisableS3ExpressSessionAuth'], False)+        self.assertEqual(bins['SDK::Endpoint'], None)+        self.assertEqual(bins['AWS::Auth::AccountId'], None)+        self.assertEqual(bins['AWS::Auth::AccountIdEndpointMode'], 'preferred')++    def test_aws_region(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            region_name='my-region-1',+        )+        self.assertEqual(bins['AWS::Region'], 'my-region-1')++    def test_aws_use_fips_when_config_is_set_true(self):+        self.config_store.set_config_variable('use_fips_endpoint', True)+        bins = self.call_compute_endpoint_resolver_builtin_defaults()+        self.assertEqual(bins['AWS::UseFIPS'], True)++    def test_aws_use_fips_when_config_is_set_false(self):+        self.config_store.set_config_variable('use_fips_endpoint', False)+        bins = self.call_compute_endpoint_resolver_builtin_defaults()+        self.assertEqual(bins['AWS::UseFIPS'], False)++    def test_aws_use_dualstack_when_config_is_set_true(self):+        self.bridge.client_config = AioConfig(+            s3={'use_dualstack_endpoint': True}+        )+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            service_name='s3-control'+        )+        self.assertEqual(bins['AWS::UseDualStack'], True)++    def test_aws_use_dualstack_when_config_is_set_false(self):+        self.bridge.client_config = AioConfig(+            s3={'use_dualstack_endpoint': False}+        )+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            service_name='s3-control'+        )+        self.assertEqual(bins['AWS::UseDualStack'], False)++    def test_aws_use_dualstack_when_non_dualstack_service(self):+        self.bridge.client_config = AioConfig(+            s3={'use_dualstack_endpoint': True}+        )+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            service_name='other-service'+        )+        self.assertEqual(bins['AWS::UseDualStack'], False)++    def test_aws_sts_global_endpoint_with_default_and_legacy_region(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            region_name='us-west-2',+        )+        self.assertEqual(bins['AWS::STS::UseGlobalEndpoint'], False)++    def test_aws_sts_global_endpoint_with_default_and_nonlegacy_region(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            region_name='eu-south-1',+        )+        self.assertEqual(bins['AWS::STS::UseGlobalEndpoint'], False)++    def test_aws_sts_global_endpoint_with_nondefault_config(self):+        self.config_store.set_config_variable(+            'sts_regional_endpoints', 'regional'+        )+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            region_name='us-west-2',+        )+        self.assertEqual(bins['AWS::STS::UseGlobalEndpoint'], False)++    def test_s3_global_endpoint(self):+        # The only reason for this builtin to not have the default value+        # (False) is that the ``_should_force_s3_global`` method+        # returns True.+        self.args_create._should_force_s3_global = mock.Mock(return_value=True)+        bins = self.call_compute_endpoint_resolver_builtin_defaults()+        self.assertTrue(bins['AWS::S3::UseGlobalEndpoint'])+        self.args_create._should_force_s3_global.assert_called_once()++    def test_s3_accelerate_with_config_set_true(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'use_accelerate_endpoint': True},+        )+        self.assertEqual(bins['AWS::S3::Accelerate'], True)++    def test_s3_accelerate_with_config_set_false(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'use_accelerate_endpoint': False},+        )+        self.assertEqual(bins['AWS::S3::Accelerate'], False)++    def test_force_path_style_with_config_set_to_path(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'addressing_style': 'path'},+        )+        self.assertEqual(bins['AWS::S3::ForcePathStyle'], True)++    def test_force_path_style_with_config_set_to_auto(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'addressing_style': 'auto'},+        )+        self.assertEqual(bins['AWS::S3::ForcePathStyle'], False)++    def test_force_path_style_with_config_set_to_virtual(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'addressing_style': 'virtual'},+        )+        self.assertEqual(bins['AWS::S3::ForcePathStyle'], False)++    def test_use_arn_region_with_config_set_false(self):+        # These two builtins both take their value from the ``use_arn_region``+        # in the S3 configuration, but have different default values.+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'use_arn_region': False},+        )+        self.assertEqual(bins['AWS::S3::UseArnRegion'], False)+        self.assertEqual(bins['AWS::S3Control::UseArnRegion'], False)++    def test_use_arn_region_with_config_set_true(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'use_arn_region': True},+        )+        self.assertEqual(bins['AWS::S3::UseArnRegion'], True)+        self.assertEqual(bins['AWS::S3Control::UseArnRegion'], True)++    def test_disable_mrap_with_config_set_true(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'s3_disable_multiregion_access_points': True},+        )+        self.assertEqual(bins['AWS::S3::DisableMultiRegionAccessPoints'], True)++    def test_disable_mrap_with_config_set_false(self):+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            s3_config={'s3_disable_multiregion_access_points': False},+        )+        self.assertEqual(+            bins['AWS::S3::DisableMultiRegionAccessPoints'], False+        )++    def test_sdk_endpoint_both_inputs_set(self):+        # assume a legacy endpoint resolver that uses a customized+        # endpoints.json file+        self.bridge.endpoint_resolver.uses_builtin_data = False+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            client_endpoint_url='https://my.client.endpoint.com',+            legacy_endpoint_url='https://my.legacy.endpoint.com',+        )+        self.assertEqual(+            bins['SDK::Endpoint'], 'https://my.client.endpoint.com'+        )++    def test_sdk_endpoint_legacy_set_with_builtin_data(self):+        # assume a legacy endpoint resolver that uses a customized+        # endpoints.json file+        self.bridge.endpoint_resolver.uses_builtin_data = False+        bins = self.call_compute_endpoint_resolver_builtin_defaults(+            client_endpoint_url=None,+            legacy_endpoint_url='https://my.legacy.endpoint.com',+        )
… 43 more lines (truncated)
tests/botocore_tests/unit/test_credentials.py +2661 lines · 12 flagged
--- +++ @@ -0,0 +1,2661 @@+"""+These tests have been taken from+https://github.com/boto/botocore/blob/develop/tests/unit/test_credentials.py+and adapted to work with asyncio and pytest+"""++import asyncio+import json+import logging+import os+import shlex+import shutil+import subprocess+import sys+import tempfile+import uuid+from contextlib import asynccontextmanager+from datetime import datetime, timedelta+from functools import partial+from unittest import TestCase, mock++import botocore.exceptions+import pytest+import wrapt+from botocore.configprovider import ConfigValueStore+from botocore.credentials import (+    Credentials,+    JSONFileCache,+    ReadOnlyCredentials,+)+from botocore.exceptions import (+    ClientError,+    LoginError,+    MissingDependencyException,+)+from botocore.stub import Stubber+from botocore.utils import (+    FileWebIdentityTokenLoader,+    SSOTokenLoader,+    datetime2timestamp,+)+from dateutil.tz import tzlocal, tzutc++from aiobotocore import credentials+from aiobotocore._async_primitives import (+    AsyncPrimitives,+    infer_async_primitives,+)+from aiobotocore._httpx import httpx+from aiobotocore.config import AioConfig+from aiobotocore.credentials import (+    AioAssumeRoleProvider,+    AioCanonicalNameCredentialSourcer,+    AioContainerProvider,+    AioEnvProvider,+    AioInstanceMetadataProvider,+    AioLoginProvider,+    AioProfileProviderBuilder,+    AioSSOCredentialFetcher,+    AioSSOProvider,+)+from aiobotocore.httpxsession import is_httpx_session_cls+from aiobotocore.session import AioSession+from tests.botocore_tests import random_chars, requires_crt, skip_if_crt+from tests.botocore_tests.helpers import StubbedSession++SAMPLE_SIGN_IN_DPOP_PEM = (+    '-----BEGIN EC PRIVATE KEY-----\n'+    'MHcCAQEEIDXxfh2F6vl+AX+tK/jvY5ll6aZ9n8sI2ODsWCmrsx'+    'SDoAoGCCqGSM49\nAwEHoUQDQgAERKnl1X15pEx7ebbMQ0dFw6'+    'VeOuCjEuh3NT8dwnBHYyF/7YDy8+Fu\nCx+4wgiSs9sRD3LaDK'+    'CjIbbmEq07Jw59YQ==\n-----END EC PRIVATE KEY-----\n'+)+++# From class TestCredentials(BaseEnvVar):[email protected](+    "access,secret", [('foo\xe2\x80\x99', 'bar\xe2\x80\x99'), ('foo', 'bar')]+)+def test_credentials_normalization(access, secret):+    c = credentials.AioCredentials(access, secret)+    assert isinstance(c.access_key, str)+    assert isinstance(c.secret_key, str)+++# From class TestAssumeRoleCredentialFetcher(BaseEnvVar):+def assume_role_client_creator(with_response):+    class _Client:+        def __init__(self, resp):+            self._resp = resp++            self._called = []+            self._call_count = 0++        async def assume_role(self, *args, **kwargs):+            self._call_count += 1+            self._called.append((args, kwargs))++            if isinstance(self._resp, list):+                return self._resp.pop(0)+            return self._resp++        async def __aenter__(self):+            return self++        async def __aexit__(self, exc_type, exc_val, exc_tb):+            pass++    return mock.Mock(return_value=_Client(with_response))+++def some_future_time():+    timeobj = datetime.now(tzlocal())+    return timeobj + timedelta(hours=24)+++def get_expected_creds_from_response(response):+    expiration = response['Credentials']['Expiration']+    if isinstance(expiration, datetime):+        expiration = expiration.isoformat()+    return {+        'access_key': response['Credentials']['AccessKeyId'],+        'secret_key': response['Credentials']['SecretAccessKey'],+        'token': response['Credentials']['SessionToken'],+        'expiry_time': expiration,+        'account_id': response.get('Credentials', {}).get('AccountId'),+    }+++# From class CredentialResolverTest(BaseEnvVar):[email protected]+def credential_provider():+    def _f(method, canonical_name, creds='None'):+        # 'None' so that we can differentiate from None+        provider = mock.Mock()+        provider.METHOD = method+        provider.CANONICAL_NAME = canonical_name++        async def load():+            if creds != 'None':+                return creds++            return mock.Mock()++        provider.load = load+        return provider++    return _f+++async def test_assumerolefetcher_no_cache():+    response = {+        'Credentials': {+            'AccessKeyId': 'foo',+            'SecretAccessKey': 'bar',+            'SessionToken': 'baz',+            'Expiration': some_future_time().isoformat(),+        },+    }+    refresher = credentials.AioAssumeRoleCredentialFetcher(+        assume_role_client_creator(response),+        credentials.AioCredentials('a', 'b', 'c'),+        'myrole',+    )++    expected_response = get_expected_creds_from_response(response)+    response = await refresher.fetch_credentials()++    assert response == expected_response+++async def test_assumerolefetcher_cache_key_with_role_session_name():+    response = {+        'Credentials': {+            'AccessKeyId': 'foo',+            'SecretAccessKey': 'bar',+            'SessionToken': 'baz',+            'Expiration': some_future_time().isoformat(),+        },+    }+    cache = {}+    client_creator = assume_role_client_creator(response)+    role_session_name = 'my_session_name'++    refresher = credentials.AioAssumeRoleCredentialFetcher(+        client_creator,+        credentials.AioCredentials('a', 'b', 'c'),+        'myrole',+        cache=cache,+        extra_args={'RoleSessionName': role_session_name},+    )+    await refresher.fetch_credentials()++    # This is the sha256 hex digest of the expected assume role args.+    cache_key = '2964201f5648c8be5b9460a9cf842d73a266daf2'+    assert cache_key in cache+    assert cache[cache_key] == response+++async def test_assumerolefetcher_cache_in_cache_but_expired():+    response = {+        'Credentials': {+            'AccessKeyId': 'foo',+            'SecretAccessKey': 'bar',+            'SessionToken': 'baz',+            'Expiration': some_future_time().isoformat(),+        },+    }+    client_creator = assume_role_client_creator(response)+    cache = {+        'development--myrole': {+            'Credentials': {+                'AccessKeyId': 'foo-cached',+                'SecretAccessKey': 'bar-cached',+                'SessionToken': 'baz-cached',+                'Expiration': datetime.now(tzlocal()),+            }+        }+    }++    refresher = credentials.AioAssumeRoleCredentialFetcher(+        client_creator,+        credentials.AioCredentials('a', 'b', 'c'),+        'myrole',+        cache=cache,+    )+    expected = get_expected_creds_from_response(response)+    response = await refresher.fetch_credentials()++    assert response == expected+++async def test_assumerolefetcher_mfa():+    response = {+        'Credentials': {+            'AccessKeyId': 'foo',+            'SecretAccessKey': 'bar',+            'SessionToken': 'baz',+            'Expiration': some_future_time().isoformat(),+        },+    }+    client_creator = assume_role_client_creator(response)+    prompter = mock.Mock(return_value='token-code')+    mfa_serial = 'mfa'++    refresher = credentials.AioAssumeRoleCredentialFetcher(+        client_creator,
… 2414 more lines (truncated)
tests/botocore_tests/unit/test_protocols.py +455 lines · 3 flagged
--- +++ @@ -0,0 +1,455 @@+#!/usr/bin/env python+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.+#+# Licensed under the Apache License, Version 2.0 (the "License"). You+# may not use this file except in compliance with the License. A copy of+# the License is located at+#+# http://aws.amazon.com/apache2.0/+#+# or in the "license" file accompanying this file. This file is+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF+# ANY KIND, either express or implied. See the License for the specific+# language governing permissions and limitations under the License.+"""Test runner for the JSON models compliance tests++This is a test runner for all the output JSON tests defined in+``tests/unit/protocols/``.++You can use the normal ``python -m pytest tests/unit/test_protocols.py``+to run this test.  In addition, there are several env vars you can use during+development.++Tests are broken down by filename, test suite, testcase.  When a test fails+you'll see the protocol (filename), test suite, and test case number of the+failed test.++::++    Description           : Scalar members (0:0)  <--- (suite_id:test_id)+    Protocol:             : ec2                  <--- test file (ec2.json)+    Given                 : ...+    Response              : ...+    Expected serialization: ...+    Actual serialization  : ...+    Assertion message     : ...++To run tests from only a single file, you can set the+BOTOCORE_TEST env var::++    BOTOCORE_TEST=tests/unit/protocols/input/json.json pytest tests/unit/test_protocols.py++To run a single test suite you can set the BOTOCORE_TEST_ID env var:++    BOTOCORE_TEST=tests/unit/protocols/input/json.json BOTOCORE_TEST_ID=5 \+        pytest tests/unit/test_protocols.py++To run a single test case in a suite (useful when debugging a single test), you+can set the BOTOCORE_TEST_ID env var with the ``suite_id:test_id`` syntax.++    BOTOCORE_TEST_ID=5:1 pytest tests/unit/test_protocols.py++"""++import base64+import copy+import os+from enum import Enum++import pytest+from botocore.awsrequest import HeadersDict+from botocore.compat import OrderedDict, json+from botocore.model import NoShapeFoundError, OperationModel, ServiceModel+from botocore.utils import parse_timestamp+from dateutil.tz import tzutc++from aiobotocore.eventstream import AioEventStream+from aiobotocore.parsers import (+    AioEC2QueryParser,+    AioJSONParser,+    AioQueryParser,+    AioRestJSONParser,+    AioRestXMLParser,+    AioRpcV2CBORParser,+)++TEST_DIR = os.path.join(+    os.path.dirname(os.path.abspath(__file__)), 'protocols'+)+PROTOCOL_PARSERS = {+    'ec2': AioEC2QueryParser,+    'query': AioQueryParser,+    'json': AioJSONParser,+    'rest-json': AioRestJSONParser,+    'rest-xml': AioRestXMLParser,+    'smithy-rpc-v2-cbor': AioRpcV2CBORParser,+}+IGNORE_LIST_FILENAME = "protocol-tests-ignore-list.json"+++class TestType(Enum):+    # Tell test runner to ignore this class+    __test__ = False++    INPUT = "input"+    OUTPUT = "output"+++def get_protocol_test_ignore_list():+    ignore_list_path = os.path.join(TEST_DIR, IGNORE_LIST_FILENAME)+    with open(ignore_list_path) as f:+        return json.load(f)+++def _compliance_tests(test_type=None):+    inp = test_type is None or test_type is TestType.INPUT+    out = test_type is None or test_type is TestType.OUTPUT++    for full_path in _walk_files():+        if full_path.endswith('.json'):+            for model, case, basename in _load_cases(full_path):+                protocol = basename.replace('.json', '')+                if _should_ignore_test(+                    protocol,+                    "input" if inp else "output",+                    model['description'],+                    case.get('id'),+                ):+                    continue+                if ('params' in case and inp) or ('response' in case and out):+                    yield model, case, basename+++class FakeStreamReader:+    class ChunkedIterator:+        def __init__(self, chunks):+            self.iter = iter((chunks,))++        def __aiter__(self):+            return self++        async def __anext__(self):+            try:+                result = next(self.iter)+                return result, True+            except StopIteration:+                raise StopAsyncIteration()++    def __init__(self, chunks):+        self.chunks = base64.b64decode(chunks)+        self.content = self++    def iter_chunks(self):+        return self.ChunkedIterator(self.chunks)++[email protected](+    "json_description, case, basename", _compliance_tests(TestType.OUTPUT)+)+async def test_output_compliance(json_description, case, basename):+    service_description = copy.deepcopy(json_description)+    case = copy.deepcopy(case)+    operation_name = case.get('given', {}).get('name', 'OperationName')+    service_description['operations'] = {+        operation_name: case,+    }+    case['response']['context'] = {'operation_name': operation_name}+    try:+        model = ServiceModel(service_description)+        operation_model = OperationModel(case['given'], model)+        protocol = model.metadata['protocol']+        parser = PROTOCOL_PARSERS[protocol](+            timestamp_parser=_compliance_timestamp_parser+        )+        # We load the json as utf-8, but the response parser is at the+        # botocore boundary, so it expects to work with bytes.+        # If a test case doesn't define a response body, set it to `None`.+        if 'body' in case['response']:+            body_bytes = case['response']['body'].encode('utf-8')+            case['response']['body'] = body_bytes+        else:+            case['response']['body'] = (+                b'' if protocol != "query" else b'<xml/>'+            )+        # We need the headers to be case insensitive+        # If a test case doesn't define response headers, set it to an empty `HeadersDict`.+        case['response']['headers'] = HeadersDict(+            case['response'].get('headers', {})+        )+        # If this is an event stream fake the raw streamed response+        if operation_model.has_event_stream_output:+            case['response']['body'] = FakeStreamReader(body_bytes)+        if 'error' in case:+            output_shape = operation_model.output_shape+            if protocol == 'smithy-rpc-v2-cbor':+                case['response']['body'] = base64.b64decode(+                    case['response']['body']+                )+            parsed = await parser.parse(case['response'], output_shape)+            try:+                error_code = parsed.get("Error", {}).get("Code")+                error_shape = model.shape_for_error_code(error_code)+            except NoShapeFoundError:+                error_shape = None+            if error_shape is not None:+                error_parse = await parser.parse(case['response'], error_shape)+                parsed.update(error_parse)+        else:+            output_shape = operation_model.output_shape+            if protocol == 'query' and output_shape and output_shape.members:+                output_shape.serialization['resultWrapper'] = (+                    f'{operation_name}Result'+                )+            elif protocol == 'smithy-rpc-v2-cbor':+                case['response']['body'] = base64.b64decode(+                    case['response']['body']+                )+            parsed = await parser.parse(case['response'], output_shape)+        parsed = await _fixup_parsed_result(parsed)+    except Exception as e:  # pragma: no cover+        msg = (+            "\nFailed to run test  : {}\n"+            "Protocol            : {}\n"+            "Description         : {} ({}:{})\n".format(+                e,+                model.metadata['protocol'],+                case['description'],+                case['suite_id'],+                case['test_id'],+            )+        )+        raise AssertionError(msg)+    try:+        if 'error' in case:+            expected_result = {+                'Error': {+                    'Code': case.get('errorCode', ''),+                    'Message': case.get('errorMessage', ''),+                }+            }+            expected_result.update(case['error'])+        else:+            expected_result = case['result']+        assert_equal(parsed, expected_result, "Body")+    except Exception as e:  # pragma: no cover+        _output_failure_message(+            model.metadata['protocol'], case, parsed, expected_result, e+        )+++async def _fixup_parsed_result(parsed):+    # This function contains all the transformation we need+    # to do from the response _our_ response parsers give+    # vs. the expected responses in the protocol tests.+    # These are implementation specific changes, not any+    # "we're not following the spec"-type changes.++    # 1. RequestMetadata.  We parse this onto the returned dict, but compliance
… 208 more lines (truncated)
tests/botocore_tests/unit/test_signers.py +403 lines · 1 flagged
--- +++ @@ -0,0 +1,403 @@+# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.+#+# Licensed under the Apache License, Version 2.0 (the "License"). You+# may not use this file except in compliance with the License. A copy of+# the License is located at+#+# http://aws.amazon.com/apache2.0/+#+# or in the "license" file accompanying this file. This file is+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF+# ANY KIND, either express or implied. See the License for the specific+# language governing permissions and limitations under the License.+import datetime+from datetime import timezone+from unittest import mock++import botocore.auth+import pytest+from botocore.awsrequest import AWSRequest+from botocore.exceptions import (+    NoRegionError,+    ParamValidationError,+    UnknownClientMethodError,+    UnknownSignatureVersionError,+)+from botocore.model import ServiceId++import aiobotocore.credentials+import aiobotocore.session+import aiobotocore.signers+from tests.botocore_tests import assert_url_equal++DATE = datetime.datetime(2024, 11, 7, 17, 39, 33, tzinfo=timezone.utc)++[email protected](+    'aws_auth',+    [{'aws_secret_access_key': 'skid', 'aws_access_key_id': 'akid'}],+)+async def test_signers_generate_db_auth_token(rds_client):+    hostname = 'prod-instance.us-east-1.rds.amazonaws.com'+    port = 3306+    username = 'someusername'+    clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=timezone.utc)++    with mock.patch('datetime.datetime') as dt:+        dt.now.return_value = clock+        result = await aiobotocore.signers.generate_db_auth_token(+            rds_client, hostname, port, username+        )++        result2 = await rds_client.generate_db_auth_token(+            hostname, port, username+        )++    expected_result = (+        'prod-instance.us-east-1.rds.amazonaws.com:3306/?Action=connect'+        '&DBUser=someusername&X-Amz-Algorithm=AWS4-HMAC-SHA256'+        '&X-Amz-Date=20161107T173933Z&X-Amz-SignedHeaders=host'+        '&X-Amz-Expires=900&X-Amz-Credential=akid%2F20161107%2F'+        'us-east-1%2Frds-db%2Faws4_request&X-Amz-Signature'+        '=d1138cdbc0ca63eec012ec0fc6c2267e03642168f5884a7795320d4c18374c61'+    )++    assert_url_equal('http://' + result, 'http://' + expected_result)++    assert result2 == result+++class TestDSQLGenerateDBAuthToken:+    @pytest.fixture(scope="session")+    def hostname(self):+        return 'test.dsql.us-east-1.on.aws'++    @pytest.fixture(scope="session")+    def action(self):+        return 'DbConnect'++    @pytest.fixture+    async def client(self, session):+        async with session.create_client(+            'dsql',+            region_name='us-east-1',+            aws_access_key_id='ACCESS_KEY',+            aws_secret_access_key='SECRET_KEY',+            aws_session_token="SESSION_TOKEN",+        ) as client:+            yield client++    async def test_dsql_generate_db_auth_token(+        self, client, hostname, action, time_machine+    ):+        time_machine.move_to(DATE, tick=False)++        result = await aiobotocore.signers._dsql_generate_db_auth_token(+            client, hostname, action+        )++        expected_result = (+            'test.dsql.us-east-1.on.aws/?Action=DbConnect'+            '&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential='+            'ACCESS_KEY%2F20241107%2Fus-east-1%2Fdsql%2Faws4_request'+            '&X-Amz-Date=20241107T173933Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host'+            '&X-Amz-Security-Token=SESSION_TOKEN&X-Amz-Signature='+            '57fe03e060348aaa21405c239bf02572bbc911076e94dcd65c12ae569dd8fcf4'+        )++        # A scheme needs to be appended to the beginning or urlsplit may fail+        # on certain systems.+        assert_url_equal('https://' + result, 'https://' + expected_result)++    async def test_dsql_generate_db_connect_auth_token(+        self, client, hostname, time_machine+    ):+        time_machine.move_to(DATE, tick=False)++        result = await aiobotocore.signers.dsql_generate_db_connect_auth_token(+            client, hostname+        )++        expected_result = (+            'test.dsql.us-east-1.on.aws/?Action=DbConnect'+            '&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential='+            'ACCESS_KEY%2F20241107%2Fus-east-1%2Fdsql%2Faws4_request'+            '&X-Amz-Date=20241107T173933Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host'+            '&X-Amz-Security-Token=SESSION_TOKEN&X-Amz-Signature='+            '57fe03e060348aaa21405c239bf02572bbc911076e94dcd65c12ae569dd8fcf4'+        )++        # A scheme needs to be appended to the beginning or urlsplit may fail+        # on certain systems.+        assert_url_equal('https://' + result, 'https://' + expected_result)++    async def test_dsql_generate_db_connect_admin_auth_token(+        self, client, hostname, time_machine+    ):+        time_machine.move_to(DATE, tick=False)++        result = await aiobotocore.signers.dsql_generate_db_connect_admin_auth_token(+            client, hostname+        )++        expected_result = (+            'test.dsql.us-east-1.on.aws/?Action=DbConnectAdmin'+            '&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential='+            'ACCESS_KEY%2F20241107%2Fus-east-1%2Fdsql%2Faws4_request'+            '&X-Amz-Date=20241107T173933Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host'+            '&X-Amz-Security-Token=SESSION_TOKEN&X-Amz-Signature='+            '5ac084bc7cabccc19a52a5d1b5c24b50d3ce143f43b659bd484c91aaf555e190'+        )++        # A scheme needs to be appended to the beginning or urlsplit may fail+        # on certain systems.+        assert_url_equal('https://' + result, 'https://' + expected_result)++    async def test_dsql_generate_db_auth_token_invalid_action(+        self, client, hostname+    ):+        with pytest.raises(ParamValidationError):+            await aiobotocore.signers._dsql_generate_db_auth_token(+                client, hostname, "FooBar"+            )+++# From class TestSigner[email protected]+async def base_signer_setup() -> dict:+    emitter = mock.AsyncMock()+    emitter.emit_until_response.return_value = (None, None)+    credentials = aiobotocore.credentials.AioCredentials('key', 'secret')++    signer = aiobotocore.signers.AioRequestSigner(+        ServiceId('service_name'),+        'region_name',+        'signing_name',+        'v4',+        credentials,+        emitter,+    )+    return {+        'credentials': credentials,+        'emitter': emitter,+        'signer': signer,+        'fixed_credentials': await credentials.get_frozen_credentials(),+        'request': AWSRequest(),+    }++[email protected]+async def base_signer_setup_s3v4() -> dict:+    emitter = mock.AsyncMock()+    emitter.emit_until_response.return_value = (None, None)+    credentials = aiobotocore.credentials.AioCredentials('key', 'secret')++    request_signer = aiobotocore.signers.AioRequestSigner(+        ServiceId('service_name'),+        'region_name',+        'signing_name',+        's3v4',+        credentials,+        emitter,+    )+    signer = aiobotocore.signers.AioS3PostPresigner(request_signer)++    return {+        'credentials': credentials,+        'emitter': emitter,+        'signer': signer,+        'fixed_credentials': await credentials.get_frozen_credentials(),+        'request': AWSRequest(),+    }+++# From class TestGenerateUrl+async def test_signers_generate_presigned_urls():+    with mock.patch(+        'aiobotocore.signers.AioRequestSigner.generate_presigned_url'+    ) as cls_gen_presigned_url_mock:+        session = aiobotocore.session.get_session()+        async with session.create_client(+            's3',+            region_name='us-east-1',+            aws_access_key_id='lalala',+            aws_secret_access_key='lalala',+            aws_session_token='lalala',+        ) as client:+            # Uses HEAD as it covers more lines :)+            await client.generate_presigned_url(+                'get_object',+                Params={'Bucket': 'mybucket', 'Key': 'mykey'},+                HttpMethod='HEAD',+            )++            ref_request_dict = {+                'body': b'',+                'url': 'https://mybucket.s3.amazonaws.com/mykey',+                'headers': {},+                'query_string': {},+                'url_path': '/mykey',+                'method': 'HEAD',+                'context': mock.ANY,+                'auth_path': '/mybucket/mykey',+            }++            cls_gen_presigned_url_mock.assert_called_with(+                request_dict=ref_request_dict,+                expires_in=3600,
… 156 more lines (truncated)
tests/botocore_tests/unit/test_utils.py +1132 lines · 6 flagged
--- +++ @@ -0,0 +1,1132 @@+from __future__ import annotations++import itertools+import json+from collections.abc import Iterator+from contextlib import asynccontextmanager+from unittest import mock++import pytest+from botocore.endpoint_provider import RuleSetEndpoint+from botocore.exceptions import (+    ClientError,+    ConnectionClosedError,+    ConnectTimeoutError,+    InvalidRegionError,+    ReadTimeoutError,+)+from botocore.utils import BadIMDSRequestError, MetadataRetrievalError++from aiobotocore import utils+from aiobotocore.awsrequest import AioAWSResponse+from aiobotocore.httpxsession import is_httpx_session_cls+from aiobotocore.regions import AioEndpointRulesetResolver+from aiobotocore.utils import (+    AioInstanceMetadataFetcher,+    AioS3RegionRedirectorv2,+)+from tests.test_response import AsyncBytesIO+++class TestS3RegionRedirector:+    pytestmark = pytest.mark.anyio++    @pytest.fixture(autouse=True)+    def _setup(self):+        self.client = mock.AsyncMock()+        self.client._ruleset_resolver = AioEndpointRulesetResolver(+            endpoint_ruleset_data={+                'version': '1.0',+                'parameters': {},+                'rules': [],+            },+            partition_data={},+            service_model=mock.Mock(service_name='s3'),+            builtins={},+            client_context=None,+            event_emitter=None,+            use_ssl=True,+            requested_auth_scheme=None,+        )+        self.client._ruleset_resolver.construct_endpoint = mock.AsyncMock(+            return_value=RuleSetEndpoint(+                url='https://new-endpoint.amazonaws.com',+                properties={},+                headers={},+            )+        )+        self.cache = {}+        self.redirector = AioS3RegionRedirectorv2(None, self.client)+        self.set_client_response_headers({})+        self.operation = mock.Mock()+        self.operation.name = 'foo'++    def set_client_response_headers(self, headers):+        error_response = ClientError(+            {+                'Error': {'Code': '', 'Message': ''},+                'ResponseMetadata': {'HTTPHeaders': headers},+            },+            'HeadBucket',+        )+        success_response = {'ResponseMetadata': {'HTTPHeaders': headers}}+        self.client.head_bucket.side_effect = [+            error_response,+            success_response,+        ]++    def test_set_request_url(self):+        old_url = 'https://us-west-2.amazonaws.com/foo'+        new_endpoint = 'https://eu-central-1.amazonaws.com'+        new_url = self.redirector.set_request_url(old_url, new_endpoint)+        assert new_url == 'https://eu-central-1.amazonaws.com/foo'++    def test_set_request_url_keeps_old_scheme(self):+        old_url = 'http://us-west-2.amazonaws.com/foo'+        new_endpoint = 'https://eu-central-1.amazonaws.com'+        new_url = self.redirector.set_request_url(old_url, new_endpoint)+        assert new_url == 'http://eu-central-1.amazonaws.com/foo'++    def test_sets_signing_context_from_cache(self):+        self.cache['foo'] = 'new-region-1'+        self.redirector = AioS3RegionRedirectorv2(+            None, self.client, cache=self.cache+        )+        params = {'Bucket': 'foo'}+        builtins = {'AWS::Region': 'old-region-1'}+        self.redirector.redirect_from_cache(builtins, params)+        assert builtins.get('AWS::Region') == 'new-region-1'++    def test_only_changes_context_if_bucket_in_cache(self):+        self.cache['foo'] = 'new-region-1'+        self.redirector = AioS3RegionRedirectorv2(+            None, self.client, cache=self.cache+        )+        params = {'Bucket': 'bar'}+        builtins = {'AWS::Region': 'old-region-1'}+        self.redirector.redirect_from_cache(builtins, params)+        assert builtins.get('AWS::Region') == 'old-region-1'++    async def test_redirect_from_error(self):+        request_dict = {+            'context': {+                's3_redirect': {+                    'bucket': 'foo',+                    'redirected': False,+                    'params': {'Bucket': 'foo'},+                },+                'signing': {+                    'region': 'us-west-2',+                },+            },+            'url': 'https://us-west-2.amazonaws.com/foo',+        }+        response = (+            None,+            {+                'Error': {+                    'Code': 'PermanentRedirect',+                    'Endpoint': 'foo.eu-central-1.amazonaws.com',+                    'Bucket': 'foo',+                },+                'ResponseMetadata': {+                    'HTTPHeaders': {'x-amz-bucket-region': 'eu-central-1'}+                },+            },+        )++        self.client._ruleset_resolver.construct_endpoint.return_value = (+            RuleSetEndpoint(+                url='https://eu-central-1.amazonaws.com/foo',+                properties={+                    'authSchemes': [+                        {+                            'name': 'sigv4',+                            'signingRegion': 'eu-central-1',+                            'disableDoubleEncoding': True,+                        }+                    ]+                },+                headers={},+            )+        )++        redirect_response = await self.redirector.redirect_from_error(+            request_dict, response, self.operation+        )++        # The response needs to be 0 so that there is no retry delay+        assert redirect_response == 0++        assert request_dict['url'] == 'https://eu-central-1.amazonaws.com/foo'++        expected_signing_context = {+            'region': 'eu-central-1',+            'disableDoubleEncoding': True,+        }+        signing_context = request_dict['context'].get('signing')+        assert signing_context == expected_signing_context+        assert request_dict['context']['s3_redirect'].get('redirected')++    async def test_does_not_redirect_if_previously_redirected(self):+        request_dict = {+            'context': {+                'signing': {'bucket': 'foo', 'region': 'us-west-2'},+                's3_redirected': True,+            },+            'url': 'https://us-west-2.amazonaws.com/foo',+        }+        response = (+            None,+            {+                'Error': {+                    'Code': '400',+                    'Message': 'Bad Request',+                },+                'ResponseMetadata': {+                    'HTTPHeaders': {'x-amz-bucket-region': 'us-west-2'}+                },+            },+        )+        redirect_response = await self.redirector.redirect_from_error(+            request_dict, response, self.operation+        )+        assert redirect_response is None++    async def test_does_not_redirect_unless_permanentredirect_recieved(self):+        request_dict = {}+        response = (None, {})+        redirect_response = await self.redirector.redirect_from_error(+            request_dict, response, self.operation+        )+        assert redirect_response is None+        assert request_dict == {}++    async def test_does_not_redirect_if_region_cannot_be_found(self):+        request_dict = {+            'url': 'https://us-west-2.amazonaws.com/foo',+            'context': {+                's3_redirect': {+                    'bucket': 'foo',+                    'redirected': False,+                    'params': {'Bucket': 'foo'},+                },+                'signing': {},+            },+        }+        response = (+            None,+            {+                'Error': {+                    'Code': 'PermanentRedirect',+                    'Endpoint': 'foo.eu-central-1.amazonaws.com',+                    'Bucket': 'foo',+                },+                'ResponseMetadata': {'HTTPHeaders': {}},+            },+        )++        redirect_response = await self.redirector.redirect_from_error(+            request_dict, response, self.operation+        )++        assert redirect_response is None++    async def test_redirects_301(self):+        request_dict = {+            'url': 'https://us-west-2.amazonaws.com/foo',+            'context': {+                's3_redirect': {+                    'bucket': 'foo',+                    'redirected': False,+                    'params': {'Bucket': 'foo'},+                },+                'signing': {},+            },+        }+        response = (
… 885 more lines (truncated)
tests/mock_server.py +114 lines · 1 flagged
--- +++ @@ -0,0 +1,114 @@+import asyncio+import threading++# Third Party+import aiohttp+import aiohttp.web+import anyio.to_thread+import pytest+from aiohttp.web import StreamResponse+from moto.server import ThreadedMotoServer++_proxy_bypass = {+    "http": None,+    "https": None,+}++host = '127.0.0.1'+++# A thread with its own loop, not a subprocess: the spawned child took >30s to bind on 3.12 and only 3.12.+class AIOServer:+    """+    This is a mock AWS service which will 5 seconds before returning+    a response to test socket timeouts.+    """++    def __init__(self):+        self.endpoint_url = None+        self._ready = threading.Event()+        self._stop = threading.Event()+        self._error = None+        self._thread = None++    def _run(self):+        loop = asyncio.new_event_loop()+        try:+            loop.run_until_complete(self._serve())+        except Exception as exc:+            self._error = exc+        finally:+            # Always unblock __aenter__, even if the loop died before binding.+            self._ready.set()+            loop.close()++    async def _serve(self):+        app = aiohttp.web.Application()+        app.router.add_route('*', '/ok', self.ok)+        app.router.add_route('*', '/{anything:.*}', self.stream_handler)++        runner = aiohttp.web.AppRunner(app)+        await runner.setup()+        # Port 0, published once bound: nothing can take it in between.+        site = aiohttp.web.TCPSite(runner, host, 0)+        await site.start()+        self.endpoint_url = site.name+        self._ready.set()+        await asyncio.to_thread(self._stop.wait)+        await runner.cleanup()++    async def __aenter__(self):+        self._thread = threading.Thread(target=self._run, daemon=True)+        self._thread.start()+        # __aexit__ only runs if __aenter__ returns, so a failed start stops here.+        if not await self._wait_until_up():+            await self._shutdown()+            pytest.fail('mock server never bound a port')+        if self._error is not None:+            await self._shutdown()+            raise self._error+        if self.endpoint_url is None:+            await self._shutdown()+            pytest.fail('mock server thread exited before binding')+        return self++    async def __aexit__(self, exc_type, exc_val, exc_tb):+        await self._shutdown()++    # anyio, not asyncio: this half runs on the test's framework, trio included.+    async def _wait_until_up(self, timeout: float = 30) -> bool:+        return await anyio.to_thread.run_sync(self._ready.wait, timeout)++    async def _shutdown(self):+        self._stop.set()+        if self._thread is not None:+            await anyio.to_thread.run_sync(self._thread.join, 10)++    @staticmethod+    async def ok(request):+        return aiohttp.web.Response()++    async def stream_handler(self, request):+        # Without the Content-Type, most (all?) browsers will not render+        # partially downloaded content. Note, the response type is+        # StreamResponse not Response.+        resp = StreamResponse(+            status=200, reason='OK', headers={'Content-Type': 'text/html'}+        )++        await resp.prepare(request)+        # Outlast the client read timeout, but return at once on shutdown.+        await asyncio.to_thread(self._stop.wait, 5)+        await resp.write(b'')+        return resp++[email protected]+async def moto_server(server_scheme):+    server = ThreadedMotoServer(port=0)+    try:+        server.start()+        host, port = server.get_host_and_port()+        yield f'http://{host}:{port}'+    finally:+        server.stop()
tests/test_adaptive.py +15 lines · 1 flagged
--- +++ @@ -32,2 +32,10 @@         return self.timestamp_sequences.pop(0)+++def test_register_retry_handler_custom_http_session_uses_asyncio():+    client = mock.Mock(_endpoint=mock.Mock(http_session=object()))++    limiter = adaptive.register_retry_handler(client)++    assert isinstance(limiter, adaptive.AsyncClientRateLimiter) @@ -96,8 +104,13 @@     @pytest.fixture(autouse=True)-    def _setup(self):+    def _setup(self, current_http_backend):         self.timestamp_sequences = [0]         self.clock = FakeClock(self.timestamp_sequences)+        # aiohttp is asyncio-only; the httpx backend also runs on trio.+        if current_http_backend == 'httpx':+            self.bucket_cls = bucket.AnyioTokenBucket+        else:+            self.bucket_cls = bucket.AsyncTokenBucket      def create_token_bucket(self, max_rate=10, min_rate=0.1):-        return bucket.AsyncTokenBucket(+        return self.bucket_cls(             max_rate=max_rate, clock=self.clock, min_rate=min_rate
tests/test_httpsession.py +44 lines · 1 flagged
--- +++ @@ -1 +1,2 @@+import anyio.to_thread import botocore@@ -4,5 +5,8 @@ from aiobotocore.httpsession import AIOHTTPSession+from aiobotocore.httpxsession import HttpxSession+from aiobotocore.session import AioSession  -async def test_cannot_create_client_sessions_outside_context(session):+async def test_cannot_create_client_sessions_outside_context():+    session = AioSession()     s3_client_context = session.create_client(@@ -24,5 +28,19 @@ -async def test_ssl_context_built_off_loop_on_first_request(mocker):-    # Regression for #1469: AIOHTTPSession._build_ssl_context (which calls-    # blocking SSL/file APIs) must run via asyncio.to_thread, not on the loop.+async def test_ssl_context_built_off_loop_on_first_request(+    mocker, current_http_backend+):+    # Regression for #1469: _build_ssl_context (which calls blocking SSL/file+    # APIs) must run off the event loop. aiohttp dispatches it with+    # asyncio.to_thread; httpx, which also runs on trio, uses anyio.+    if current_http_backend == 'httpx':+        run_sync = mocker.patch(+            'aiobotocore.httpxsession.anyio.to_thread.run_sync',+            wraps=anyio.to_thread.run_sync,+        )+        async with HttpxSession():+            # The httpx session builds its SSL context(s) on entry.+            run_sync.assert_called_once()+            assert run_sync.call_args.args[0].__name__ == '_build_ssl_contexts'+        return+     to_thread = mocker.patch(@@ -36,3 +54,3 @@         first_arg = to_thread.call_args.args[0]-        assert first_arg.__name__ == '_build_ssl_context'+        assert first_arg.__name__ == '_build_ssl_contexts' @@ -41 +59,22 @@         to_thread.assert_called_once()+++async def test_ssl_context_built_inline_without_file_io(+    mocker, current_http_backend+):+    if current_http_backend == 'httpx':+        run_sync = mocker.patch(+            'aiobotocore.httpxsession.anyio.to_thread.run_sync',+            wraps=anyio.to_thread.run_sync,+        )+        async with HttpxSession(verify=False):+            run_sync.assert_not_called()+        return++    to_thread = mocker.patch(+        'aiobotocore.httpsession.asyncio.to_thread',+        wraps=__import__('asyncio').to_thread,+    )+    async with AIOHTTPSession(verify=False) as http:+        await http._get_session(proxy_url=None)+        to_thread.assert_not_called()
tests/test_proxy.py +411 lines · 1 flagged
--- +++ @@ -0,0 +1,411 @@+"""End-to-end proxy tests for both http backends.++These stand up a real HTTP ``CONNECT`` proxy (``tiny_proxy``) in front of a real+HTTPS target whose certificate is minted by ``trustme``, then drive the session+through it. They are parametrized over the http backend, so aiohttp's and+httpx's proxy code are both exercised against a real proxy (aiohttp on asyncio,+httpx on asyncio and trio).+"""++from __future__ import annotations++import json+import ssl+import sys++import anyio+import pytest+import tiny_proxy+from anyio.abc import SocketAttribute+from anyio.streams.tls import TLSListener+from botocore.exceptions import (+    EndpointConnectionError,+    HTTPClientError,+    InvalidProxiesConfigError,+    ProxyConnectionError,+)++from aiobotocore import httpxsession+from aiobotocore.httpxsession import HttpxSession+from tests.tls_helpers import (+    prepared_request,+    serve_https_target,+)++pytestmark = pytest.mark.anyio++PROXY_HOST = "localhost"++[email protected]_kwargs({'http_session_cls': HttpxSession})+async def test_httpx_entry_failure_closes_exit_stack(monkeypatch):+    class RecordingExitStack(httpxsession.AsyncExitStack):+        closed = False+        exit_exception = None++        async def __aexit__(self, exc_type, exc, traceback):+            self.closed = True+            self.exit_exception = exc+            return await super().__aexit__(exc_type, exc, traceback)++    exit_stack = RecordingExitStack()+    monkeypatch.setattr(httpxsession, 'AsyncExitStack', lambda: exit_stack)+    session = HttpxSession()++    def fail_build_ssl_contexts(_proxy_urls):+        raise RuntimeError('setup failed')++    monkeypatch.setattr(+        session, '_build_ssl_contexts', fail_build_ssl_contexts+    )++    with pytest.raises(RuntimeError, match='setup failed'):+        await session.__aenter__()++    assert exit_stack.closed+    assert isinstance(exit_stack.exit_exception, RuntimeError)+    assert session._entered is False++[email protected]_kwargs({'http_session_cls': HttpxSession})+def test_httpx_proxy_context_does_not_mutate_endpoint_context():+    endpoint_context = ssl.create_default_context()+    endpoint_context.check_hostname = False+    session = HttpxSession(+        proxies={'https': 'https://localhost:1234'},+        verify=endpoint_context,+    )++    verify, proxy_contexts = session._build_ssl_contexts(+        {'https': 'https://localhost:1234'}+    )++    proxy_context = proxy_contexts['https://localhost:1234']+    assert verify is endpoint_context+    assert proxy_context is not endpoint_context+    assert endpoint_context.check_hostname is False+    assert proxy_context.check_hostname is True+    assert set(proxy_context.get_ca_certs(binary_form=True)) == set(+        endpoint_context.get_ca_certs(binary_form=True)+    )++[email protected]_kwargs({'http_session_cls': HttpxSession})+def test_httpx_proxy_context_with_verification_disabled():+    endpoint_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)+    endpoint_context.check_hostname = False+    endpoint_context.verify_mode = ssl.CERT_NONE+    session = HttpxSession(+        proxies={'https': 'https://localhost:1234'},+        verify=endpoint_context,+    )++    verify, proxy_contexts = session._build_ssl_contexts(+        {'https': 'https://localhost:1234'}+    )++    proxy_context = proxy_contexts['https://localhost:1234']+    assert verify is endpoint_context+    assert proxy_context is not endpoint_context+    assert proxy_context.verify_mode == ssl.CERT_NONE+    assert proxy_context.check_hostname is False++[email protected]_kwargs({'http_session_cls': HttpxSession})+async def test_httpx_proxy_uses_one_client_for_multiple_targets(monkeypatch):+    async with HttpxSession(+        proxies={'https': 'http://127.0.0.1:1234'}+    ) as session:+        first = await session._get_session('https://first.example')+        second = await session._get_session('https://second.example')++        assert first is second+        assert session._session is first++[email protected]_kwargs({'http_session_cls': HttpxSession})+async def test_httpx_concurrent_requests_create_one_client(monkeypatch):+    async with HttpxSession() as session:+        client = session._make_async_client()+        entered = anyio.Event()+        release = anyio.Event()+        calls = 0++        async def enter_async_context(_client):+            nonlocal calls+            calls += 1+            entered.set()+            await release.wait()+            return client++        monkeypatch.setattr(+            session._exit_stack,+            'enter_async_context',+            enter_async_context,+        )+        results = []++        async def get_session(target):+            results.append(await session._get_session(target))++        async with anyio.create_task_group() as task_group:+            task_group.start_soon(get_session, 'https://first.example')+            await entered.wait()+            task_group.start_soon(get_session, 'https://second.example')+            release.set()++        assert results == [client, client]+        assert calls == 1+        await client.aclose()+++async def _serve_http_proxy(*, task_status) -> None:+    handler = tiny_proxy.HttpProxyHandler()+    listener = await anyio.create_tcp_listener(+        local_host="127.0.0.1", local_port=0+    )+    async with listener:+        port = listener.extra(SocketAttribute.local_port)+        task_status.started(port)+        await listener.serve(handler.handle)+++async def _serve_https_proxy(ca, *, client_ca=None, task_status) -> None:+    # A hostname (not an IP) so _setup_proxy_ssl_context enables hostname+    # checking against proxy_ca_bundle.+    proxy_cert = ca.issue_cert(PROXY_HOST)+    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)+    proxy_cert.configure_cert(ssl_context)+    if client_ca is not None:+        ssl_context.verify_mode = ssl.CERT_REQUIRED+        client_ca.configure_trust(ssl_context)++    handler = tiny_proxy.HttpProxyHandler()+    listener = await anyio.create_tcp_listener(+        local_host="127.0.0.1", local_port=0+    )+    async with listener:+        port = listener.extra(SocketAttribute.local_port)+        task_status.started(port)+        await TLSListener(listener, ssl_context).serve(handler.handle)++[email protected]+def proxy_client_cert(ca, tmp_path):+    leaf = ca.issue_cert("[email protected]")+    cert_path = tmp_path / "client.pem"+    key_path = tmp_path / "client.key"+    cert_path.write_bytes(b"".join(b.bytes() for b in leaf.cert_chain_pems))+    key_path.write_bytes(leaf.private_key_pem.bytes())+    return str(cert_path), str(key_path)++[email protected]+def proxy_client_cert_combined(ca, tmp_path):+    leaf = ca.issue_cert("[email protected]")+    pem_path = tmp_path / "client-combined.pem"+    pem_path.write_bytes(+        b"".join(b.bytes() for b in leaf.cert_chain_pems)+        + leaf.private_key_pem.bytes()+    )+    return str(pem_path)++[email protected](params=["string", "tuple"])+def client_cert(request, ca, tmp_path):+    leaf = ca.issue_cert("[email protected]")+    cert_path = tmp_path / "client.pem"+    key_path = tmp_path / "client.key"+    cert_path.write_bytes(b"".join(b.bytes() for b in leaf.cert_chain_pems))+    key_path.write_bytes(leaf.private_key_pem.bytes())+    if request.param == "string":+        pem_path = tmp_path / "client-combined.pem"+        pem_path.write_bytes(cert_path.read_bytes() + key_path.read_bytes())+        return str(pem_path)+    return str(cert_path), str(key_path)+++async def test_https_request_through_http_proxy(+    http_session_cls, ca, ca_bundle+):+    async with anyio.create_task_group() as tg:+        proxy_port = await tg.start(_serve_http_proxy)+        target_port = await tg.start(serve_https_target, ca)++        async with http_session_cls(+            proxies={"https": f"http://127.0.0.1:{proxy_port}"},+            verify=ca_bundle,+        ) as session:+            response = await session.send(prepared_request(target_port))+            assert response.status_code == 200+            assert json.loads(await response.content) == {"ok": True}++        tg.cancel_scope.cancel()+++async def test_https_request_through_https_proxy(+    http_session_cls, current_http_backend, ca, ca_bundle, proxy_client_cert
… 164 more lines (truncated)
aiobotocore/__init__.py +1 lines
--- +++ @@ -2,2 +2,2 @@ -__version__ = '3.8.0'+__version__ = '3.9.0'
aiobotocore/_async_primitives.py +16 lines
--- +++ @@ -0,0 +1,16 @@+from __future__ import annotations++from enum import Enum++from .httpxsession import is_httpx_session_cls+++class AsyncPrimitives(Enum):+    ASYNCIO = 'asyncio'+    ANYIO = 'anyio'+++def infer_async_primitives(http_session_cls) -> AsyncPrimitives:+    if is_httpx_session_cls(http_session_cls):+        return AsyncPrimitives.ANYIO+    return AsyncPrimitives.ASYNCIO
aiobotocore/_endpoint_helpers.py +1 lines
--- +++ @@ -6,6 +6,3 @@ -try:-    import httpx-except ImportError:-    httpx = None+from aiobotocore._httpx import httpx 
aiobotocore/_httpx.py +28 lines
--- +++ @@ -0,0 +1,28 @@+"""Resolution of the optional httpx backend dependency.++aiobotocore's httpx backend prefers httpx2 -- Pydantic's maintained,+API-compatible fork of httpx -- and falls back to the original ``httpx``+package when httpx2 is not installed. The legacy ``httpx`` fallback is+deprecated; ``HttpxSession`` emits a ``DeprecationWarning`` when it is used.+The warning is deferred to backend use (rather than raised here at import)+so aiohttp-only users who merely happen to have ``httpx`` installed are not+warned.++This mirrors the compatibility shim used by authlib's httpx integration. It+is kept free of intra-package imports so that low-level modules (e.g.+``_endpoint_helpers``, which is itself imported by ``httpxsession``) can share+it without creating an import cycle.+"""++try:+    import httpx2 as httpx++    HTTPX_IS_LEGACY = False+except ImportError:+    try:+        import httpx++        HTTPX_IS_LEGACY = True+    except ImportError:+        httpx = None+        HTTPX_IS_LEGACY = False
aiobotocore/_tee.py +89 lines
--- +++ @@ -0,0 +1,89 @@+from __future__ import annotations++from collections import deque+from collections.abc import AsyncIterable, AsyncIterator+from typing import Any, Generic, TypeVar++import anyio++T = TypeVar('T')+++class _TeeState(Generic[T]):+    """Shared source and per-consumer buffers behind a set of tee iterators."""++    def __init__(self, itr: AsyncIterable[T], n: int) -> None:+        self.iterator = itr.__aiter__()+        self.buffers = [deque() for _ in range(n)]+        self.lock = anyio.Lock()+        # Empty until the source is done: holds None on exhaustion, else the+        # exception it raised. Replayed to every consumer, as aioitertools does.+        self.outcome: list[Any] = []++    async def pull(self, buf: deque) -> None:+        """Advance the source once, fanning the value out to every buffer.++        Only the caller whose buffer is still empty needs a value; take the+        lock, then bail if another consumer filled it (or finished the source)+        while we waited.+        """+        async with self.lock:+            if buf or self.outcome:+                return+            try:+                value = await self.iterator.__anext__()+            except StopAsyncIteration:+                self.outcome.append(None)+            except anyio.get_cancelled_exc_class():+                # Cancelling this consumer tears down the source, which is+                # shared. Make the others fail loudly rather than silently+                # yield a truncated stream.+                self.outcome.append(RuntimeError('tee source was cancelled'))+                raise+            except Exception as e:+                self.outcome.append(e)+            else:+                for other in self.buffers:+                    other.append(value)+++class _TeeIterator(AsyncIterator[T]):+    def __init__(self, state: _TeeState[T], buf: deque) -> None:+        self._state = state+        self._buf = buf+        self._done = False++    def __aiter__(self) -> AsyncIterator[T]:+        return self++    async def __anext__(self) -> T:+        if self._done:+            raise StopAsyncIteration++        buf = self._buf+        state = self._state+        while not buf:+            await state.pull(buf)+            if buf:+                break+            # Source is done: replay its outcome, then stay stopped.+            self._done = True+            if state.outcome[0] is not None:+                raise state.outcome[0]+            raise StopAsyncIteration+        return buf.popleft()+++def tee(itr: AsyncIterable[T], n: int = 2) -> tuple[AsyncIterator[T], ...]:+    """Backend-agnostic equivalent of ``aioitertools.tee``.++    ``aioitertools.tee`` fans values out over ``asyncio.Queue`` and+    ``asyncio.gather``, so it only runs on asyncio. This buffers per consumer+    instead, taking the lock only to pull from the source, so it runs on any+    anyio backend.+    """+    if n <= 0:+        raise ValueError('n must be >= 1')++    state: _TeeState[T] = _TeeState(itr, n)+    return tuple(_TeeIterator(state, buf) for buf in state.buffers)
aiobotocore/args.py +8 lines
--- +++ @@ -79,3 +79,10 @@ -        new_config = AioConfig(connector_args, **config_kwargs)+        new_config = AioConfig(+            connector_args,+            http_session_cls=http_session_cls,+            warm_up_loader_caches=getattr(+                client_config, 'warm_up_loader_caches', False+            ),+            **config_kwargs,+        )         endpoint_creator = AioEndpointCreator(event_emitter)
aiobotocore/client.py +30 lines
--- +++ @@ -20,10 +20,19 @@ from . import waiter+from ._async_primitives import AsyncPrimitives, infer_async_primitives from .args import AioClientArgsCreator from .context import with_current_context-from .credentials import AioRefreshableCredentials+from .credentials import (+    AioRefreshableCredentials,+    AnyioRefreshableCredentials,+) from .discovery import AioEndpointDiscoveryHandler, AioEndpointDiscoveryManager from .httpchecksum import apply_request_checksum-from .paginate import AioPaginator+from .httpxsession import HttpxSession+from .paginate import AioPaginator, AnyioPaginator from .retries import adaptive, standard-from .utils import AioS3ExpressIdentityResolver, AioS3RegionRedirectorv2+from .utils import (+    AioS3ExpressIdentityResolver,+    AioS3RegionRedirectorv2,+    AnyioS3ExpressIdentityResolver,+) @@ -252,5 +261,9 @@             return-        AioS3ExpressIdentityResolver(-            client, AioRefreshableCredentials-        ).register()+        if isinstance(client._endpoint.http_session, HttpxSession):+            resolver_cls = AnyioS3ExpressIdentityResolver+            credential_cls = AnyioRefreshableCredentials+        else:+            resolver_cls = AioS3ExpressIdentityResolver+            credential_cls = AioRefreshableCredentials+        resolver_cls(client, credential_cls).register() @@ -586,4 +599,13 @@             # attach a docstring to the method.+            # aiohttp is asyncio-only; the httpx backend also runs on trio.+            async_primitives = infer_async_primitives(+                type(self._endpoint.http_session)+            )+            if async_primitives is AsyncPrimitives.ANYIO:+                paginator_cls = AnyioPaginator+            else:+                paginator_cls = AioPaginator+             def paginate(self, **kwargs):-                return AioPaginator.paginate(self, **kwargs)+                return paginator_cls.paginate(self, **kwargs) @@ -611,3 +633,3 @@             documented_paginator_cls = type(-                paginator_class_name, (AioPaginator,), {'paginate': paginate}+                paginator_class_name, (paginator_cls,), {'paginate': paginate}             )
aiobotocore/config.py +31 lines
--- +++ @@ -4,3 +4,3 @@ import sys-from typing import TypedDict+from typing import TypedDict, cast @@ -14,3 +14,3 @@ from .httpsession import AIOHTTPSession-from .httpxsession import HttpxSession+from .httpxsession import HttpxSession, is_httpx_session_cls @@ -39,2 +39,3 @@ _HttpSessionType = AIOHTTPSession | HttpxSession+_OPTION_DEFAULT = object() @@ -44,14 +45,31 @@         self,-        connector_args: _ConnectorArgs | None = None,-        http_session_cls: type[_HttpSessionType] = DEFAULT_HTTP_SESSION_CLS,-        warm_up_loader_caches: bool = False,+        connector_args: _ConnectorArgs | None | object = _OPTION_DEFAULT,+        http_session_cls: type[_HttpSessionType] | object = _OPTION_DEFAULT,+        warm_up_loader_caches: bool | object = _OPTION_DEFAULT,         **kwargs,     ):+        aio_options = {}+        if connector_args is not _OPTION_DEFAULT:+            aio_options['connector_args'] = connector_args+        else:+            connector_args = None+        if http_session_cls is not _OPTION_DEFAULT:+            aio_options['http_session_cls'] = http_session_cls+        else:+            http_session_cls = DEFAULT_HTTP_SESSION_CLS+        if warm_up_loader_caches is not _OPTION_DEFAULT:+            aio_options['warm_up_loader_caches'] = warm_up_loader_caches+        else:+            warm_up_loader_caches = False+         super().__init__(**kwargs)+        self._user_provided_options.update(aio_options)          self.connector_args: _ConnectorArgs = (-            copy.copy(connector_args) if connector_args else {}+            copy.copy(cast(_ConnectorArgs, connector_args))+            if connector_args+            else {}         )-        self.http_session_cls: type[_HttpSessionType] = http_session_cls-        self.warm_up_loader_caches: bool = warm_up_loader_caches+        self.http_session_cls = cast(type[_HttpSessionType], http_session_cls)+        self.warm_up_loader_caches = cast(bool, warm_up_loader_caches)         self._validate_connector_args(@@ -69,3 +87,3 @@         config_options.update(other_config._user_provided_options)-        return AioConfig(self.connector_args, **config_options)+        return AioConfig(**config_options) @@ -79,3 +97,3 @@             if k == 'use_dns_cache':-                if http_session_cls is HttpxSession:+                if is_httpx_session_cls(http_session_cls):                     raise ParamValidationError(@@ -98,3 +116,3 @@             elif k == 'force_close':-                if http_session_cls is HttpxSession:+                if is_httpx_session_cls(http_session_cls):                     raise ParamValidationError(@@ -113,3 +131,3 @@             elif k == "resolver":-                if http_session_cls is HttpxSession:+                if is_httpx_session_cls(http_session_cls):                     raise ParamValidationError(@@ -122,3 +140,3 @@             elif k == "socket_factory":-                if http_session_cls is HttpxSession:+                if is_httpx_session_cls(http_session_cls):                     raise ParamValidationError(
aiobotocore/credentials.py +205 lines
--- +++ @@ -67,2 +67,3 @@ +from aiobotocore._async_primitives import AsyncPrimitives from aiobotocore._helpers import resolve_awaitable@@ -73,2 +74,4 @@     AioInstanceMetadataFetcher,+    AnyioContainerMetadataFetcher,+    AnyioInstanceMetadataFetcher,     create_nested_client,@@ -79,3 +82,9 @@ -def create_credential_resolver(session, cache=None, region_name=None):+def create_credential_resolver(+    session,+    cache=None,+    region_name=None,+    *,+    async_primitives=AsyncPrimitives.ASYNCIO,+):     """Create a default credential resolver.@@ -106,6 +115,19 @@ -    env_provider = AioEnvProvider()-    container_provider = AioContainerProvider()-    instance_metadata_provider = AioInstanceMetadataProvider(-        iam_role_fetcher=AioInstanceMetadataFetcher(+    if async_primitives is AsyncPrimitives.ANYIO:+        env_provider = AnyioEnvProvider()+        container_provider = AnyioContainerProvider()+        iam_role_fetcher_cls = AnyioInstanceMetadataFetcher+        instance_metadata_provider_cls = AnyioInstanceMetadataProvider+        profile_provider_builder_cls = AnyioProfileProviderBuilder+        assume_role_provider_cls = AnyioAssumeRoleProvider+    else:+        env_provider = AioEnvProvider()+        container_provider = AioContainerProvider()+        iam_role_fetcher_cls = AioInstanceMetadataFetcher+        instance_metadata_provider_cls = AioInstanceMetadataProvider+        profile_provider_builder_cls = AioProfileProviderBuilder+        assume_role_provider_cls = AioAssumeRoleProvider++    instance_metadata_provider = instance_metadata_provider_cls(+        iam_role_fetcher=iam_role_fetcher_cls(             timeout=metadata_timeout,@@ -117,6 +139,6 @@ -    profile_provider_builder = AioProfileProviderBuilder(+    profile_provider_builder = profile_provider_builder_cls(         session, cache=cache, region_name=region_name     )-    assume_role_provider = AioAssumeRoleProvider(+    assume_role_provider = assume_role_provider_cls(         load_config=lambda: session.full_config,@@ -228,4 +250,49 @@ +class AnyioProfileProviderBuilder(AioProfileProviderBuilder):+    def _create_process_provider(self, profile_name):+        return AnyioProcessProvider(+            profile_name=profile_name,+            load_config=lambda: self._session.full_config,+        )++    def _create_web_identity_provider(self, profile_name, disable_env_vars):+        return AnyioAssumeRoleWithWebIdentityProvider(+            load_config=lambda: self._session.full_config,+            client_creator=_get_client_creator(+                self._session, self._region_name+            ),+            cache=self._cache,+            profile_name=profile_name,+            disable_env_vars=disable_env_vars,+        )++    def _create_sso_provider(self, profile_name):+        from aiobotocore.tokens import AnyioSSOTokenProvider++        return AnyioSSOProvider(+            load_config=lambda: self._session.full_config,+            client_creator=self._session.create_client,+            profile_name=profile_name,+            cache=self._cache,+            token_cache=self._sso_token_cache,+            token_provider=AnyioSSOTokenProvider(+                self._session,+                cache=self._sso_token_cache,+                profile_name=profile_name,+            ),+        )++    def _create_login_provider(self, profile_name):+        return AnyioLoginProvider(+            load_config=lambda: self._session.full_config,+            client_creator=self._session.create_client,+            profile_name=profile_name,+            token_cache=self._login_token_cache,+        )++ async def get_credentials(session):-    resolver = create_credential_resolver(session)+    resolver = create_credential_resolver(+        session, async_primitives=session._async_primitives+    )     return await resolver.load_credentials()@@ -293,5 +360,8 @@ class AioRefreshableCredentials(RefreshableCredentials):+    def _create_lock(self):+        return asyncio.Lock()+     def __init__(self, *args, **kwargs):         super().__init__(*args, **kwargs)-        self._refresh_lock = asyncio.Lock()+        self._refresh_lock = self._create_lock() @@ -441,5 +511,18 @@         self._time_fetcher = time_fetcher-        self._refresh_lock = asyncio.Lock()+        self._refresh_lock = self._create_lock()         self.method = method         self._frozen_credentials = None+++class AnyioRefreshableCredentials(AioRefreshableCredentials):+    def _create_lock(self):+        import anyio++        return anyio.Lock()+++class AnyioDeferredRefreshableCredentials(+    AioDeferredRefreshableCredentials, AnyioRefreshableCredentials+):+    pass @@ -562,2 +645,4 @@ class AioProcessProvider(ProcessProvider):+    _refreshable_credentials_cls = AioRefreshableCredentials+     def __init__(self, *args, popen=asyncio.create_subprocess_exec, **kwargs):@@ -574,3 +659,3 @@         if creds_dict.get('expiry_time') is not None:-            return AioRefreshableCredentials.create_from_metadata(+            return self._refreshable_credentials_cls.create_from_metadata(                 creds_dict,@@ -605,3 +690,3 @@             # worker thread so the loop stays unblocked. (#1415)-            stdout, stderr, returncode = await asyncio.to_thread(+            stdout, stderr, returncode = await self._run_in_thread(                 _run_credential_process_sync, process_list@@ -636,4 +721,51 @@ +    async def _run_in_thread(self, func, *args):+        return await asyncio.to_thread(func, *args)+++class _AnyioSubprocess:+    """Adapts an anyio ``CompletedProcess`` to the ``asyncio`` subprocess+    interface (awaitable ``communicate()`` plus ``returncode``) that+    ``AioProcessProvider._retrieve_credentials_using`` expects."""++    def __init__(self, completed):+        self._completed = completed++    @property+    def returncode(self):+        return self._completed.returncode++    async def communicate(self):+        return self._completed.stdout, self._completed.stderr+++async def _anyio_create_subprocess_exec(+    program, *args, stdout=None, stderr=None+):+    # anyio is a hard dependency of httpx, so it is importable whenever the+    # httpx (trio-capable) backend is in use. Unlike asyncio subprocesses, it+    # works on trio, whose event loop has no asyncio subprocess transport.+    import anyio++    completed = await anyio.run_process(+        [program, *args], stdout=stdout, stderr=stderr, check=False+    )+    return _AnyioSubprocess(completed)+++class AnyioProcessProvider(AioProcessProvider):+    _refreshable_credentials_cls = AnyioRefreshableCredentials++    def __init__(self, *args, popen=_anyio_create_subprocess_exec, **kwargs):+        super().__init__(*args, popen=popen, **kwargs)++    async def _run_in_thread(self, func, *args):+        import anyio.to_thread++        return await anyio.to_thread.run_sync(func, *args)+  class AioInstanceMetadataProvider(InstanceMetadataProvider):+    _refreshable_credentials_cls = AioRefreshableCredentials+     async def load(self):@@ -648,3 +780,3 @@ -        creds = AioRefreshableCredentials.create_from_metadata(+        creds = self._refreshable_credentials_cls.create_from_metadata(             metadata,@@ -656,3 +788,9 @@ +class AnyioInstanceMetadataProvider(AioInstanceMetadataProvider):+    _refreshable_credentials_cls = AnyioRefreshableCredentials++ class AioEnvProvider(EnvProvider):+    _refreshable_credentials_cls = AioRefreshableCredentials+     async def load(self):@@ -669,3 +807,3 @@                 expiry_time = parse(expiry_time)-                return AioRefreshableCredentials(+                return self._refreshable_credentials_cls(                     credentials['access_key'],@@ -688,2 +826,6 @@             return None+++class AnyioEnvProvider(AioEnvProvider):+    _refreshable_credentials_cls = AnyioRefreshableCredentials @@ -795,2 +937,4 @@ class AioAssumeRoleProvider(AssumeRoleProvider):+    _deferred_credentials_cls = AioDeferredRefreshableCredentials+     async def load(self):@@ -847,3 +991,3 @@         # strictly needed.-        return AioDeferredRefreshableCredentials(+        return self._deferred_credentials_cls(             method=self.METHOD,@@ -932,3 +1076,9 @@ +class AnyioAssumeRoleProvider(AioAssumeRoleProvider):+    _deferred_credentials_cls = AnyioDeferredRefreshableCredentials++ class AioAssumeRoleWithWebIdentityProvider(AssumeRoleWithWebIdentityProvider):+    _deferred_credentials_cls = AioDeferredRefreshableCredentials+     async def load(self):
… 83 more lines (truncated)
aiobotocore/endpoint.py +26 lines
--- +++ @@ -16,2 +16,7 @@ +from aiobotocore._async_primitives import (+    AsyncPrimitives,+    infer_async_primitives,+)+from aiobotocore._httpx import httpx from aiobotocore.httpchecksum import handle_checksum_body@@ -20,7 +25,2 @@ from aiobotocore.response import AioHttpxStreamingBody, AioStreamingBody--try:-    import httpx-except ImportError:-    httpx = None @@ -300,4 +300,7 @@             )-            await asyncio.sleep(handler_response)+            await self._sleep(handler_response)             return True++    async def _sleep(self, sleep_amount):+        await asyncio.sleep(sleep_amount) @@ -305,2 +308,13 @@         return await self.http_session.send(request)+++class AnyioEndpoint(AioEndpoint):+    """Endpoint for the httpx backend, which also runs on trio."""++    async def _sleep(self, sleep_amount):+        # anyio is a hard dependency of httpx, so it is importable whenever+        # the httpx backend is in use.+        import anyio++        await anyio.sleep(sleep_amount) @@ -345,3 +359,8 @@ -        return AioEndpoint(+        if infer_async_primitives(http_session_cls) is AsyncPrimitives.ANYIO:+            endpoint_cls = AnyioEndpoint+        else:+            endpoint_cls = AioEndpoint++        return endpoint_cls(             endpoint_url,
aiobotocore/httpchecksum.py +1 lines
--- +++ @@ -14,8 +14,4 @@ from aiobotocore._helpers import resolve_awaitable+from aiobotocore._httpx import httpx from aiobotocore.response import AioHttpxStreamingBody, AioStreamingBody--try:-    import httpx-except ImportError:-    httpx = None 
aiobotocore/paginate.py +22 lines
--- +++ @@ -110,4 +110,7 @@ +    def _tee(self, n):+        return aioitertools.tee(self, n)+     def result_key_iters(self):-        teed_results = aioitertools.tee(self, len(self.result_keys))+        teed_results = self._tee(len(self.result_keys))         return [@@ -167,4 +170,22 @@ +class AnyioPageIterator(AioPageIterator):+    """Page iterator for the httpx backend, which also runs on trio."""++    def _tee(self, n):+        # aioitertools.tee is built on asyncio.Queue. anyio is a hard+        # dependency of httpx, so ._tee is importable whenever the httpx+        # backend is in use.+        from ._tee import tee++        return tee(self, n)++ class AioPaginator(Paginator):     PAGE_ITERATOR_CLS = AioPageIterator+++class AnyioPaginator(AioPaginator):+    """Paginator for the httpx backend, which also runs on trio."""++    PAGE_ITERATOR_CLS = AnyioPageIterator 
aiobotocore/response.py +32 lines
--- +++ @@ -12,2 +12,19 @@ from aiobotocore import parsers+from aiobotocore._httpx import httpx++if httpx is not None:+    _HTTPX_READ_TIMEOUTS: tuple[type[BaseException], ...] = (+        httpx.ReadTimeout,+    )+    # NetworkError covers read/write/connect/close failures; RemoteProtocolError+    # is a server disconnecting mid-body, which aiohttp reports as a+    # ClientConnectionError (ServerDisconnectedError).+    _HTTPX_STREAM_ERRORS: tuple[type[BaseException], ...] = (+        httpx.NetworkError,+        httpx.RemoteProtocolError,+    )+else:+    # Never matches, so the aiohttp backend is unaffected.+    _HTTPX_READ_TIMEOUTS = ()+    _HTTPX_STREAM_ERRORS = () @@ -202,2 +219,8 @@                 self._stream_exhausted = True+            except _HTTPX_READ_TIMEOUTS as e:+                raise AioReadTimeoutError(+                    endpoint_url=self._raw_stream.url, error=e+                )+            except _HTTPX_STREAM_ERRORS as e:+                raise ResponseStreamingError(error=e) @@ -214,4 +237,11 @@             self._buffer = b''-            async for chunk in self._stream_iter:-                chunks.append(chunk)+            try:+                async for chunk in self._stream_iter:+                    chunks.append(chunk)+            except _HTTPX_READ_TIMEOUTS as e:+                raise AioReadTimeoutError(+                    endpoint_url=self._raw_stream.url, error=e+                )+            except _HTTPX_STREAM_ERRORS as e:+                raise ResponseStreamingError(error=e)             self._stream_exhausted = True
boto3 pypi
1.43.78 13h ago nominal
critical-tier BURSTINSTALL-EXEC
latest 1.43.78 versions 2102 maintainers 1 critical-tier (snapshotted)
1.43.67
1.43.68
1.43.69
1.43.70
1.43.71
1.43.72
1.43.73
1.43.74
1.43.75
1.43.76
1.43.77
1.43.78
BURST
2 releases in 36m: 1.2.0, 1.2.1
info · registry-verified · 2015-10-23 · 10y ago
INSTALL-EXEC
setup.py in sdist uses subprocess/exec (runs at pip install)
warn · snapshot-derived
release diff 1.43.77 → 1.43.78
+0 added · -0 removed · ~6 modified
boto3/__init__.py +1 lines
--- +++ @@ -20,3 +20,3 @@ __author__ = 'Amazon Web Services'-__version__ = '1.43.77'+__version__ = '1.43.78' 
setup.cfg +1 lines
--- +++ @@ -5,3 +5,3 @@ requires_dist = -	botocore>=1.43.77,<1.44.0+	botocore>=1.43.78,<1.44.0 	jmespath>=0.7.1,<2.0.0
setup.py +1 lines
--- +++ @@ -16,3 +16,3 @@ requires = [-    'botocore>=1.43.77,<1.44.0',+    'botocore>=1.43.78,<1.44.0',     'jmespath>=0.7.1,<2.0.0',
botocore pypi
1.43.78 13h ago nominal
critical-tier BURST ×2
latest 1.43.78 versions 2500 maintainers 1 critical-tier (snapshotted)
1.43.67
1.43.68
1.43.69
1.43.70
1.43.71
1.43.72
1.43.73
1.43.74
1.43.75
1.43.76
1.43.77
1.43.78
BURST
2 releases in 14m: 0.13.0, 0.13.1
info · registry-verified · 2013-07-18 · 13y ago
BURST
2 releases in 4m: 0.15.0, 0.15.1
info · registry-verified · 2013-08-23 · 13y ago
release diff 1.43.77 → 1.43.78
artifact too large or unavailable
h11 pypi
0.16.0 1y ago nominal
BURSTINSTALL-EXEC
latest 0.16.0 versions 14 maintainers 1
0.6.0
0.7.0
0.8.0
0.8.1
0.9.0
0.10.0
0.11.0
0.12.0
0.13.0
0.14.0
0.15.0
0.16.0
BURST
2 releases in 28m: 0.15.0, 0.16.0
info · registry-verified · 2025-04-24 · 1y ago
INSTALL-EXEC
setup.py in sdist uses subprocess/exec (runs at pip install)
warn · snapshot-derived
release diff 0.15.0 → 0.16.0
+0 added · -0 removed · ~6 modified
h11/_readers.py +13 lines
--- +++ @@ -150,6 +150,5 @@         self._bytes_in_chunk = 0-        # After reading a chunk, we have to throw away the trailing \r\n; if-        # this is >0 then we discard that many bytes before resuming regular-        # de-chunkification.-        self._bytes_to_discard = 0+        # After reading a chunk, we have to throw away the trailing \r\n.+        # This tracks the bytes that we need to match and throw away.+        self._bytes_to_discard = b""         self._reading_trailer = False@@ -162,11 +161,15 @@             return EndOfMessage(headers=list(_decode_header_lines(lines)))-        if self._bytes_to_discard > 0:-            data = buf.maybe_extract_at_most(self._bytes_to_discard)+        if self._bytes_to_discard:+            data = buf.maybe_extract_at_most(len(self._bytes_to_discard))             if data is None:                 return None-            self._bytes_to_discard -= len(data)-            if self._bytes_to_discard > 0:+            if data != self._bytes_to_discard[: len(data)]:+                raise LocalProtocolError(+                    f"malformed chunk footer: {data!r} (expected {self._bytes_to_discard!r})"+                )+            self._bytes_to_discard = self._bytes_to_discard[len(data) :]+            if self._bytes_to_discard:                 return None             # else, fall through and read some more-        assert self._bytes_to_discard == 0+        assert self._bytes_to_discard == b""         if self._bytes_in_chunk == 0:@@ -196,3 +199,3 @@         if self._bytes_in_chunk == 0:-            self._bytes_to_discard = 2+            self._bytes_to_discard = b"\r\n"             chunk_end = True
h11/_version.py +1 lines
--- +++ @@ -15,2 +15,2 @@ -__version__ = "0.15.0"+__version__ = "0.16.0"
h11/tests/test_io.py +38 lines
--- +++ @@ -354,3 +354,9 @@     buf = makebuf(data)-    assert _run_reader(thunk(), buf, do_eof) == expected+    try:+        assert _run_reader(thunk(), buf, do_eof) == expected+    except LocalProtocolError:+        if LocalProtocolError in expected:+            pass+        else:+            raise @@ -361,7 +367,13 @@     events = []-    for i in range(len(data)):-        events += _run_reader(reader, buf, False)-        buf += data[i : i + 1]-    events += _run_reader(reader, buf, do_eof)-    assert normalize_data_events(events) == expected+    try:+        for i in range(len(data)):+            events += _run_reader(reader, buf, False)+            buf += data[i : i + 1]+        events += _run_reader(reader, buf, do_eof)+        assert normalize_data_events(events) == expected+    except LocalProtocolError:+        if LocalProtocolError in expected:+            pass+        else:+            raise @@ -426,10 +438,8 @@     # refuses arbitrarily long chunk integers-    with pytest.raises(LocalProtocolError):-        # Technically this is legal HTTP/1.1, but we refuse to process chunk-        # sizes that don't fit into 20 characters of hex-        t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [Data(data=b"xxx")])+    # Technically this is legal HTTP/1.1, but we refuse to process chunk+    # sizes that don't fit into 20 characters of hex+    t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [LocalProtocolError])      # refuses garbage in the chunk count-    with pytest.raises(LocalProtocolError):-        t_body_reader(ChunkedReader, b"10\x00\r\nxxx", None)+    t_body_reader(ChunkedReader, b"10\x00\r\nxxx", [LocalProtocolError]) @@ -447,5 +457,18 @@         ChunkedReader,-        b"5   	 \r\n01234\r\n" + b"0\r\n\r\n",+        b"5   \t \r\n01234\r\n" + b"0\r\n\r\n",         [Data(data=b"01234"), EndOfMessage()],     )++    # Chunked encoding with bad chunk termination characters are refused. Originally we+    # simply dropped the 2 bytes after a chunk, instead of validating that the bytes+    # were \r\n -- so we would successfully decode the data below as b"xxxa". And+    # apparently there are other HTTP processors that ignore the chunk length and just+    # keep reading until they see \r\n, so they would decode it as b"xxx__1a". Any time+    # two HTTP processors accept the same input but interpret it differently, there's a+    # possibility of request smuggling shenanigans. So we now reject this.+    t_body_reader(ChunkedReader, b"3\r\nxxx__1a\r\n", [LocalProtocolError])++    # Confirm we check both bytes individually+    t_body_reader(ChunkedReader, b"3\r\nxxx\r_1a\r\n", [LocalProtocolError])+    t_body_reader(ChunkedReader, b"3\r\nxxx_\n1a\r\n", [LocalProtocolError]) @@ -473,4 +496,4 @@     w = ContentLengthWriter(5)-    dowrite(w, Data(data=b"123")) == b"123"-    dowrite(w, Data(data=b"45")) == b"45"+    assert dowrite(w, Data(data=b"123")) == b"123"+    assert dowrite(w, Data(data=b"45")) == b"45"     with pytest.raises(LocalProtocolError):
idna pypi
3.19 4d ago nominal
critical-tier BURST
latest 3.19 versions 42 maintainers 1 critical-tier (snapshotted)
3.8
3.9
3.10
3.11
3.12
3.13
3.14
3.15
3.16
3.17
3.18
3.19
BURST
2 releases in 23m: 0.7, 0.8
info · registry-verified · 2014-07-10 · 12y ago
release diff 3.18 → 3.19
+6 added · -0 removed · ~19 modified
new files touching dangerous APIs: tests/fuzz_idna_api.py, tests/fuzz_idna_codec.py
tests/fuzz_idna_api.py +122 lines · 1 flagged
--- +++ @@ -0,0 +1,122 @@+#!/usr/bin/env python3+"""OSS-Fuzz target for the whole-domain and per-label API.++Each input selects an operation and flag combination from its leading bytes+and feeds the remainder as the domain or label. The harness asserts the same+invariants as ``tests/test_idna_properties.py``: only :class:`idna.IDNAError`+may escape, successful output is bounded ASCII, encoding then decoding then+encoding again is stable, and UTS #46 remapping is NFC and idempotent.++OSS-Fuzz builds every ``fuzz_*.py`` it finds in the checkout, so this file+needs no registration there. To run it locally::++    pip install atheris .+    python tests/fuzz_idna_api.py -max_total_time=60++Any libFuzzer flag is accepted; a crash writes a ``crash-*`` file which can be+passed back as an argument to reproduce. ``tests/test_idna_fuzz_targets.py``+smoke-tests this harness in the ordinary test suite without atheris.+"""++import sys+import unicodedata++import atheris  # ty: ignore[unresolved-import]++with atheris.instrument_imports():+    import idna++MAX_INPUT = 1100  # just past idna's 1024-character input cap+STD3_ASCII = frozenset("abcdefghijklmnopqrstuvwxyz0123456789-.")+++def _only_idnaerror(fn, *args, **kwargs):+    try:+        return fn(*args, **kwargs)+    except idna.IDNAError:+        return None+++def fuzz_encode(fdp):+    strict, uts46, std3 = fdp.ConsumeBool(), fdp.ConsumeBool(), fdp.ConsumeBool()+    s = fdp.ConsumeUnicode(MAX_INPUT)+    encoded = _only_idnaerror(idna.encode, s, strict=strict, uts46=uts46, std3_rules=std3)+    if encoded is None:+        return+    encoded.decode("ascii")+    assert len(encoded) <= 254, encoded+    for label in encoded.rstrip(b".").split(b"."):+        assert 0 < len(label) <= 63, encoded+    # Anything encode() produced must decode, and re-encode to itself+    # (up to ASCII case, since ulabel() lowercases while alabel() does not).+    decoded = idna.decode(encoded)+    assert idna.encode(decoded) == encoded.lower(), (encoded, decoded)+    assert idna.decode(encoded, display=True) == decoded+++def fuzz_decode(fdp):+    strict, uts46, std3, display = fdp.ConsumeBool(), fdp.ConsumeBool(), fdp.ConsumeBool(), fdp.ConsumeBool()+    data = fdp.ConsumeUnicode(MAX_INPUT) if fdp.ConsumeBool() else fdp.ConsumeBytes(MAX_INPUT)+    decoded = _only_idnaerror(idna.decode, data, strict=strict, uts46=uts46, std3_rules=std3, display=display)+    if decoded is None or not strict or uts46 or display:+        return+    # RFC 5891 §5.3: an A-label that decodes must re-encode to itself, so+    # under strict non-UTS46 processing any ASCII input that decodes is (up+    # to case) its own encoding. decode() does not enforce the 63-octet+    # label limit (nor does UTS #46 ToUnicode) but encode() does, so skip+    # overlong labels.+    if isinstance(data, str):+        if not data.isascii():+            return+        data = data.encode("ascii")+    if all(len(label) <= 63 for label in data.split(b".")):+        assert idna.encode(decoded, strict=True) == data.lower(), (data, decoded)+++def fuzz_uts46_remap(fdp):+    std3 = fdp.ConsumeBool()+    s = fdp.ConsumeUnicode(MAX_INPUT)+    out = _only_idnaerror(idna.uts46_remap, s, std3_rules=std3)+    if out is None:+        return+    assert unicodedata.is_normalized("NFC", out), out+    assert idna.uts46_remap(out, std3_rules=std3) == out, out+    if std3:  # UTS #46 §4.1 UseSTD3ASCIIRules+        assert all(c in STD3_ASCII for c in out if c.isascii()), out+++def fuzz_labels(fdp):+    label = fdp.ConsumeUnicode(MAX_INPUT)+    for fn in (+        idna.alabel,+        idna.ulabel,+        idna.check_label,+        idna.check_bidi,+        idna.check_hyphen_ok,+        idna.check_initial_combiner,+        idna.check_nfc,+        idna.valid_label_length,+    ):+        _only_idnaerror(fn, label)+    _only_idnaerror(idna.ulabel, label.encode("utf-8", "surrogatepass"))+    _only_idnaerror(idna.check_label, label.encode("utf-8", "surrogatepass"))+    encoded = _only_idnaerror(idna.alabel, label)+    if encoded is not None:+        assert idna.alabel(idna.ulabel(encoded)) == encoded.lower(), (label, encoded)+++OPERATIONS = (fuzz_encode, fuzz_decode, fuzz_uts46_remap, fuzz_labels)+++def TestOneInput(data):+    fdp = atheris.FuzzedDataProvider(data)+    OPERATIONS[fdp.ConsumeIntInRange(0, len(OPERATIONS) - 1)](fdp)+++def main():+    atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)+    atheris.Fuzz()+++if __name__ == "__main__":+    main()
tests/fuzz_idna_codec.py +113 lines · 1 flagged
--- +++ @@ -0,0 +1,113 @@+#!/usr/bin/env python3+"""OSS-Fuzz target for the ``idna2008`` codec.++Exercises the one-shot codec and, more importantly, the incremental+encoder/decoder: the input is fed in fuzzer-chosen chunk sizes and the+concatenated result must equal the one-shot result (or both must raise+:class:`idna.IDNAError`). The buffering logic in+:mod:`idna.codec` is stateful across calls, which is exactly the kind of+code a fuzzer is good at breaking.++OSS-Fuzz builds every ``fuzz_*.py`` it finds in the checkout, so this file+needs no registration there. To run it locally::++    pip install atheris .+    python tests/fuzz_idna_codec.py -max_total_time=60++Any libFuzzer flag is accepted; a crash writes a ``crash-*`` file which can be+passed back as an argument to reproduce. ``tests/test_idna_fuzz_targets.py``+smoke-tests this harness in the ordinary test suite without atheris.+"""++import codecs+import sys++import atheris  # ty: ignore[unresolved-import]++with atheris.instrument_imports():+    import idna+    import idna.codec  # registers the "idna2008" codec++MAX_INPUT = 1100  # just past idna's 1024-character input cap+MAX_CHUNKS = 8+++def _outcome(fn, *args):+    try:+        return fn(*args), None+    except idna.IDNAError as err:+        return None, err+++def _chunks(fdp, data):+    cuts = sorted(fdp.ConsumeIntInRange(0, len(data)) for _ in range(fdp.ConsumeIntInRange(0, MAX_CHUNKS)))+    points = [0, *cuts, len(data)]+    return [data[i:j] for i, j in zip(points, points[1:])]+++def fuzz_encoder(fdp):+    s = fdp.ConsumeUnicode(MAX_INPUT)+    if not s:+        return  # the codec maps "" to b"" by design; core raises "Empty domain"+    one_shot = _outcome(idna.encode, s)+    assert _outcome(s.encode, "idna2008") == one_shot or one_shot[1] is not None++    chunks = _chunks(fdp, s)+    encoder = codecs.getincrementalencoder("idna2008")()++    def incremental():+        out = b"".join(encoder.encode(chunk) for chunk in chunks)+        return out + encoder.encode("", final=True)++    result = _outcome(incremental)+    assert (result[1] is None) == (one_shot[1] is None), (s, chunks, one_shot, result)+    assert result[0] == one_shot[0], (s, chunks, one_shot, result)+++def fuzz_decoder(fdp):+    b = fdp.ConsumeBytes(MAX_INPUT)+    if not b:+        return+    one_shot = _outcome(idna.decode, b)+    assert _outcome(b.decode, "idna2008") == one_shot or one_shot[1] is not None++    chunks = _chunks(fdp, b)+    decoder = codecs.getincrementaldecoder("idna2008")()++    def incremental():+        out = "".join(decoder.decode(chunk) for chunk in chunks)+        return out + decoder.decode(b"", final=True)++    result = _outcome(incremental)+    assert (result[1] is None) == (one_shot[1] is None), (b, chunks, one_shot, result)+    assert result[0] == one_shot[0], (b, chunks, one_shot, result)+++def fuzz_stream(fdp):+    # StreamWriter/StreamReader wrap the one-shot codec; make sure they only+    # ever raise IDNAError.+    import io++    if fdp.ConsumeBool():+        writer = codecs.getwriter("idna2008")(io.BytesIO())+        _outcome(writer.write, fdp.ConsumeUnicode(MAX_INPUT))+    else:+        reader = codecs.getreader("idna2008")(io.BytesIO(fdp.ConsumeBytes(MAX_INPUT)))+        _outcome(reader.read)+++OPERATIONS = (fuzz_encoder, fuzz_decoder, fuzz_stream)+++def TestOneInput(data):+    fdp = atheris.FuzzedDataProvider(data)+    OPERATIONS[fdp.ConsumeIntInRange(0, len(OPERATIONS) - 1)](fdp)+++def main():+    atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)+    atheris.Fuzz()+++if __name__ == "__main__":+    main()
idna/__init__.py +2 lines
--- +++ @@ -20,2 +20,3 @@ )+from .idnadata import __version__ as unicode_version from .intranges import intranges_contain@@ -25,2 +26,3 @@     "__version__",+    "unicode_version",     "IDNABidiError",
idna/cli.py +9 lines
--- +++ @@ -5,11 +5,15 @@ +from __future__ import annotations+ import argparse import sys-from collections.abc import Iterable from itertools import chain-from typing import IO, Optional+from typing import IO, TYPE_CHECKING -from . import IDNAError, decode, encode+from . import IDNAError, decode, encode, unicode_version from .core import _alabel_prefix, _unicode_dots_re from .package_data import __version__++if TYPE_CHECKING:+    from collections.abc import Iterable @@ -62,3 +66,3 @@         action="version",-        version=f"idna {__version__}",+        version=f"idna {__version__} (Unicode {unicode_version})",     )@@ -93,3 +97,3 @@ -def main(argv: Optional[list[str]] = None) -> int:+def main(argv: list[str] | None = None) -> int:     """Entry point for ``python -m idna``.
idna/codec.py +12 lines
--- +++ @@ -1,3 +1,5 @@+from __future__ import annotations+ import codecs-from typing import Any, Optional+from typing import Any @@ -19,3 +21,3 @@         if errors != "strict":-            raise IDNAError(f'Unsupported error handling "{errors}"')+            raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") @@ -28,3 +30,3 @@         if errors != "strict":-            raise IDNAError(f'Unsupported error handling "{errors}"')+            raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") @@ -50,3 +52,3 @@         if errors != "strict":-            raise IDNAError(f'Unsupported error handling "{errors}"')+            raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") @@ -75,3 +77,2 @@ -        # Join with U+002E         result_bytes = b".".join(result) + trailing_dot@@ -93,3 +94,3 @@         if errors != "strict":-            raise IDNAError(f'Unsupported error handling "{errors}"')+            raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") @@ -99,3 +100,6 @@         if not isinstance(data, str):-            data = str(data, "ascii")+            try:+                data = str(data, "ascii")+            except UnicodeDecodeError as err:+                raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") from err @@ -134,3 +138,3 @@ -def search_function(name: str) -> Optional[codecs.CodecInfo]:+def search_function(name: str) -> codecs.CodecInfo | None:     """Codec search function registered with :mod:`codecs`.
idna/compat.py +4 lines
--- +++ @@ -1,2 +1,4 @@-from typing import Any, Union+from __future__ import annotations++from typing import Any @@ -18,3 +20,3 @@ -def ToUnicode(label: Union[bytes, bytearray]) -> str:+def ToUnicode(label: bytes | bytearray) -> str:     """Compatibility shim for :rfc:`3490` ``ToUnicode``.
idna/core.py +325 lines
--- +++ @@ -1 +1,3 @@+from __future__ import annotations+ import bisect@@ -4,3 +6,3 @@ import warnings-from typing import Optional, Union+from typing import Literal @@ -12,6 +14,5 @@ _max_input_length = 1024+_STATUS_VALID, _STATUS_MAPPED, _STATUS_DEVIATION, _STATUS_IGNORED = b"VMDI" _unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]")---# Bidi category sets from RFC 5893, hoisted out of the per-codepoint loop+_std3_disallowed_re = re.compile("[\x00-\x2c\x2f\x3a-\x40A-Z\x5b-\x60\x7b-\x7f]") _bidi_rtl_first = frozenset({"R", "AL"})@@ -27,3 +28,3 @@ -def _joining_type(cp: int) -> Optional[str]:+def _joining_type(cp: int) -> str | None:     for jt, ranges in idnadata.joining_types.items():@@ -34,4 +35,73 @@ +# Machine-readable identifiers for the rule an :class:`IDNAError` reports.+# These strings are stable and documented; exception message wording is not.+_ErrorCode = Literal[+    "input_too_long",+    "label_too_long",+    "domain_too_long",+    "empty_label",+    "empty_domain",+    "not_nfc",+    "hyphen_3_4",+    "hyphen_start_end",+    "leading_combiner",+    "disallowed_codepoint",+    "contextj",+    "contexto",+    "unknown_codepoint",+    "bidi_rule_1",+    "bidi_rule_2",+    "bidi_rule_3",+    "bidi_rule_4",+    "bidi_rule_5",+    "bidi_rule_6",+    "bidi_unknown_direction",+    "invalid_alabel",+    "non_canonical_alabel",+    "invalid_ascii",+    "invalid_utf8",+    "uts46_disallowed",+    "uts46_std3",+    "unsupported_errors",+]++ class IDNAError(UnicodeError):-    """Base exception for all IDNA-encoding related problems"""+    """Base exception for all IDNA-encoding related problems.++    ``str(err)`` is a human-readable description of the failure. The+    exception also carries machine-readable attributes so callers do not+    need to parse the message:++    * ``code`` -- a short, stable identifier for the rule that failed, such+      as ``"disallowed_codepoint"`` or ``"bidi_rule_2"``; the full list is+      documented in the README. Message wording, by contrast, may change+      between releases.+    * ``text`` -- the label (or, for UTS #46 processing, the domain) that+      was being validated;+    * ``codepoint`` -- the offending codepoint, as an ``int``;+    * ``position`` -- the 1-based index of the offending character within+      ``text``, matching the position quoted in the message.++    Each is ``None`` when it does not apply.+    """++    code: str | None+    text: str | None+    codepoint: int | None+    position: int | None++    def __init__(+        self,+        *args: object,+        code: _ErrorCode | None = None,+        text: str | None = None,+        codepoint: int | None = None,+        position: int | None = None,+    ) -> None:+        super().__init__(*args)+        self.code = code+        self.text = text+        self.codepoint = codepoint+        self.position = position @@ -69,3 +139,3 @@ -def valid_label_length(label: Union[bytes, str]) -> bool:+def valid_label_length(label: bytes | str) -> bool:     """Check that a label does not exceed the maximum permitted length.@@ -84,3 +154,3 @@ -def valid_string_length(domain: Union[bytes, str], trailing_dot: bool) -> bool:+def valid_string_length(domain: bytes | str, trailing_dot: bool) -> bool:     """Check that a full domain name does not exceed the maximum length.@@ -115,3 +185,3 @@     if len(label) > _max_input_length:-        raise IDNAError("Label too long")+        raise IDNAError("Label too long", code="input_too_long")     # Bidi rules should only be applied if string contains RTL characters@@ -122,3 +192,9 @@             # String likely comes from a newer version of Unicode-            raise IDNABidiError(f"Unknown directionality in label {label!r} at position {idx}")+            raise IDNABidiError(+                f"Unknown directionality in label {label!r} at position {idx}",+                code="bidi_unknown_direction",+                text=label,+                codepoint=ord(cp),+                position=idx,+            )         if direction in _bidi_rtl_categories:@@ -135,6 +211,13 @@     else:-        raise IDNABidiError(f"First codepoint in label {label!r} must be directionality L, R or AL")+        raise IDNABidiError(+            f"First codepoint in label {label!r} must be directionality L, R or AL",+            code="bidi_rule_1",+            text=label,+            codepoint=ord(label[0]),+            position=1,+        )      valid_ending = False-    number_type: Optional[str] = None+    ending_idx = 1+    number_type: str | None = None     for idx, cp in enumerate(label, 1):@@ -145,3 +228,9 @@             if direction not in _bidi_rtl_allowed:-                raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a right-to-left label")+                raise IDNABidiError(+                    f"Invalid direction for codepoint at position {idx} in a right-to-left label",+                    code="bidi_rule_2",+                    text=label,+                    codepoint=ord(cp),+                    position=idx,+                )             # Bidi rule 3@@ -149,4 +238,6 @@                 valid_ending = True+                ending_idx = idx             elif direction != "NSM":                 valid_ending = False+                ending_idx = idx             # Bidi rule 4@@ -156,3 +247,9 @@                 elif number_type != direction:-                    raise IDNABidiError("Can not mix numeral types in a right-to-left label")+                    raise IDNABidiError(+                        "Can not mix numeral types in a right-to-left label",+                        code="bidi_rule_4",+                        text=label,+                        codepoint=ord(cp),+                        position=idx,+                    )         else:@@ -160,3 +257,9 @@             if direction not in _bidi_ltr_allowed:-                raise IDNABidiError(f"Invalid direction for codepoint at position {idx} in a left-to-right label")+                raise IDNABidiError(+                    f"Invalid direction for codepoint at position {idx} in a left-to-right label",+                    code="bidi_rule_5",+                    text=label,+                    codepoint=ord(cp),+                    position=idx,+                )             # Bidi rule 6@@ -164,7 +267,17 @@                 valid_ending = True+                ending_idx = idx             elif direction != "NSM":                 valid_ending = False+                ending_idx = idx      if not valid_ending:-        raise IDNABidiError("Label ends with illegal codepoint directionality")+        # Rules 3 and 6 concern the last character that is not a+        # non-spacing mark, which is what ``ending_idx`` tracks.+        raise IDNABidiError(+            "Label ends with illegal codepoint directionality",+            code="bidi_rule_3" if rtl else "bidi_rule_6",+            text=label,+            codepoint=ord(label[ending_idx - 1]),+            position=ending_idx,+        ) @@ -183,4 +296,10 @@     """-    if unicodedata.category(label[0])[0] == "M":-        raise IDNAError("Label begins with an illegal combining character")+    if label and unicodedata.category(label[0])[0] == "M":+        raise IDNAError(+            "Label begins with an illegal combining character",+            code="leading_combiner",+            text=label,+            codepoint=ord(label[0]),+            position=1,+        )     return True@@ -200,5 +319,5 @@     if label[2:4] == "--":-        raise IDNAError("Label has disallowed hyphens in 3rd and 4th position")-    if label[0] == "-" or label[-1] == "-":-        raise IDNAError("Label must not start or end with a hyphen")+        raise IDNAError("Label has disallowed hyphens in 3rd and 4th position", code="hyphen_3_4")+    if label.startswith("-") or label.endswith("-"):+        raise IDNAError("Label must not start or end with a hyphen", code="hyphen_start_end")     return True@@ -213,5 +332,5 @@     if len(label) > _max_input_length:-        raise IDNAError("Label too long")+        raise IDNAError("Label too long", code="input_too_long")     if unicodedata.normalize("NFC", label) != label:-        raise IDNAError("Label must be in Normalization Form C")+        raise IDNAError("Label must be in Normalization Form C", code="not_nfc") @@ -235,3 +354,3 @@     if len(label) > _max_input_length:-        raise IDNAError("Label too long")+        raise IDNAError("Label too long", code="input_too_long")     cp_value = ord(label[pos])@@ -288,3 +407,3 @@     if len(label) > _max_input_length:-        raise IDNAError("Label too long")+        raise IDNAError("Label too long", code="input_too_long")     cp_value = ord(label[pos])@@ -321,3 +440,3 @@ -def check_label(label: Union[str, bytes, bytearray]) -> None:+def check_label(label: str | bytes | bytearray) -> None:     """Run the full set of IDNA 2008 validity checks on a single label.@@ -340,12 +459,16 @@     if len(label) > _max_input_length:-        raise IDNAError("Label too long")+        raise IDNAError("Label too long", code="input_too_long")
… 363 more lines (truncated)
idna/package_data.py +1 lines
--- +++ @@ -1 +1 @@-__version__ = "3.18"+__version__ = "3.19"
idna/uts46data.py +56 lines
--- +++ @@ -2,4 +2,5 @@ +from __future__ import annotations+ from array import array-from typing import Optional @@ -10,3 +11,3 @@ -uts46_starts: "array[int]" = array(+uts46_starts: array[int] = array(     "I",@@ -8522,3 +8523,3 @@ -uts46_replacements: tuple[Optional[str], ...] = (+uts46_replacements: tuple[str | None, ...] = (     None,@@ -10064,3 +10065,3 @@     "ꙋ",-    "\u1c8a",+    "ᲊ",     None,@@ -12326,5 +12327,5 @@     "ɤ",-    "\ua7cd",-    None,-    "\ua7cf",+    "ꟍ",+    None,+    "꟏",     None,@@ -12340,3 +12341,3 @@     None,-    "\ua7db",+    "ꟛ",     None,@@ -14236,24 +14237,24 @@     None,-    "\U00010d70",-    "\U00010d71",-    "\U00010d72",-    "\U00010d73",-    "\U00010d74",-    "\U00010d75",-    "\U00010d76",-    "\U00010d77",-    "\U00010d78",-    "\U00010d79",-    "\U00010d7a",-    "\U00010d7b",-    "\U00010d7c",-    "\U00010d7d",-    "\U00010d7e",-    "\U00010d7f",-    "\U00010d80",-    "\U00010d81",-    "\U00010d82",-    "\U00010d83",-    "\U00010d84",-    "\U00010d85",+    "𐵰",+    "𐵱",+    "𐵲",+    "𐵳",+    "𐵴",+    "𐵵",+    "𐵶",+    "𐵷",+    "𐵸",+    "𐵹",+    "𐵺",+    "𐵻",+    "𐵼",+    "𐵽",+    "𐵾",+    "𐵿",+    "𐶀",+    "𐶁",+    "𐶂",+    "𐶃",+    "𐶄",+    "𐶅",     None,@@ -14615,27 +14616,27 @@     None,-    "\U00016ebb",-    "\U00016ebc",-    "\U00016ebd",-    "\U00016ebe",-    "\U00016ebf",-    "\U00016ec0",-    "\U00016ec1",-    "\U00016ec2",-    "\U00016ec3",-    "\U00016ec4",-    "\U00016ec5",-    "\U00016ec6",-    "\U00016ec7",-    "\U00016ec8",-    "\U00016ec9",-    "\U00016eca",-    "\U00016ecb",-    "\U00016ecc",-    "\U00016ecd",-    "\U00016ece",-    "\U00016ecf",-    "\U00016ed0",-    "\U00016ed1",-    "\U00016ed2",-    "\U00016ed3",+    "𖺻",+    "𖺼",+    "𖺽",+    "𖺾",+    "𖺿",+    "𖻀",+    "𖻁",+    "𖻂",+    "𖻃",+    "𖻄",+    "𖻅",+    "𖻆",+    "𖻇",+    "𖻈",+    "𖻉",+    "𖻊",+    "𖻋",+    "𖻌",+    "𖻍",+    "𖻎",+    "𖻏",+    "𖻐",+    "𖻑",+    "𖻒",+    "𖻓",     None,
pyproject.toml +19 lines
--- +++ @@ -50,6 +50,15 @@ all = [-    "ruff >= 0.6.2",+    "ruff >= 0.16.0",     "mypy >= 1.11.2",+    "ty >= 0.0.37",     "pytest >= 8.3.2",+    "hypothesis >= 6.141.1",+    "coverage >= 7.10.0", ]++[tool.coverage.run]+source = ["idna"]+[tool.coverage.report]+show_missing = true+fail_under = 95 @@ -59,2 +68,7 @@ extend-select = [+    # pycodestyle import/statement/runtime errors; these were part of ruff's+    # default rule set before 0.16 and are kept explicitly here.+    "E4",+    "E7",+    "E9",     "I",            # isort@@ -67,2 +81,6 @@     "RUF",          # ruff-specific+    "PTH",          # flake8-use-pathlib+    "TC",           # flake8-type-checking+    "FURB",         # refurb+    "C4",           # flake8-comprehensions ]
tests/test_idna.py +187 lines
--- +++ @@ -1,3 +1 @@-#!/usr/bin/env python- import unittest@@ -142,3 +140,2 @@         self.assertTrue(idna.check_bidi(r + al))-        self.assertTrue(idna.check_bidi(r + al))         self.assertTrue(idna.check_bidi(r + an))@@ -191,2 +188,3 @@         self.assertRaises(idna.IDNAError, idna.check_initial_combiner, m + a)+        self.assertTrue(idna.check_initial_combiner("")) @@ -198,2 +196,4 @@         self.assertRaises(idna.IDNAError, idna.check_hyphen_ok, "-a")+        self.assertRaises(idna.IDNAError, idna.check_hyphen_ok, "-")+        self.assertTrue(idna.check_hyphen_ok("")) @@ -214,2 +214,32 @@         self.assertTrue(idna.valid_contextj(virama + zwj, 1))  # Preceding Virama++    def test_check_label_contextj_violation(self):+        zwnj = "\u200c"+        zwj = "\u200d"+        virama = "\u094d"+        latin = "\u0061"++        for joiner in (zwnj, zwj):+            with self.assertRaises(idna.InvalidCodepointContext) as context:+                idna.check_label(latin + joiner + latin)+            self.assertIn("not allowed at position 2", str(context.exception))+            self.assertRaises(idna.InvalidCodepointContext, idna.encode, latin + joiner + latin)++        # Valid joiner contexts are still accepted+        idna.check_label(latin + virama + zwj + latin)+        idna.check_label(latin + virama + zwnj + latin)++    def test_check_label_contextj_unknown_codepoint(self):+        # An adjacent codepoint unknown to unicodedata (e.g. in a+        # newer Unicode version than the Python build supports) must still+        # surface as an IDNAError. Need to mock this to test.+        from unittest import mock++        with (+            mock.patch("idna.core._combining_class", side_effect=ValueError("Unknown character in unicodedata")),+            self.assertRaises(idna.IDNAError) as context,+        ):+            idna.check_label("\u0061\u200d\u0061")+        self.assertNotIsInstance(context.exception, idna.InvalidCodepointContext)+        self.assertIn("Unknown codepoint adjacent to joiner", str(context.exception)) @@ -336,2 +366,14 @@ +    def test_uts46_remap_transitional_deprecation_warning(self):+        with warnings.catch_warnings(record=True) as w:+            warnings.simplefilter("always")+            idna.uts46_remap("example.com", transitional=True)+            self.assertEqual(len(w), 1)+            self.assertTrue(issubclass(w[0].category, DeprecationWarning))+            self.assertIn("transitional", str(w[0].message).lower())+        with warnings.catch_warnings(record=True) as w:+            warnings.simplefilter("always")+            idna.uts46_remap("example.com")+            self.assertEqual(len(w), 0)+     def test_encode_no_transitional_no_warning(self):@@ -351,2 +393,132 @@ +    def test_uts46_remap(self):+        remap = idna.uts46_remap+        # Empty and unchanged input, including the no-copy path for a+        # non-ASCII string that needs no mapping.+        self.assertEqual(remap(""), "")+        self.assertEqual(remap("\u0431\u0443\u043a\u0432\u044b"), "\u0431\u0443\u043a\u0432\u044b")+        # Mapped (M) characters interleaved with runs of valid ones: case+        # folding, fullwidth forms, and the alternative label separators.+        self.assertEqual(remap("\u0411\u0443\u041a\u0432\u042b"), "\u0431\u0443\u043a\u0432\u044b")+        self.assertEqual(remap("ab\uff23\uff24ef"), "abcdef")+        self.assertEqual(remap("a\u3002b\uff0ec\uff61d"), "a.b.c.d")+        # Ignored (I) characters are dropped, wherever they fall.+        self.assertEqual(remap("\u00ada\u00adb\u00ad"), "ab")+        # Deviation (D) characters are kept. Transitional processing, which+        # mapped them, is deprecated in UTS #46 and the flag has no effect.+        self.assertEqual(remap("a\u00dfb"), "a\u00dfb")+        self.assertEqual(remap("a\u03c2b"), "a\u03c2b")+        self.assertEqual(remap("a\u200cb"), "a\u200cb")+        with warnings.catch_warnings():+            warnings.simplefilter("ignore", DeprecationWarning)+            self.assertEqual(remap("a\u00dfb", transitional=True), "a\u00dfb")+            self.assertEqual(remap("a\u03c2b", transitional=True), "a\u03c2b")+            self.assertEqual(remap("a\u200cb", transitional=True), "a\u200cb")+            self.assertEqual(remap("\u1e9e", transitional=True), "\u00df")+        # Output is NFC even when the input is not.+        self.assertEqual(remap("e\u0301"), "\u00e9")+        # Disallowed (X) characters raise, reporting the 1-based position in+        # the input.+        with self.assertRaises(idna.InvalidCodepoint) as cm:+            remap("ab\ufffdc")+        self.assertIn("position 3", str(cm.exception))+        self.assertRaises(idna.IDNAError, remap, "a" * 1025)++    def test_uts46_remap_ascii(self):+        # uts46_remap() takes a shortcut for pure-ASCII input on the basis+        # that the only ASCII mapping in UTS #46 is upper- to lowercase and+        # every other ASCII codepoint has status V. Pin that against the+        # table so a future table change cannot silently invalidate it.+        from idna.uts46data import uts46_replacements, uts46_statuses++        for cp in range(128):+            char = chr(cp)+            if "A" <= char <= "Z":+                self.assertEqual(chr(uts46_statuses[cp]), "M", char)+                self.assertEqual(uts46_replacements[cp], char.lower(), char)+            else:+                self.assertEqual(chr(uts46_statuses[cp]), "V", char)+                self.assertIsNone(uts46_replacements[cp], char)+        for std3_rules in (True, False):+            self.assertEqual(idna.uts46_remap("WWW.Example.COM", std3_rules=std3_rules), "www.example.com")+        self.assertEqual(idna.uts46_remap("a-b_c d~", std3_rules=False), "a-b_c d~")+        self.assertRaises(idna.InvalidCodepoint, idna.uts46_remap, "a-b_c d~", std3_rules=True)+        self.assertRaises(idna.IDNAError, idna.uts46_remap, "A" * 1025)++    def test_uts46_remap_std3(self):+        # UTS #46 §4.1: with UseSTD3ASCIIRules, an ASCII character in the+        # mapped output must be a lowercase letter, digit or hyphen (or the+        # label separator). The offending codepoint and position reported are+        # those of the *input* character, including when the ASCII character+        # was produced by a mapping.+        remap = idna.uts46_remap+        for domain, expected, cp, position in (+            ("a_b", "a_b", "U+005F", 2),  # ASCII fast path+            ("A B", "a b", "U+0020", 2),+            ("a/b.c", "a/b.c", "U+002F", 2),+            ("a\uff01b", "a!b", "U+FF01", 2),  # fullwidth ! maps to !+            ("\u00a0x", " x", "U+00A0", 1),  # NBSP maps to space+            ("a\u2100b", "aa/cb", "U+2100", 2),  # ACCOUNT OF maps to a/c+            ("a\u03b2_", "a\u03b2_", "U+005F", 3),  # in a run after a non-ASCII char+            ("\u03b2\u0391a~", "\u03b2\u03b1a~", "U+007E", 4),  # in the tail run+            ("~\u0391", "~\u03b1", "U+007E", 1),  # in a run before a mapped char+        ):+            with self.subTest(domain=domain):+                self.assertEqual(remap(domain, std3_rules=False), expected)+                with self.assertRaises(idna.InvalidCodepoint) as cm:+                    remap(domain, std3_rules=True)+                self.assertEqual(str(cm.exception), f"Codepoint {cp} not allowed at position {position} in {domain!r}")+        # Letters, digits, hyphens and label separators (including the ones+        # mapped to U+002E) are fine either way.+        for domain, expected in (+            ("a-b.c9", "a-b.c9"),+            ("XN--80AK6AA92E.COM", "xn--80ak6aa92e.com"),+            ("\u0431\uff0e\u0432\u3002\u0433\uff61", "\u0431.\u0432.\u0433."),+            ("\uff21\uff22\uff23", "abc"),+        ):+            for std3_rules in (True, False):+                self.assertEqual(remap(domain, std3_rules=std3_rules), expected)+        # encode() forwards the flag (default off): with it on the mapping+        # step rejects the character; with it off the character survives+        # mapping and is only rejected later by IDNA 2008 label validation.+        with self.assertRaises(idna.InvalidCodepoint) as cm:+            idna.encode("a_b", uts46=True, std3_rules=True)+        self.assertEqual(str(cm.exception), "Codepoint U+005F not allowed at position 2 in 'a_b'")+        with self.assertRaises(idna.InvalidCodepoint) as cm:+            idna.encode("a_b", uts46=True)+        self.assertEqual(str(cm.exception), "Codepoint U+005F at position 2 of 'a_b' not allowed")+        self.assertEqual(idna.encode("a\u00adb", uts46=True, std3_rules=True), b"ab")++    def test_bytes_input_errors_are_idnaerror(self):+        # bytes given to the label helpers must fail with IDNAError, not leak+        # UnicodeDecodeError: check_label() decodes bytes as UTF-8, ulabel()+        # treats bytes as ASCII.+        self.assertRaises(idna.IDNAError, idna.check_label, b"\xff")+        self.assertRaises(idna.IDNAError, idna.ulabel, b"\xff")+        self.assertRaises(idna.IDNAError, idna.ulabel, b"\xc3\x9f")  # valid UTF-8 for U+00DF, still not ASCII+        self.assertRaises(idna.IDNAError, idna.ulabel, bytearray(b"xn--\xff"))+        self.assertEqual(idna.ulabel(b"xn--e1afmkfd"), "\u043f\u0440\u0438\u043c\u0435\u0440")++    def test_non_canonical_alabel(self):+        # RFC 5891 §5.3: an A-label must re-encode to itself. "xn---bbk" is+        # a non-canonical Punycode spelling of "xn--bbk" (RFC 3492 permits+        # a delimiter before an empty basic-code-point run, so both decode+        # to the same U-label); accepting it would let two different+        # wire-format names display identically.+        self.assertEqual(idna.ulabel("xn--bbk"), "\u307e")+        self.assertEqual(idna.encode("xn--bbk"), b"xn--bbk")+        for label in ("xn---bbk", b"xn---bbk", "XN---BBK"):+            with self.subTest(label=label):+                with self.assertRaises(idna.IDNAError) as ctx:+                    idna.ulabel(label)+                self.assertEqual(ctx.exception.code, "non_canonical_alabel")+        self.assertRaises(idna.IDNAError, idna.alabel, "xn---bbk")+        self.assertRaises(idna.IDNAError, idna.encode, "xn---bbk.example")+        self.assertRaises(idna.IDNAError, idna.decode, "xn---bbk.example")+        # display decoding keeps the wire form rather than the misleading U-label+        self.assertEqual(idna.decode("XN---BBK.example", display=True), "xn---bbk.example")+        # ASCII case in the input is not a canonicality violation+        self.assertEqual(idna.ulabel("XN--MNCHEN-3YA"), "m\xfcnchen")+        self.assertEqual(idna.ulabel("xn--Mnchen-3ya"), "m\xfcnchen")+     def test_decode_display(self):@@ -407,2 +579,14 @@ +class UnicodeVersionTests(unittest.TestCase):+    def test_unicode_version_is_exported_and_consistent(self):+        import idna.idnadata+        import idna.uts46data++        self.assertIn("unicode_version", idna.__all__)+        self.assertRegex(idna.unicode_version, r"^\d+\.\d+\.\d+$")+        # The two generated tables must always be regenerated together.+        self.assertEqual(idna.unicode_version, idna.idnadata.__version__)+        self.assertEqual(idna.unicode_version, idna.uts46data.__version__)++ if __name__ == "__main__":
tests/test_idna_cli.py +2 lines
--- +++ @@ -1,3 +1 @@-#!/usr/bin/env python- import io@@ -9,3 +7,3 @@ -from idna import cli+from idna import cli, unicode_version from idna.package_data import __version__@@ -164,2 +162,3 @@         self.assertIn(__version__, buf.getvalue())+        self.assertIn(f"Unicode {unicode_version}", buf.getvalue()) 
tests/test_idna_codec.py +18 lines
--- +++ @@ -1,3 +1 @@-#!/usr/bin/env python- import codecs@@ -9,2 +7,10 @@ CODEC_NAME = "idna2008"++# (decoded, encoded) pairs derived from CPython's Lib/test/test_codecs.py+INCREMENTAL_TESTS = (+    ("python.org", b"python.org"),+    ("python.org.", b"python.org."),+    ("pyth\xf6n.org", b"xn--pythn-mua.org"),+    ("pyth\xf6n.org.", b"xn--pythn-mua.org."),+) @@ -33,2 +39,10 @@ +    def testIncrementalDecoderNonASCII(self):+        # Non-ASCII bytes must surface as IDNAError, as they do from+        # idna.decode() and the one-shot codec, not as UnicodeDecodeError.+        decoder = codecs.getincrementaldecoder(CODEC_NAME)()+        self.assertRaises(idna.IDNAError, decoder.decode, b"\x80")+        self.assertRaises(idna.IDNAError, decoder.decode, b"\xc3\x9f", True)+        self.assertRaises(idna.IDNAError, b"\x80".decode, CODEC_NAME)+     def testStreamReader(self):@@ -54,12 +68,3 @@     def testIncrementalDecoder(self):-        # Tests derived from Python standard library test/test_codecs.py--        incremental_tests = (-            ("python.org", b"python.org"),-            ("python.org.", b"python.org."),-            ("pyth\xf6n.org", b"xn--pythn-mua.org"),-            ("pyth\xf6n.org.", b"xn--pythn-mua.org."),-        )--        for decoded, encoded in incremental_tests:+        for decoded, encoded in INCREMENTAL_TESTS:             self.assertEqual(@@ -102,11 +107,3 @@     def testIncrementalEncoder(self):-        # Tests derived from Python standard library test/test_codecs.py--        incremental_tests = (-            ("python.org", b"python.org"),-            ("python.org.", b"python.org."),-            ("pyth\xf6n.org", b"xn--pythn-mua.org"),-            ("pyth\xf6n.org.", b"xn--pythn-mua.org."),-        )-        for decoded, encoded in incremental_tests:+        for decoded, encoded in INCREMENTAL_TESTS:             self.assertEqual(b"".join(codecs.iterencode(decoded, CODEC_NAME)), encoded)
tests/test_idna_compat.py +0 lines
--- +++ @@ -1,3 +1 @@-#!/usr/bin/env python- import unittest
tests/test_idna_concurrency.py +80 lines
--- +++ @@ -0,0 +1,80 @@+"""Concurrent use of the public API from many threads.++The library keeps no mutable module-level state (the lookup tables are+read-only and ``uts46data`` is imported lazily under the import lock), so+calling it from several threads at once must give exactly the results of+calling it serially. This holds the library to that on every build, and+on free-threaded CPython additionally checks that the GIL really is off+when the environment asked for it, so that a dependency or extension+silently re-enabling it would be noticed.+"""++import codecs+import os+import sys+import unittest+from concurrent.futures import ThreadPoolExecutor++import idna+import idna.codec  # registers the idna2008 codec++# A mix of paths: plain ASCII, U-labels, UTS #46 mapping, A-label decoding,+# the codec, and inputs that must fail with a specific error code.+_INPUTS = [+    "example.com",+    "пример.рф",+    "παράδειγμα.δοκιμή",+    "उदाहरण.परीक्षा",+    "例え.テスト",+    "Bücher.Example",+    "xn--e1afmkfd.xn--p1ai",+    "xn--zckzah.xn--zckzah",+    "xn---bbk.example",+    "-bad.example",+    "a\u200cb.example",+    "a" * 64 + ".example",+]+++def _outcome(fn, *args, **kwargs):+    try:+        return fn(*args, **kwargs)+    except idna.IDNAError as err:+        return ("error", err.code)+++def _work(rounds: int) -> list:+    """Exercise the API ``rounds`` times and return every outcome, in order."""+    results = []+    for _ in range(rounds):+        for s in _INPUTS:+            results.append(_outcome(idna.encode, s))+            results.append(_outcome(idna.encode, s, uts46=True))+            results.append(_outcome(idna.decode, s))+            results.append(_outcome(idna.decode, s, display=True))+            results.append(_outcome(idna.uts46_remap, s))+            results.append(_outcome(codecs.encode, s, "idna2008"))+    return results+++class ConcurrencyTests(unittest.TestCase):+    def test_threads_agree_with_serial_execution(self):+        expected = _work(1)+        with ThreadPoolExecutor(max_workers=8) as pool:+            for outcome in pool.map(lambda _: _work(20), range(16)):+                self.assertEqual(outcome, expected * 20)++    @unittest.skipUnless(+        os.environ.get("PYTHON_GIL") == "0" and hasattr(sys, "_is_gil_enabled"),+        "only meaningful when PYTHON_GIL=0 is set on a free-threaded build",+    )+    def test_gil_stays_disabled_when_requested(self):+        # getattr rather than direct access: the attribute only exists from+        # 3.13, and the type checkers evaluate against requires-python.+        is_gil_enabled = getattr(sys, "_is_gil_enabled", None)+        assert is_gil_enabled is not None+        self.assertFalse(is_gil_enabled())+++if __name__ == "__main__":+    unittest.main()
tests/test_idna_errors.py +174 lines
--- +++ @@ -0,0 +1,174 @@+"""Tests for the machine-readable attributes carried by IDNAError."""++import codecs+import pickle+import re+import unittest+from pathlib import Path+from typing import get_args+from unittest import mock++import idna+import idna.codec+import idna.core+++class ErrorAttributeTests(unittest.TestCase):+    def _cases(self):+        """(trigger, expected class, expected text, codepoint, position)"""+        r = "\u05d0"  # R+        an = "\u0660"  # AN+        nsm = "\u0610"  # NSM+        return [+            (lambda: idna.alabel("abc\u0141"), idna.InvalidCodepoint, "abc\u0141", 0x141, 4),+            (lambda: idna.alabel("a\u200cb"), idna.InvalidCodepointContext, "a\u200cb", 0x200C, 2),+            (lambda: idna.alabel("a\xb7b"), idna.InvalidCodepointContext, "a\xb7b", 0xB7, 2),+            (lambda: idna.alabel("\u0301abc"), idna.IDNAError, "\u0301abc", 0x301, 1),+            (lambda: self._unknown_direction("ab"), idna.IDNABidiError, "ab", 0x61, 1),+            (lambda: idna.check_bidi(an + r), idna.IDNABidiError, an + r, 0x660, 1),  # rule 1+            (lambda: idna.check_bidi(r + "a"), idna.IDNABidiError, r + "a", 0x61, 2),  # rule 2+            (lambda: idna.check_bidi(r + "-" + nsm), idna.IDNABidiError, r + "-" + nsm, 0x2D, 2),  # rule 3+            (lambda: idna.check_bidi(r + an + "0"), idna.IDNABidiError, r + an + "0", 0x30, 3),  # rule 4+            (lambda: idna.alabel("a" + r), idna.IDNABidiError, "a" + r, 0x5D0, 2),  # rule 5+            (lambda: idna.check_bidi("a-", check_ltr=True), idna.IDNABidiError, "a-", 0x2D, 2),  # rule 6+            (lambda: idna.uts46_remap("a\x80"), idna.InvalidCodepoint, "a\x80", 0x80, 2),+            (lambda: idna.uts46_remap("a_b"), idna.InvalidCodepoint, "a_b", 0x5F, 2),+            (lambda: idna.uts46_remap("a\uff3fb"), idna.InvalidCodepoint, "a\uff3fb", 0xFF3F, 2),+            (lambda: idna.encode("a_b", uts46=True, std3_rules=True), idna.InvalidCodepoint, "a_b", 0x5F, 2),+        ]++    def test_attributes_are_populated(self):+        for trigger, exc_class, text, codepoint, position in self._cases():+            with self.subTest(text=text):+                with self.assertRaises(exc_class) as ctx:+                    trigger()+                err = ctx.exception+                self.assertEqual(err.text, text)+                self.assertEqual(err.codepoint, codepoint)+                self.assertEqual(err.position, position)+                # position indexes text and names the codepoint ...+                self.assertEqual(ord(err.text[err.position - 1]), err.codepoint)+                # ... and agrees with the message where the message quotes one+                match = re.search(r"position (\d+)", str(err))+                if match:+                    self.assertEqual(int(match.group(1)), err.position)++    def test_every_error_code_is_documented_and_raisable(self):+        """Each code has an input that produces it, and vice versa; the README+        table must list exactly this set."""+        r = "\u05d0"+        an = "\u0660"+        triggers = {+            "input_too_long": lambda: idna.encode("a" * 1025),+            "label_too_long": lambda: idna.alabel("a" * 64),+            "domain_too_long": lambda: idna.encode(".".join(["a" * 63] * 4)),+            "empty_label": lambda: idna.encode("a..b"),+            "empty_domain": lambda: idna.encode(""),+            "not_nfc": lambda: idna.alabel("e\u0301xample"),+            "hyphen_3_4": lambda: idna.alabel("ab--cd"),+            "hyphen_start_end": lambda: idna.alabel("-abc"),+            "leading_combiner": lambda: idna.alabel("\u0301abc"),+            "disallowed_codepoint": lambda: idna.alabel("abc\u0141"),+            "contextj": lambda: idna.alabel("a\u200cb"),+            "contexto": lambda: idna.alabel("a\xb7b"),+            "unknown_codepoint": self._unknown_codepoint,+            "bidi_rule_1": lambda: idna.check_bidi(an + r),+            "bidi_rule_2": lambda: idna.check_bidi(r + "a"),+            "bidi_rule_3": lambda: idna.check_bidi(r + "-"),+            "bidi_rule_4": lambda: idna.check_bidi(r + an + "0"),+            "bidi_rule_5": lambda: idna.alabel("a" + r),+            "bidi_rule_6": lambda: idna.check_bidi("a-", check_ltr=True),+            "bidi_unknown_direction": lambda: self._unknown_direction("ab"),+            "invalid_alabel": lambda: idna.ulabel("xn--"),+            "non_canonical_alabel": lambda: idna.ulabel("xn---bbk"),+            "invalid_ascii": lambda: idna.encode(b"\xff"),+            "invalid_utf8": lambda: idna.check_label(b"\xff"),+            "uts46_disallowed": lambda: idna.uts46_remap("a\x80"),+            "uts46_std3": lambda: idna.uts46_remap("a_b"),+            "unsupported_errors": lambda: codecs.encode("a", "idna2008", errors="ignore"),+        }+        codes = set(get_args(idna.core._ErrorCode))+        self.assertEqual(set(triggers), codes)+        for code, trigger in triggers.items():+            with self.subTest(code=code):+                with self.assertRaises(idna.IDNAError) as ctx:+                    trigger()+                self.assertEqual(ctx.exception.code, code)+        readme = Path(__file__).resolve().parent.parent / "README.md"+        if not readme.is_file():+            self.skipTest("README.md not present")+        documented = set()+        for first, last in re.findall(r"^\| `([a-z0-9_]+)`(?: \u2026 `([a-z0-9_]+)`)? \|", readme.read_text(), re.MULTILINE):+            if last:  # a `x_1` … `x_6` range row+                stem, lo = first.rsplit("_", 1)+                documented.update(f"{stem}_{i}" for i in range(int(lo), int(last.rsplit("_", 1)[1]) + 1))+            else:+                documented.add(first)+        documented.discard("code")  # the table header+        self.assertEqual(documented, codes)++    # Conditions that depend on the host's Unicode database being older than+    # the input cannot be triggered portably (from Python 3.15,+    # ``unicodedata.bidirectional`` returns a default class for every+    # codepoint), so simulate them.+    def _unknown_codepoint(self):+        with mock.patch("idna.core._combining_class", side_effect=ValueError):+            idna.check_label("a\u200cb")++    def _unknown_direction(self, label):+        with mock.patch("idna.core.unicodedata.bidirectional", return_value=""):+            idna.check_bidi(label)++    def test_unknown_codepoint_adjacent_to_joiner(self):+        unknown = mock.patch("idna.core._combining_class", side_effect=ValueError)+        with unknown, self.assertRaises(idna.IDNAError) as ctx:+            idna.check_label("a\u200cb")+        err = ctx.exception+        self.assertNotIsInstance(err, idna.InvalidCodepointContext)+        self.assertEqual(err.code, "unknown_codepoint")+        self.assertEqual((err.text, err.codepoint, err.position), ("a\u200cb", 0x200C, 2))++    def test_positional_attributes_default_to_none(self):+        for trigger in (+            lambda: idna.encode("a..b"),+            lambda: idna.encode(""),+            lambda: idna.alabel("a" * 64),+            lambda: idna.alabel("ab--cd"),+            lambda: idna.alabel("-abc"),+            lambda: idna.ulabel("xn--"),+            lambda: idna.encode(b"\xff"),+        ):+            with self.assertRaises(idna.IDNAError) as ctx:+                trigger()+            err = ctx.exception+            self.assertIsNotNone(err.code)+            self.assertIsNone(err.text)+            self.assertIsNone(err.codepoint)+            self.assertIsNone(err.position)++    def test_construction_is_backwards_compatible(self):+        err = idna.IDNAError("just a message")+        self.assertEqual(str(err), "just a message")+        self.assertEqual(err.args, ("just a message",))+        self.assertIsNone(err.code)+        self.assertIsNone(err.text)+        self.assertEqual(idna.IDNAError().args, ())+        self.assertEqual(idna.InvalidCodepoint("a", "b").args, ("a", "b"))++    def test_message_remains_sole_positional_argument(self):+        with self.assertRaises(idna.InvalidCodepoint) as ctx:+            idna.alabel("abc\u0141")+        self.assertEqual(ctx.exception.args, ("Codepoint U+0141 at position 4 of 'abc\u0141' not allowed",))++    def test_attributes_survive_pickle(self):+        with self.assertRaises(idna.InvalidCodepoint) as ctx:+            idna.alabel("abc\u0141")+        err = pickle.loads(pickle.dumps(ctx.exception))+        self.assertIsInstance(err, idna.InvalidCodepoint)+        self.assertEqual(str(err), str(ctx.exception))+        self.assertEqual(err.code, "disallowed_codepoint")+        self.assertEqual((err.text, err.codepoint, err.position), ("abc\u0141", 0x141, 4))+++if __name__ == "__main__":+    unittest.main()
tests/test_idna_fuzz_targets.py +108 lines
--- +++ @@ -0,0 +1,108 @@+"""Smoke-test the OSS-Fuzz harnesses (``tests/fuzz_*.py``) without libFuzzer.++The real fuzzers need ``atheris`` (and a libFuzzer-capable clang) to run.+Here a minimal stand-in for the parts of ``atheris`` the harnesses use is+installed into ``sys.modules`` and each ``TestOneInput`` is driven with+pseudo-random bytes. This catches harnesses that fall out of step with the+library API long before OSS-Fuzz reports a build or run failure.+"""++from __future__ import annotations++import contextlib+import importlib.util+import random+import sys+import types+import unittest+from pathlib import Path+from typing import Any, Callable+from unittest import mock++TARGETS = sorted(Path(__file__).resolve().parent.glob("fuzz_*.py"))+ITERATIONS = 2000++# Well-formed inputs are vanishingly rare in random bytes, so half the+# iterations splice one of these behind a random header to reach the+# harnesses' success-path assertions (round trips, idempotence, ...).+SEEDS = [+    b"example.com",+    b"ExAmPlE.COM.",+    b"a-b.c1.d",+    "пример.рф".encode(),+    b"xn--e1afmkfd.xn--p1ai",+    "παράδειγμα.δοκιμή".encode(),+    "उदाहरण.परीक्षा".encode(),+    "例え.テスト".encode(),+    "bücher.example".encode(),+    "Faß.de".encode(),+    "a\u200cb.example".encode(),+    b"xn--.example",+    b"-hyphen.example",+    b"xn--80ak6aa92e.com",+    b"xn---bbk.example",  # non-canonical spelling of xn--bbk+    b"XN--MNCHEN-3YA.example",+]+++class _FuzzedDataProvider:+    """Just enough of ``atheris.FuzzedDataProvider`` for the harnesses."""++    def __init__(self, data: bytes) -> None:+        self._data = data+        self._pos = 0++    def _take(self, n: int) -> bytes:+        chunk = self._data[self._pos : self._pos + n]+        self._pos += len(chunk)+        return chunk++    def ConsumeBool(self) -> bool:+        return bool(self._take(1)[0] & 1) if self._pos < len(self._data) else False++    def ConsumeIntInRange(self, low: int, high: int) -> int:+        raw = self._take(4)+        return low + (int.from_bytes(raw, "little") % (high - low + 1)) if raw else low++    def ConsumeBytes(self, count: int) -> bytes:+        return self._take(count)++    def ConsumeUnicode(self, count: int) -> str:+        return self._take(count).decode("utf-8", "surrogatepass" if self.ConsumeBool() else "replace")+++def _fake_atheris() -> types.ModuleType:+    module = types.ModuleType("atheris")+    module.__dict__.update(+        FuzzedDataProvider=_FuzzedDataProvider,+        instrument_imports=contextlib.nullcontext,+        Setup=lambda *args, **kwargs: None,+        Fuzz=lambda *args, **kwargs: None,+    )+    return module+++def _load(path: Path) -> Callable[[bytes], Any]:+    with mock.patch.dict(sys.modules, {"atheris": _fake_atheris()}):+        spec = importlib.util.spec_from_file_location(path.stem, path)+        assert spec is not None and spec.loader is not None+        module = importlib.util.module_from_spec(spec)+        spec.loader.exec_module(module)+    return module.TestOneInput  # type: ignore[no-any-return]+++class FuzzTargetSmokeTests(unittest.TestCase):+    def test_targets_survive_random_input(self) -> None:+        rng = random.Random(0)+        for path in TARGETS:+            with self.subTest(target=path.name):+                test_one_input = _load(path)+                for i in range(ITERATIONS):+                    data = rng.randbytes(rng.randrange(0, 200))+                    if i % 2:+                        data = rng.randbytes(rng.randrange(4, 12)) + rng.choice(SEEDS)+                    test_one_input(data)+++if __name__ == "__main__":+    unittest.main()
tests/test_idna_properties.py +272 lines
--- +++ @@ -0,0 +1,272 @@+"""Property-based tests using Hypothesis.++The UTS #46 conformance suite covers known-answer cases; these tests explore+the input space for the failure class behind CVE-2024-3651 and+CVE-2026-45409 ("pathological input causes unexpected behaviour"). Each+property asserts an invariant that must hold for *any* input: the only+exception the public API raises is :class:`idna.IDNAError`, successful+output is well-formed, and the several routes to the same operation agree.++Set ``HYPOTHESIS_PROFILE=thorough`` to run 10,000 examples per property.+"""++from __future__ import annotations++import codecs+import os+import unicodedata+import unittest+import warnings+from typing import Any, Callable++from hypothesis import HealthCheck, example, given, settings+from hypothesis import strategies as st++import idna+import idna.codec  # registers the "idna2008" codec+from idna.intranges import intranges_contain, intranges_from_list++settings.register_profile("idna", deadline=None, print_blob=True)+settings.register_profile(+    "thorough",+    max_examples=10_000,+    deadline=None,+    print_blob=True,+    suppress_health_check=[HealthCheck.too_slow],+)+settings.load_profile(os.environ.get("HYPOTHESIS_PROFILE", "idna"))+++# --- Strategies ------------------------------------------------------------++# Characters that exercise the interesting rules in RFC 5891-5893 and+# UTS #46: label separators, joiners, combining marks, contextual-rule+# codepoints, hyphens/digits, "xn--" prefixes, and full-width/case variants.+_interesting = st.sampled_from(+    "abcxyzABCXYZ0189-_ "+    "xn--"+    ".。.。"  # label separators+    "‌‍"  # ZWNJ, ZWJ (CONTEXTJ)+    "्̀̈ํ"  # combining marks / virama+    "·͵・"  # CONTEXTO: middle dot, keraia, katakana middle dot+    "αςбяकम中文カタひ"  # sample letters+    "ßẞσÅÅfi①A"  # UTS #46 mapped/deviation chars+    "\U0001d400\U0001f600"  # supplementary plane+)+_bidi_range = st.characters(min_codepoint=0x0590, max_codepoint=0x08FF)  # RTL scripts, for bidi rules+_any_char = st.characters(exclude_categories=())  # includes surrogates and unassigned codepoints++_label = st.text(alphabet=st.one_of(_interesting, _bidi_range, _any_char, st.characters()), max_size=70)+_structured_domain = st.lists(_label, max_size=6).map(".".join)+_free_text = st.text(alphabet=st.one_of(_any_char, st.characters()), max_size=300)+_over_long = st.text(min_size=1000, max_size=1100)++domains = st.one_of(_structured_domain, _free_text, _over_long)+labels = st.text(alphabet=st.one_of(_interesting, _bidi_range, st.characters()), max_size=100)+ascii_domains = st.text(alphabet=st.characters(max_codepoint=0x7F), max_size=300)+binary = st.binary(max_size=300)+flags = st.booleans()+_STD3_ASCII = frozenset("abcdefghijklmnopqrstuvwxyz0123456789-.")+++def _run(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> tuple[Any, idna.IDNAError | None]:+    """Return ``(result, None)`` or ``(None, error)``, letting anything else propagate."""+    with warnings.catch_warnings():+        # transitional=True is deprecated but still exercised deliberately.+        warnings.simplefilter("ignore", DeprecationWarning)+        try:+            return fn(*args, **kwargs), None+        except idna.IDNAError as err:+            return None, err+++class OnlyIDNAErrorTests(unittest.TestCase):+    """The public API never raises anything except ``IDNAError`` for any input."""++    @given(domains, flags, flags, flags, flags)+    def test_encode(self, s: str, strict: bool, uts46: bool, std3_rules: bool, transitional: bool) -> None:+        _run(idna.encode, s, strict=strict, uts46=uts46, std3_rules=std3_rules, transitional=transitional)++    @given(st.one_of(domains, binary), flags, flags, flags, flags)+    def test_decode(self, s: str | bytes, strict: bool, uts46: bool, std3_rules: bool, display: bool) -> None:+        _run(idna.decode, s, strict=strict, uts46=uts46, std3_rules=std3_rules, display=display)++    @given(domains, flags, flags)+    def test_uts46_remap(self, s: str, std3_rules: bool, transitional: bool) -> None:+        _run(idna.uts46_remap, s, std3_rules=std3_rules, transitional=transitional)++    @given(labels)+    def test_label_helpers(self, label: str) -> None:+        for fn in (+            idna.alabel,+            idna.ulabel,+            idna.check_label,+            idna.check_bidi,+            idna.check_hyphen_ok,+            idna.check_initial_combiner,+            idna.check_nfc,+            idna.valid_label_length,+        ):+            _run(fn, label)+        _run(idna.ulabel, label.encode("utf-8", "surrogatepass"))++    @given(st.one_of(domains, binary), flags)+    def test_codec(self, s: str | bytes, final: bool) -> None:+        if isinstance(s, str):+            _run(s.encode, "idna2008")+            _run(codecs.getincrementalencoder("idna2008")().encode, s, final)+        else:+            _run(s.decode, "idna2008")+            _run(codecs.getincrementaldecoder("idna2008")().decode, s, final)+++class OutputShapeTests(unittest.TestCase):+    @given(domains, flags, flags, flags)+    def test_encode_output_is_bounded_ascii(self, s: str, strict: bool, uts46: bool, std3_rules: bool) -> None:+        result, err = _run(idna.encode, s, strict=strict, uts46=uts46, std3_rules=std3_rules)+        if err is not None:+            return+        self.assertIsInstance(result, bytes)+        result.decode("ascii")+        self.assertLessEqual(len(result), 254)+        for label in result.rstrip(b".").split(b"."):+            self.assertTrue(0 < len(label) <= 63)++    @given(domains, flags, flags)+    def test_uts46_remap_output_is_nfc_and_idempotent(self, s: str, std3_rules: bool, transitional: bool) -> None:+        out, err = _run(idna.uts46_remap, s, std3_rules=std3_rules, transitional=transitional)+        if err is not None:+            return+        self.assertTrue(unicodedata.is_normalized("NFC", out))+        again, _ = _run(idna.uts46_remap, out, std3_rules=std3_rules, transitional=transitional)+        self.assertEqual(again, out)+        if std3_rules:+            # UTS #46 §4.1 UseSTD3ASCIIRules: only LDH ASCII (plus the label+            # separator) may survive mapping.+            self.assertTrue(all(c in _STD3_ASCII for c in out if c.isascii()), out)+        else:+            # Turning the rules on must never change a result, only reject it.+            strict, err = _run(idna.uts46_remap, s, std3_rules=True, transitional=transitional)+            self.assertTrue(err is not None or strict == out)+++class RoundTripTests(unittest.TestCase):+    @given(domains, flags, flags)+    def test_encode_decode_encode(self, s: str, uts46: bool, std3_rules: bool) -> None:+        encoded, err = _run(idna.encode, s, uts46=uts46, std3_rules=std3_rules)+        if err is not None:+            return+        decoded = idna.decode(encoded)  # anything encode() produced must decode+        # ulabel() lowercases ASCII labels while alabel() preserves case, so the+        # round trip is exact only up to ASCII case.+        self.assertEqual(idna.encode(decoded), encoded.lower())+        # display=True only changes behaviour for labels that fail to decode+        self.assertEqual(idna.decode(encoded, display=True), decoded)++    @given(ascii_domains)+    @example("xn---bbk.example")+    @example("a" * 64)+    def test_decode_encode(self, s: str) -> None:+        # RFC 5891 §5.3: an A-label that decodes must re-encode to itself, so+        # any ASCII input that decodes is (up to case) its own encoding.+        # Restricted to strict, non-UTS46 processing since other modes may+        # legitimately rewrite the input, and to labels within the DNS+        # length limit, which decode() (like UTS #46 ToUnicode) does not+        # enforce but encode() does.+        decoded, err = _run(idna.decode, s, strict=True)+        if err is not None or any(len(label) > 63 for label in s.split(".")):+            return+        self.assertEqual(idna.encode(decoded, strict=True), s.lower().encode("ascii"))++    @given(labels)+    def test_alabel_ulabel(self, label: str) -> None:+        encoded, err = _run(idna.alabel, label)+        if err is not None:+            return+        self.assertEqual(idna.alabel(idna.ulabel(encoded)), encoded.lower())+++class DifferentialTests(unittest.TestCase):+    """Different routes to the same operation must agree."""++    @staticmethod+    def _assert_same_outcome(test: unittest.TestCase, a: tuple[Any, Any], b: tuple[Any, Any]) -> None:+        (a_result, a_err), (b_result, b_err) = a, b+        test.assertEqual(a_err is None, b_err is None, f"{a_err!r} vs {b_err!r}")+        test.assertEqual(a_result, b_result)++    @given(domains, flags)+    def test_transitional_has_no_effect(self, s: str, std3_rules: bool) -> None:+        # UTS #46 deprecated transitional processing; the flag is accepted+        # for backwards compatibility but deviation characters are kept+        # either way.+        self._assert_same_outcome(+            self,+            _run(idna.uts46_remap, s, std3_rules=std3_rules, transitional=True),+            _run(idna.uts46_remap, s, std3_rules=std3_rules),+        )+        self._assert_same_outcome(+            self,+            _run(idna.encode, s, uts46=True, std3_rules=std3_rules, transitional=True),+            _run(idna.encode, s, uts46=True, std3_rules=std3_rules),+        )++    @given(ascii_domains)+    def test_strict_is_irrelevant_for_ascii(self, s: str) -> None:+        self._assert_same_outcome(self, _run(idna.encode, s, strict=True), _run(idna.encode, s, strict=False))+        self._assert_same_outcome(self, _run(idna.decode, s, strict=True), _run(idna.decode, s, strict=False))++    @given(domains)+    def test_codec_encode_matches_core(self, s: str) -> None:+        if not s:+            return  # the codec short-circuits empty input where core raises "Empty domain"+        self._assert_same_outcome(self, _run(s.encode, "idna2008"), _run(idna.encode, s))++    @given(binary)+    def test_codec_decode_matches_core(self, b: bytes) -> None:+        if not b:+            return+        self._assert_same_outcome(self, _run(b.decode, "idna2008"), _run(idna.decode, b))++    @given(domains, st.lists(st.integers(min_value=0, max_value=300), max_size=8))+    def test_incremental_encoder_matches_one_shot(self, s: str, cuts: list[int]) -> None:+        if not s:+            return  # see test_codec_encode_matches_core+        one_shot, err = _run(idna.encode, s)+        encoder = codecs.getincrementalencoder("idna2008")()+        chunks = _split(s, cuts)++        def incremental() -> bytes:+            out = b"".join(encoder.encode(chunk) for chunk in chunks)+            return out + encoder.encode("", final=True)++        self._assert_same_outcome(self, (one_shot, err), _run(incremental))++    @given(binary, st.lists(st.integers(min_value=0, max_value=300), max_size=8))+    def test_incremental_decoder_matches_one_shot(self, b: bytes, cuts: list[int]) -> None:+        if not b:
… 25 more lines (truncated)
tests/test_idna_uts46.py +36 lines
--- +++ @@ -16242,4 +16242,4 @@     def test_uts46_4218(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032931⒛⾳.ꡦ⒈', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032931⒛⾳.ꡦ⒈', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲤱⒛⾳.ꡦ⒈', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲤱⒛⾳.ꡦ⒈', strict=True) @@ -16966,16 +16966,16 @@     def test_uts46_4401(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dß', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dß', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dß', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dß', strict=True)      def test_uts46_4402(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dß', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dß', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dß', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dß', strict=True)      def test_uts46_4403(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dSS', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dSS', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dSS', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dSS', strict=True)      def test_uts46_4404(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dss', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dss', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dss', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dss', strict=True) @@ -16990,16 +16990,16 @@     def test_uts46_4410(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dSS', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dSS', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dSS', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dSS', strict=True)      def test_uts46_4411(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dss', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dss', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dss', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dss', strict=True)      def test_uts46_4412(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dSs', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dSs', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dSs', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dSs', strict=True)      def test_uts46_4413(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U00032b9a9ꍩ៓.\u200dSs', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U00032b9a9ꍩ៓.\u200dSs', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲮚9ꍩ៓.\u200dSs', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲮚9ꍩ៓.\u200dSs', strict=True) @@ -22086,8 +22086,8 @@     def test_uts46_5693(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0003250f\U0001eae8\U0007afc2硲.ڭ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0003250f\U0001eae8\U0007afc2硲.ڭ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲔏\U0001eae8\U0007afc2硲.ڭ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲔏\U0001eae8\U0007afc2硲.ڭ', strict=True)      def test_uts46_5694(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0003250f\U0001eae8\U0007afc2硲.ڭ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0003250f\U0001eae8\U0007afc2硲.ڭ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𲔏\U0001eae8\U0007afc2硲.ڭ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𲔏\U0001eae8\U0007afc2硲.ڭ', strict=True) @@ -22658,16 +22658,16 @@     def test_uts46_5836(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9ς', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9ς', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9ς', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9ς', strict=True)      def test_uts46_5837(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9ς', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9ς', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9ς', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9ς', strict=True)      def test_uts46_5838(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9Σ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9Σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9Σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9Σ', strict=True)      def test_uts46_5839(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9σ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。\U00032a67\U000e04b9σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆4\U000a9786。𲩧\U000e04b9σ', strict=True) @@ -22682,8 +22682,8 @@     def test_uts46_5842(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9Σ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9Σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9Σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9Σ', strict=True)      def test_uts46_5843(self):-        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9σ', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。\U00032a67\U000e04b9σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9σ', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '\U0005747f꠆₄\U000a9786。𲩧\U000e04b9σ', strict=True) @@ -24626,4 +24626,4 @@     def test_uts46_6330(self):-        self.assertRaises(idna.IDNAError, idna.decode, '𑄳。\u1adc𐹻', strict=True)-        self.assertRaises(idna.IDNAError, idna.encode, '𑄳。\u1adc𐹻', strict=True)+        self.assertRaises(idna.IDNAError, idna.decode, '𑄳。᫜𐹻', strict=True)+        self.assertRaises(idna.IDNAError, idna.encode, '𑄳。᫜𐹻', strict=True) 
tests/test_intranges.py +0 lines
--- +++ @@ -1,3 +1 @@-#!/usr/bin/env python- import unittest
iniconfig pypi
2.3.0 10mo ago nominal
no findings
latest 2.3.0 versions 11 maintainers 1
0.1
1.0.0
1.0.1
1.1.0
1.1.1
2.0.0
2.1.0
2.2.0
2.3.0
CLEAN
no findings — nominal
release diff 2.2.0 → 2.3.0
+0 added · -0 removed · ~7 modified
src/iniconfig/__init__.py +75 lines
--- +++ @@ -98,29 +98,82 @@         encoding: str = "utf-8",+        *,+        _sections: Mapping[str, Mapping[str, str]] | None = None,+        _sources: Mapping[tuple[str, str | None], int] | None = None,     ) -> None:         self.path = os.fspath(path)++        # Determine sections and sources+        if _sections is not None and _sources is not None:+            # Use provided pre-parsed data (called from parse())+            sections_data = _sections+            sources = _sources+        else:+            # Parse the data (backward compatible path)+            if data is None:+                with open(self.path, encoding=encoding) as fp:+                    data = fp.read()++            # Use old behavior (no stripping) for backward compatibility+            sections_data, sources = _parse.parse_ini_data(+                self.path, data, strip_inline_comments=False+            )++        # Assign once to Final attributes+        self._sources = sources+        self.sections = sections_data++    @classmethod+    def parse(+        cls,+        path: str | os.PathLike[str],+        data: str | None = None,+        encoding: str = "utf-8",+        *,+        strip_inline_comments: bool = True,+        strip_section_whitespace: bool = False,+    ) -> "IniConfig":+        """Parse an INI file.++        Args:+            path: Path to the INI file (used for error messages)+            data: Optional INI content as string. If None, reads from path.+            encoding: Encoding to use when reading the file (default: utf-8)+            strip_inline_comments: Whether to strip inline comments from values+                (default: True). When True, comments starting with # or ; are+                removed from values, matching the behavior for section comments.+            strip_section_whitespace: Whether to strip whitespace from section and key names+                (default: False). When True, strips Unicode whitespace from section and key names,+                addressing issue #4. When False, preserves existing behavior for backward compatibility.++        Returns:+            IniConfig instance with parsed configuration++        Example:+            # With comment stripping (default):+            config = IniConfig.parse("setup.cfg")+            # value = "foo" instead of "foo # comment"++            # Without comment stripping (old behavior):+            config = IniConfig.parse("setup.cfg", strip_inline_comments=False)+            # value = "foo # comment"++            # With section name stripping (opt-in for issue #4):+            config = IniConfig.parse("setup.cfg", strip_section_whitespace=True)+            # section names and keys have Unicode whitespace stripped+        """+        fspath = os.fspath(path)+         if data is None:-            with open(self.path, encoding=encoding) as fp:+            with open(fspath, encoding=encoding) as fp:                 data = fp.read() -        tokens = _parse.parse_lines(self.path, data.splitlines(True))--        self._sources = {}-        sections_data: dict[str, dict[str, str]]-        self.sections = sections_data = {}--        for lineno, section, name, value in tokens:-            if section is None:-                raise ParseError(self.path, lineno, "no section header defined")-            self._sources[section, name] = lineno-            if name is None:-                if section in self.sections:-                    raise ParseError(-                        self.path, lineno, f"duplicate section {section!r}"-                    )-                sections_data[section] = {}-            else:-                if name in self.sections[section]:-                    raise ParseError(self.path, lineno, f"duplicate name {name!r}")-                assert value is not None-                sections_data[section][name] = value+        sections_data, sources = _parse.parse_ini_data(+            fspath,+            data,+            strip_inline_comments=strip_inline_comments,+            strip_section_whitespace=strip_section_whitespace,+        )++        # Call constructor with pre-parsed sections and sources+        return cls(path=fspath, _sections=sections_data, _sources=sources) 
src/iniconfig/_parse.py +89 lines
--- +++ @@ -1 +1,2 @@+from collections.abc import Mapping from typing import NamedTuple@@ -14,3 +15,57 @@ -def parse_lines(path: str, line_iter: list[str]) -> list[ParsedLine]:+def parse_ini_data(+    path: str,+    data: str,+    *,+    strip_inline_comments: bool,+    strip_section_whitespace: bool = False,+) -> tuple[Mapping[str, Mapping[str, str]], Mapping[tuple[str, str | None], int]]:+    """Parse INI data and return sections and sources mappings.++    Args:+        path: Path for error messages+        data: INI content as string+        strip_inline_comments: Whether to strip inline comments from values+        strip_section_whitespace: Whether to strip whitespace from section and key names+            (default: False). When True, addresses issue #4 by stripping Unicode whitespace.++    Returns:+        Tuple of (sections_data, sources) where:+        - sections_data: mapping of section -> {name -> value}+        - sources: mapping of (section, name) -> line number+    """+    tokens = parse_lines(+        path,+        data.splitlines(True),+        strip_inline_comments=strip_inline_comments,+        strip_section_whitespace=strip_section_whitespace,+    )++    sources: dict[tuple[str, str | None], int] = {}+    sections_data: dict[str, dict[str, str]] = {}++    for lineno, section, name, value in tokens:+        if section is None:+            raise ParseError(path, lineno, "no section header defined")+        sources[section, name] = lineno+        if name is None:+            if section in sections_data:+                raise ParseError(path, lineno, f"duplicate section {section!r}")+            sections_data[section] = {}+        else:+            if name in sections_data[section]:+                raise ParseError(path, lineno, f"duplicate name {name!r}")+            assert value is not None+            sections_data[section][name] = value++    return sections_data, sources+++def parse_lines(+    path: str,+    line_iter: list[str],+    *,+    strip_inline_comments: bool = False,+    strip_section_whitespace: bool = False,+) -> list[ParsedLine]:     result: list[ParsedLine] = []@@ -18,3 +73,5 @@     for lineno, line in enumerate(line_iter):-        name, data = _parseline(path, line, lineno)+        name, data = _parseline(+            path, line, lineno, strip_inline_comments, strip_section_whitespace+        )         # new value@@ -44,3 +101,9 @@ -def _parseline(path: str, line: str, lineno: int) -> tuple[str | None, str | None]:+def _parseline(+    path: str,+    line: str,+    lineno: int,+    strip_inline_comments: bool,+    strip_section_whitespace: bool,+) -> tuple[str | None, str | None]:     # blank lines@@ -58,3 +121,7 @@         if line[-1] == "]":-            return line[1:-1], None+            section_name = line[1:-1]+            # Optionally strip whitespace from section name (issue #4)+            if strip_section_whitespace:+                section_name = section_name.strip()+            return section_name, None         return None, realline.strip()@@ -71,6 +138,22 @@                 raise ParseError(path, lineno, f"unexpected line: {line!r}") from None-        return name.strip(), value.strip()++        # Strip key name (always for backward compatibility, optionally with unicode awareness)+        key_name = name.strip()++        # Strip value+        value = value.strip()+        # Strip inline comments from values if requested (issue #55)+        if strip_inline_comments:+            for c in COMMENTCHARS:+                value = value.split(c)[0].rstrip()++        return key_name, value     # continuation     else:-        return None, line.strip()+        line = line.strip()+        # Strip inline comments from continuations if requested (issue #55)+        if strip_inline_comments:+            for c in COMMENTCHARS:+                line = line.split(c)[0].rstrip()+        return None, line 
src/iniconfig/_version.py +3 lines
--- +++ @@ -30,5 +30,5 @@ -__version__ = version = '2.2.0'-__version_tuple__ = version_tuple = (2, 2, 0)+__version__ = version = '2.3.0'+__version_tuple__ = version_tuple = (2, 3, 0) -__commit_id__ = commit_id = 'g57b7ed9c7'+__commit_id__ = commit_id = 'g7faed13ae'
testing/test_iniconfig.py +109 lines
--- +++ @@ -127,3 +127,3 @@     with pytest.raises(TypeError):-        IniConfig(data=path.read_text())  # type: ignore+        IniConfig(data=path.read_text())  # type: ignore[call-arg] @@ -306 +306,109 @@     assert iscommentline(line)+++def test_parse_strips_inline_comments() -> None:+    """Test that IniConfig.parse() strips inline comments from values by default."""+    config = IniConfig.parse(+        "test.ini",+        data=dedent(+            """+            [section1]+            name1 = value1 # this is a comment+            name2 = value2 ; this is also a comment+            name3 = value3# no space before comment+            list = a, b, c # some items+            """+        ),+    )+    assert config["section1"]["name1"] == "value1"+    assert config["section1"]["name2"] == "value2"+    assert config["section1"]["name3"] == "value3"+    assert config["section1"]["list"] == "a, b, c"+++def test_parse_strips_inline_comments_from_continuations() -> None:+    """Test that inline comments are stripped from continuation lines."""+    config = IniConfig.parse(+        "test.ini",+        data=dedent(+            """+            [section]+            names =+                Alice # first person+                Bob ; second person+                Charlie+            """+        ),+    )+    assert config["section"]["names"] == "Alice\nBob\nCharlie"+++def test_parse_preserves_inline_comments_when_disabled() -> None:+    """Test that IniConfig.parse(strip_inline_comments=False) preserves comments."""+    config = IniConfig.parse(+        "test.ini",+        data=dedent(+            """+            [section1]+            name1 = value1 # this is a comment+            name2 = value2 ; this is also a comment+            list = a, b, c # some items+            """+        ),+        strip_inline_comments=False,+    )+    assert config["section1"]["name1"] == "value1 # this is a comment"+    assert config["section1"]["name2"] == "value2 ; this is also a comment"+    assert config["section1"]["list"] == "a, b, c # some items"+++def test_constructor_preserves_inline_comments_for_backward_compatibility() -> None:+    """Test that IniConfig() constructor preserves old behavior (no stripping)."""+    config = IniConfig(+        "test.ini",+        data=dedent(+            """+            [section1]+            name1 = value1 # this is a comment+            name2 = value2 ; this is also a comment+            """+        ),+    )+    assert config["section1"]["name1"] == "value1 # this is a comment"+    assert config["section1"]["name2"] == "value2 ; this is also a comment"+++def test_unicode_whitespace_stripped() -> None:+    """Test that Unicode whitespace is stripped (issue #4)."""+    config = IniConfig(+        "test.ini",+        data="[section]\n"+        + "name1 = \u00a0value1\u00a0\n"  # NO-BREAK SPACE+        + "name2 = \u2000value2\u2000\n"  # EN QUAD+        + "name3 = \u3000value3\u3000\n",  # IDEOGRAPHIC SPACE+    )+    assert config["section"]["name1"] == "value1"+    assert config["section"]["name2"] == "value2"+    assert config["section"]["name3"] == "value3"+++def test_unicode_whitespace_in_section_names_with_opt_in() -> None:+    """Test that Unicode whitespace can be stripped from section names with opt-in (issue #4)."""+    config = IniConfig.parse(+        "test.ini",+        data="[section\u00a0]\n"  # NO-BREAK SPACE at end+        + "key = value\n",+        strip_section_whitespace=True,+    )+    assert "section" in config+    assert config["section"]["key"] == "value"+++def test_unicode_whitespace_in_key_names() -> None:+    """Test that Unicode whitespace is stripped from key names (issue #4)."""+    config = IniConfig(+        "test.ini",+        data="[section]\n" + "key\u00a0 = value\n",  # NO-BREAK SPACE after key+    )+    assert "key" in config["section"]+    assert config["section"]["key"] == "value"
pycparser pypi
3.0 7mo ago nominal
no findings
latest 3.0 versions 24 maintainers 1
2.13
2.14
2.15
2.16
2.17
2.18
2.19
2.20
2.21
2.22
2.23
3.0
CLEAN
no findings — nominal
release diff 2.23 → 3.0
+1 added · -11 removed · ~33 modified
+4 more files not shown
setup.py +2 lines · 1 flagged
--- +++ @@ -1,67 +1,3 @@-import os, sys-try:-    from setuptools import setup-    from setuptools.command.install import install as _install-    from setuptools.command.sdist import sdist as _sdist-except ImportError:-    from distutils.core import setup-    from distutils.command.install import install as _install-    from distutils.command.sdist import sdist as _sdist+from setuptools import setup --def _run_build_tables(dir):-    from subprocess import check_call-    # This is run inside the install staging directory (that had no .pyc files)-    # We don't want to generate any.-    # https://github.com/eliben/pycparser/pull/135-    check_call([sys.executable, '-B', '_build_tables.py'],-               cwd=os.path.join(dir, 'pycparser'))---class install(_install):-    def run(self):-        _install.run(self)-        self.execute(_run_build_tables, (self.install_lib,),-                     msg="Build the lexing/parsing tables")---class sdist(_sdist):-    def make_release_tree(self, basedir, files):-        _sdist.make_release_tree(self, basedir, files)-        self.execute(_run_build_tables, (basedir,),-                     msg="Build the lexing/parsing tables")---setup(-    # metadata-    name='pycparser',-    description='C parser in Python',-    long_description="""-        pycparser is a complete parser of the C language, written in-        pure Python using the PLY parsing library.-        It parses C code into an AST and can serve as a front-end for-        C compilers or analysis tools.-    """,-    license='BSD-3-Clause',-    version='2.23',-    author='Eli Bendersky',-    maintainer='Eli Bendersky',-    author_email='[email protected]',-    url='https://github.com/eliben/pycparser',-    platforms='Cross Platform',-    classifiers = [-        'Development Status :: 5 - Production/Stable',-        'License :: OSI Approved :: BSD License',-        'Programming Language :: Python :: 3',-        'Programming Language :: Python :: 3.8',-        'Programming Language :: Python :: 3.9',-        'Programming Language :: Python :: 3.10',-        'Programming Language :: Python :: 3.11',-        'Programming Language :: Python :: 3.12',-        'Programming Language :: Python :: 3.13',-    ],-    python_requires=">=3.8",-    packages=['pycparser', 'pycparser.ply'],-    package_data={'pycparser': ['*.cfg']},-    cmdclass={'install': install, 'sdist': sdist},-)+setup()
examples/c-to-c.py +5 lines
--- +++ @@ -1,2 +1,2 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: c-to-c.py@@ -8,3 +8,3 @@ # License: BSD-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ import sys@@ -13,3 +13,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -18,5 +18,4 @@ -def translate_to_c(filename):-    """ Simply use the c_generator module to emit a parsed AST.-    """+def translate_to_c(filename: str) -> None:+    """Simply use the c_generator module to emit a parsed AST."""     ast = parse_file(filename, use_cpp=True)
examples/c_json.py +71 lines
--- +++ @@ -1,2 +1,2 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: c_json.py@@ -35,3 +35,3 @@ #     }-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ import json@@ -39,2 +39,3 @@ import re+from typing import Any, Callable, Dict, Optional, Set, TypeVar @@ -42,10 +43,10 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."])  from pycparser import parse_file, c_ast-from pycparser.plyparser import Coord---RE_CHILD_ARRAY = re.compile(r'(.*)\[(.*)\]')-RE_INTERNAL_ATTR = re.compile('__.*__')+from pycparser.c_parser import Coord+++RE_CHILD_ARRAY = re.compile(r"(.*)\[(.*)\]")+RE_INTERNAL_ATTR = re.compile("__.*__") @@ -56,9 +57,18 @@ -def memodict(fn):-    """ Fast memoization decorator for a function taking a single argument """-    class memodict(dict):-        def __missing__(self, key):-            ret = self[key] = fn(key)-            return ret-    return memodict().__getitem__+_T = TypeVar("_T")+_R = TypeVar("_R")+++def memodict(fn: Callable[[_T], _R]) -> Callable[[_T], _R]:+    """Fast memoization decorator for a function taking a single argument"""+    cache: Dict[_T, _R] = {}++    def memoized(arg: _T) -> _R:+        if arg in cache:+            return cache[arg]+        result = fn(arg)+        cache[arg] = result+        return result++    return memoized @@ -66,3 +76,3 @@ @memodict-def child_attrs_of(klass):+def child_attrs_of(klass: type[c_ast.Node]) -> Set[str]:     """@@ -77,10 +87,10 @@ -def to_dict(node):-    """ Recursively convert an ast into dict representation. """+def to_dict(node: c_ast.Node) -> Dict[str, Any]:+    """Recursively convert an ast into dict representation."""     klass = node.__class__ -    result = {}+    result: Dict[str, Any] = {}      # Metadata-    result['_nodetype'] = klass.__name__+    result["_nodetype"] = klass.__name__ @@ -92,5 +102,5 @@     if node.coord:-        result['coord'] = str(node.coord)+        result["coord"] = str(node.coord)     else:-        result['coord'] = None+        result["coord"] = None @@ -106,5 +116,8 @@             if array_index != len(result[array_name]):-                raise CJsonError('Internal ast error. Array {} out of order. '-                    'Expected index {}, got {}'.format(-                    array_name, len(result[array_name]), array_index))+                raise CJsonError(+                    "Internal ast error. Array {} out of order. "+                    "Expected index {}, got {}".format(+                        array_name, len(result[array_name]), array_index+                    )+                )             result[array_name].append(to_dict(child))@@ -121,4 +134,4 @@ -def to_json(node, **kwargs):-    """ Convert ast node to json string """+def to_json(node: c_ast.Node, **kwargs: Any) -> str:+    """Convert ast node to json string"""     return json.dumps(to_dict(node), **kwargs)@@ -126,4 +139,4 @@ -def file_to_dict(filename):-    """ Load C file into dict representation of ast """+def file_to_dict(filename: str) -> Dict[str, Any]:+    """Load C file into dict representation of ast"""     ast = parse_file(filename, use_cpp=True)@@ -132,4 +145,4 @@ -def file_to_json(filename, **kwargs):-    """ Load C file into json string representation of ast """+def file_to_json(filename: str, **kwargs: Any) -> str:+    """Load C file into json string representation of ast"""     ast = parse_file(filename, use_cpp=True)@@ -138,4 +151,4 @@ -def _parse_coord(coord_str):-    """ Parse coord string (file:line[:column]) into Coord object. """+def _parse_coord(coord_str: Optional[str]) -> Optional[Coord]:+    """Parse coord string (file:line[:column]) into Coord object."""     if coord_str is None:@@ -143,9 +156,11 @@ -    vals = coord_str.split(':')-    vals.extend([None] * 3)+    vals = coord_str.split(":")+    vals.extend(["", "", ""])     filename, line, column = vals[:3]-    return Coord(filename, line, column)---def _convert_to_obj(value):+    line_num = int(line) if line else 0+    column_num = int(column) if column else None+    return Coord(filename, line_num, column_num)+++def _convert_to_obj(value: Any) -> Any:     """@@ -155,15 +170,15 @@     """-    value_type = type(value)-    if value_type == dict:-        return from_dict(value)-    elif value_type == list:-        return [_convert_to_obj(item) for item in value]-    else:-        # String-        return value---def from_dict(node_dict):-    """ Recursively build an ast from dict representation """-    class_name = node_dict.pop('_nodetype')+    match value:+        case dict():+            return from_dict(value)+        case list():+            return [_convert_to_obj(item) for item in value]+        case _:+            # String+            return value+++def from_dict(node_dict: Dict[str, Any]) -> c_ast.Node:+    """Recursively build an ast from dict representation"""+    class_name = node_dict.pop("_nodetype") @@ -175,3 +190,3 @@     for key, value in node_dict.items():-        if key == 'coord':+        if key == "coord":             objs[key] = _parse_coord(value)@@ -185,4 +200,4 @@ -def from_json(ast_json):-    """ Build an ast from json string representation """+def from_json(ast_json: str) -> c_ast.Node:+    """Build an ast from json string representation"""     return from_dict(json.loads(ast_json))@@ -190,3 +205,3 @@ -#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ if __name__ == "__main__":
examples/cdecl.py +118 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: cdecl.py@@ -33,5 +33,6 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import copy import sys+from typing import Optional @@ -39,3 +40,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -44,11 +45,13 @@ -def explain_c_declaration(c_decl, expand_struct=False, expand_typedef=False):-    """ Parses the declaration in c_decl and returns a text-        explanation as a string.--        The last external node of the string is used, to allow earlier typedefs-        for used types.--        expand_struct=True will spell out struct definitions recursively.-        expand_typedef=True will expand typedef'd types.+def explain_c_declaration(+    c_decl: str, expand_struct: bool = False, expand_typedef: bool = False+) -> str:+    """Parses the declaration in c_decl and returns a text+    explanation as a string.++    The last external node of the string is used, to allow earlier typedefs+    for used types.++    expand_struct=True will spell out struct definitions recursively.+    expand_typedef=True will expand typedef'd types.     """@@ -57,3 +60,3 @@     try:-        node = parser.parse(c_decl, filename='<stdin>')+        node = parser.parse(c_decl, filename="<stdin>")     except c_parser.ParseError:@@ -62,5 +65,3 @@ -    if (not isinstance(node, c_ast.FileAST) or-        not isinstance(node.ext[-1], c_ast.Decl)-        ):+    if not isinstance(node, c_ast.FileAST) or not isinstance(node.ext[-1], c_ast.Decl):         return "Not a valid declaration"@@ -68,5 +69,8 @@     try:-        expanded = expand_struct_typedef(node.ext[-1], node,-                                         expand_struct=expand_struct,-                                         expand_typedef=expand_typedef)+        expanded = expand_struct_typedef(+            node.ext[-1],+            node,+            expand_struct=expand_struct,+            expand_typedef=expand_typedef,+        )     except Exception as e:@@ -77,56 +81,52 @@ -def _explain_decl_node(decl_node):-    """ Receives a c_ast.Decl note and returns its explanation in-        English.+def _explain_decl_node(decl_node: c_ast.Decl) -> str:+    """Receives a c_ast.Decl note and returns its explanation in+    English.     """-    storage = ' '.join(decl_node.storage) + ' ' if decl_node.storage else ''--    return (decl_node.name +-            " is a " +-            storage +-            _explain_type(decl_node.type))---def _explain_type(decl):-    """ Recursively explains a type decl node-    """-    typ = type(decl)--    if typ == c_ast.TypeDecl:-        quals = ' '.join(decl.quals) + ' ' if decl.quals else ''-        return quals + _explain_type(decl.type)-    elif typ == c_ast.Typename or typ == c_ast.Decl:-        return _explain_type(decl.type)-    elif typ == c_ast.IdentifierType:-        return ' '.join(decl.names)-    elif typ == c_ast.PtrDecl:-        quals = ' '.join(decl.quals) + ' ' if decl.quals else ''-        return quals + 'pointer to ' + _explain_type(decl.type)-    elif typ == c_ast.ArrayDecl:-        arr = 'array'-        if decl.dim: arr += '[%s]' % decl.dim.value--        return arr + " of " + _explain_type(decl.type)--    elif typ == c_ast.FuncDecl:-        if decl.args:-            params = [_explain_type(param) for param in decl.args.params]-            args = ', '.join(params)-        else:-            args = ''--        return ('function(%s) returning ' % (args) +-                _explain_type(decl.type))--    elif typ == c_ast.Struct:-        decls = [_explain_decl_node(mem_decl) for mem_decl in decl.decls]-        members = ', '.join(decls)--        return ('struct%s ' % (' ' + decl.name if decl.name else '') +-                ('containing {%s}' % members if members else ''))---def expand_struct_typedef(cdecl, file_ast,-                          expand_struct=False,-                          expand_typedef=False):+    storage = " ".join(decl_node.storage) + " " if decl_node.storage else ""++    return decl_node.name + " is a " + storage + _explain_type(decl_node.type)+++def _explain_type(decl: c_ast.Node) -> str:+    """Recursively explains a type decl node"""+    match decl:+        case c_ast.TypeDecl():+            quals = " ".join(decl.quals) + " " if decl.quals else ""+            return quals + _explain_type(decl.type)+        case c_ast.Typename() | c_ast.Decl():+            return _explain_type(decl.type)+        case c_ast.IdentifierType():+            return " ".join(decl.names)+        case c_ast.PtrDecl():+            quals = " ".join(decl.quals) + " " if decl.quals else ""+            return quals + "pointer to " + _explain_type(decl.type)+        case c_ast.ArrayDecl():+            arr = "array"+            if decl.dim is not None:+                arr += f"[{decl.dim.value}]"+            return arr + " of " + _explain_type(decl.type)+        case c_ast.FuncDecl():+            if decl.args is not None:+                params = [_explain_type(param) for param in decl.args.params]+                args = ", ".join(params)+            else:+                args = ""+            return f"function({args}) returning " + _explain_type(decl.type)+        case c_ast.Struct():+            decls = [_explain_decl_node(mem_decl) for mem_decl in decl.decls]+            members = ", ".join(decls)+            struct_name = f" {decl.name}" if decl.name else ""+            contents = f"containing {{{members}}}" if members else ""+            return f"struct{struct_name} " + contents+        case _:+            return ""+++def expand_struct_typedef(+    cdecl: c_ast.Decl,+    file_ast: c_ast.FileAST,+    expand_struct: bool = False,+    expand_typedef: bool = False,+) -> c_ast.Decl:     """Expand struct & typedef and return a new expanded node."""@@ -137,33 +137,37 @@ -def _expand_in_place(decl, file_ast, expand_struct=False, expand_typedef=False):+def _expand_in_place(+    decl: c_ast.Node,+    file_ast: c_ast.FileAST,+    expand_struct: bool = False,+    expand_typedef: bool = False,+) -> c_ast.Node:     """Recursively expand struct & typedef in place, throw RuntimeError if-       undeclared struct or typedef are used+    undeclared struct or typedef are used     """-    typ = type(decl)--    if typ in (c_ast.Decl, c_ast.TypeDecl, c_ast.PtrDecl, c_ast.ArrayDecl):-        decl.type = _expand_in_place(decl.type, file_ast, expand_struct,-                                     expand_typedef)--    elif typ == c_ast.Struct:-        if not decl.decls:-            struct = _find_struct(decl.name, file_ast)-            if not struct:-                raise RuntimeError('using undeclared struct %s' % decl.name)-            decl.decls = struct.decls--        for i, mem_decl in enumerate(decl.decls):-            decl.decls[i] = _expand_in_place(mem_decl, file_ast, expand_struct,-                                             expand_typedef)-        if not expand_struct:-            decl.decls = []--    elif (typ == c_ast.IdentifierType and-          decl.names[0] not in ('int', 'char')):-        typedef = _find_typedef(decl.names[0], file_ast)-        if not typedef:-            raise RuntimeError('using undeclared type %s' % decl.names[0])--        if expand_typedef:-            return typedef.type+    match decl:+        case c_ast.Decl() | c_ast.TypeDecl() | c_ast.PtrDecl() | c_ast.ArrayDecl():+            decl.type = _expand_in_place(+                decl.type, file_ast, expand_struct, expand_typedef+            )+        case c_ast.Struct():+            if not decl.decls:+                struct = _find_struct(decl.name, file_ast)+                if struct is None:+                    raise RuntimeError(f"using undeclared struct {decl.name}")+                decl.decls = struct.decls++            for i, mem_decl in enumerate(decl.decls):+                decl.decls[i] = _expand_in_place(+                    mem_decl, file_ast, expand_struct, expand_typedef+                )+            if not expand_struct:+                decl.decls = []+        case c_ast.IdentifierType() if decl.names[0] not in ("int", "char"):+            typedef = _find_typedef(decl.names[0], file_ast)+            if typedef is None:+                raise RuntimeError(f"using undeclared type {decl.names[0]}")+            if expand_typedef:+                return typedef.type+        case _:+            pass @@ -172,18 +176,17 @@ -def _find_struct(name, file_ast):-    """Receives a struct name and return declared struct object in file_ast-    """+def _find_struct(name: str, file_ast: c_ast.FileAST) -> Optional[c_ast.Struct]:+    """Receives a struct name and return declared struct object in file_ast"""     for node in file_ast.ext:-        if (type(node) == c_ast.Decl and-           type(node.type) == c_ast.Struct and-           node.type.name == name):
… 25 more lines (truncated)
examples/construct_ast_from_scratch.py +23 lines
--- +++ @@ -12,3 +12,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -23,16 +23,23 @@ -def empty_main_function_ast():-    constant_zero = c_ast.Constant(type='int', value='0')+def empty_main_function_ast() -> c_ast.FuncDef:+    constant_zero = c_ast.Constant(type="int", value="0")     return_node = c_ast.Return(expr=constant_zero)     compound_node = c_ast.Compound(block_items=[return_node])-    type_decl_node = c_ast.TypeDecl(declname='main', quals=[],-                                    type=c_ast.IdentifierType(names=['int']),-                                    align=[])-    func_decl_node = c_ast.FuncDecl(args=c_ast.ParamList([]),-                                    type=type_decl_node)-    func_def_node = c_ast.Decl(name='main', quals=[], storage=[], funcspec=[],-                               type=func_decl_node, init=None,-                               bitsize=None, align=[])-    main_func_node = c_ast.FuncDef(decl=func_def_node, param_decls=None,-                                   body=compound_node)+    type_decl_node = c_ast.TypeDecl(+        declname="main", quals=[], type=c_ast.IdentifierType(names=["int"]), align=[]+    )+    func_decl_node = c_ast.FuncDecl(args=c_ast.ParamList([]), type=type_decl_node)+    func_def_node = c_ast.Decl(+        name="main",+        quals=[],+        storage=[],+        funcspec=[],+        type=func_decl_node,+        init=None,+        bitsize=None,+        align=[],+    )+    main_func_node = c_ast.FuncDef(+        decl=func_def_node, param_decls=None, body=compound_node+    ) @@ -41,3 +48,3 @@ -def generate_c_code(my_ast):+def generate_c_code(my_ast: c_ast.Node) -> str:     generator = c_generator.CGenerator()@@ -46,3 +53,3 @@ -if __name__ == '__main__':+if __name__ == "__main__":     main_function_ast = empty_main_function_ast()@@ -52,2 +59,2 @@     main_c_code = generate_c_code(main_function_ast)-    print("C code: \n%s" % main_c_code)+    print(f"C code: \n{main_c_code}")
examples/dump_ast.py +13 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: dump_ast.py@@ -7,3 +7,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import argparse@@ -13,3 +13,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -18,9 +18,12 @@ if __name__ == "__main__":-    argparser = argparse.ArgumentParser('Dump AST')-    argparser.add_argument('filename',-                           default='examples/c_files/basic.c',-                           nargs='?',-                           help='name of file to parse')-    argparser.add_argument('--coord', help='show coordinates in the dump',-                           action='store_true')+    argparser = argparse.ArgumentParser("Dump AST")+    argparser.add_argument(+        "filename",+        default="examples/c_files/basic.c",+        nargs="?",+        help="name of file to parse",+    )+    argparser.add_argument(+        "--coord", help="show coordinates in the dump", action="store_true"+    )     args = argparser.parse_args()
examples/explore_ast.py +20 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: explore_ast.py@@ -13,3 +13,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys@@ -18,3 +18,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -60,3 +60,3 @@ parser = c_parser.CParser()-ast = parser.parse(text, filename='<none>')+ast = parser.parse(text, filename="<none>") @@ -67,3 +67,3 @@ -#ast.show(showcoord=True)+# ast.show(showcoord=True) @@ -80,3 +80,3 @@ -#ast.ext[2].show()+# ast.ext[2].show() @@ -92,4 +92,4 @@ -#function_decl.type.show()-#function_decl.type.args.show()+# function_decl.type.show()+# function_decl.type.args.show() @@ -97,6 +97,6 @@ -#for param_decl in function_decl.type.args.params:-    #print('Arg name: %s' % param_decl.name)-    #print('Type:')-    #param_decl.type.show(offset=6)+# for param_decl in function_decl.type.args.params:+# print(f"Arg name: {param_decl.name}")+# print('Type:')+# param_decl.type.show(offset=6) @@ -112,4 +112,4 @@ -#for decl in function_body.block_items:-    #decl.show()+# for decl in function_body.block_items:+# decl.show() @@ -121,3 +121,3 @@ for_stmt = function_body.block_items[2]-#for_stmt.show()+# for_stmt.show() @@ -131,3 +131,3 @@ while_stmt = for_stmt.stmt.block_items[1]-#while_stmt.show()+# while_stmt.show() @@ -137,3 +137,3 @@ while_cond = while_stmt.cond-#while_cond.show()+# while_cond.show() @@ -144,5 +144,5 @@ -#print(while_cond.op)-#while_cond.left.show()-#while_cond.right.show()+# print(while_cond.op)+# while_cond.left.show()+# while_cond.right.show() 
examples/func_calls.py +12 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: func_calls.py@@ -8,3 +8,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys@@ -13,3 +13,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -17,12 +17,13 @@ + # A visitor with some state information (the funcname it's looking for) class FuncCallVisitor(c_ast.NodeVisitor):-    def __init__(self, funcname):+    def __init__(self, funcname: str) -> None:         self.funcname = funcname -    def visit_FuncCall(self, node):-        if node.name.name == self.funcname:-            print('%s called at %s' % (self.funcname, node.name.coord))+    def visit_FuncCall(self, node: c_ast.FuncCall) -> None:+        if isinstance(node.name, c_ast.ID) and node.name.name == self.funcname:+            print(f"{self.funcname} called at {node.name.coord}")         # Visit args in case they contain more func calls.-        if node.args:+        if node.args is not None:             self.visit(node.args)@@ -30,3 +31,3 @@ -def show_func_calls(filename, funcname):+def show_func_calls(filename: str, funcname: str) -> None:     ast = parse_file(filename, use_cpp=True)@@ -41,4 +42,4 @@     else:-        filename = 'examples/c_files/basic.c'-        func = 'foo'+        filename = "examples/c_files/basic.c"+        func = "foo" 
examples/func_defs.py +9 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: func_defs.py@@ -11,3 +11,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys@@ -16,3 +16,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -24,11 +24,10 @@ class FuncDefVisitor(c_ast.NodeVisitor):-    def visit_FuncDef(self, node):-        print('%s at %s' % (node.decl.name, node.decl.coord))+    def visit_FuncDef(self, node: c_ast.FuncDef) -> None:+        print(f"{node.decl.name} at {node.decl.coord}")  -def show_func_defs(filename):+def show_func_defs(filename: str) -> None:     # Note that cpp is used. Provide a path to your own cpp or     # make sure one exists in PATH.-    ast = parse_file(filename, use_cpp=True,-                     cpp_args=r'-Iutils/fake_libc_include')+    ast = parse_file(filename, use_cpp=True, cpp_args=r"-Iutils/fake_libc_include") @@ -40,5 +39,5 @@     if len(sys.argv) > 1:-        filename  = sys.argv[1]+        filename = sys.argv[1]     else:-        filename = 'examples/c_files/memmgr.c'+        filename = "examples/c_files/memmgr.c" 
examples/func_defs_add_param.py +20 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: func_defs_add_param.py@@ -8,5 +8,6 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys-sys.path.extend(['.', '..'])++sys.path.extend([".", ".."]) @@ -24,18 +25,18 @@ class ParamAdder(c_ast.NodeVisitor):-    def visit_FuncDecl(self, node):-        ty = c_ast.TypeDecl(declname='_hidden',-                            quals=[],-                            align=[],-                            type=c_ast.IdentifierType(['int']))+    def visit_FuncDecl(self, node: c_ast.FuncDecl) -> None:+        ty = c_ast.TypeDecl(+            declname="_hidden", quals=[], align=[], type=c_ast.IdentifierType(["int"])+        )         newdecl = c_ast.Decl(-                    name='_hidden',-                    quals=[],-                    align=[],-                    storage=[],-                    funcspec=[],-                    type=ty,-                    init=None,-                    bitsize=None,-                    coord=node.coord)-        if node.args:+            name="_hidden",+            quals=[],+            align=[],+            storage=[],+            funcspec=[],+            type=ty,+            init=None,+            bitsize=None,+            coord=node.coord,+        )+        if node.args is not None:             node.args.params.append(newdecl)@@ -45,3 +46,3 @@ -if __name__ == '__main__':+if __name__ == "__main__":     parser = c_parser.CParser()
examples/rewrite_ast.py +4 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: rewrite_ast.py@@ -7,6 +7,6 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys -sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) from pycparser import c_parser@@ -20,3 +20,3 @@ -if __name__ == '__main__':+if __name__ == "__main__":     parser = c_parser.CParser()
examples/serialize_ast.py +9 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: serialize_ast.py@@ -8,7 +8,8 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import pickle import sys+import tempfile -sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) from pycparser import c_parser@@ -22,12 +23,12 @@ -if __name__ == '__main__':+if __name__ == "__main__":     parser = c_parser.CParser()     ast = parser.parse(text)-    dump_filename = 'ast.pickle'--    with open(dump_filename, 'wb') as f:+    with tempfile.NamedTemporaryFile(delete=False, suffix=".pickle") as f:+        dump_filename = f.name         pickle.dump(ast, f, protocol=pickle.HIGHEST_PROTOCOL)+        print(f"Dumped to {dump_filename}")      # Deserialize.-    with open(dump_filename, 'rb') as f:+    with open(dump_filename, "rb") as f:         ast = pickle.load(f)
examples/using_cpp_libc.py +8 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: using_cpp_libc.py@@ -8,3 +8,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- import sys@@ -13,3 +13,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -20,9 +20,9 @@     if len(sys.argv) > 1:-        filename  = sys.argv[1]+        filename = sys.argv[1]     else:-        filename = 'examples/c_files/year.c'+        filename = "examples/c_files/year.c" -    ast = parse_file(filename, use_cpp=True,-            cpp_path='cpp',-            cpp_args=r'-Iutils/fake_libc_include')+    ast = parse_file(+        filename, use_cpp=True, cpp_path="cpp", cpp_args=r"-Iutils/fake_libc_include"+    )     ast.show()
examples/using_gcc_E_libc.py +11 lines
--- +++ @@ -1,2 +1,2 @@-#-------------------------------------------------------------------------------+# ------------------------------------------------------------------------------- # pycparser: using_gcc_E_libc.py@@ -9,3 +9,3 @@ # License: BSD-#-------------------------------------------------------------------------------+# ------------------------------------------------------------------------------- import sys@@ -14,3 +14,3 @@ # your site-packages/ with setup.py-sys.path.extend(['.', '..'])+sys.path.extend([".", ".."]) @@ -21,9 +21,12 @@     if len(sys.argv) > 1:-        filename  = sys.argv[1]+        filename = sys.argv[1]     else:-        filename = 'examples/c_files/year.c'+        filename = "examples/c_files/year.c" -    ast = parse_file(filename, use_cpp=True,-            cpp_path='gcc',-            cpp_args=['-E', r'-Iutils/fake_libc_include'])+    ast = parse_file(+        filename,+        use_cpp=True,+        cpp_path="gcc",+        cpp_args=["-E", r"-Iutils/fake_libc_include"],+    )     ast.show()
pycparser/__init__.py +50 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # pycparser: __init__.py@@ -8,5 +8,5 @@ # License: BSD-#------------------------------------------------------------------__all__ = ['c_lexer', 'c_parser', 'c_ast']-__version__ = '2.23'+# -----------------------------------------------------------------+__all__ = ["c_lexer", "c_parser", "c_ast"]+__version__ = "3.00" @@ -14,18 +14,21 @@ from subprocess import check_output-from .c_parser import CParser++from . import c_parser++CParser = c_parser.CParser  -def preprocess_file(filename, cpp_path='cpp', cpp_args=''):-    """ Preprocess a file using cpp.+def preprocess_file(filename, cpp_path="cpp", cpp_args=""):+    """Preprocess a file using cpp. -        filename:-            Name of the file you want to preprocess.+    filename:+        Name of the file you want to preprocess. -        cpp_path:-        cpp_args:-            Refer to the documentation of parse_file for the meaning of these-            arguments.+    cpp_path:+    cpp_args:+        Refer to the documentation of parse_file for the meaning of these+        arguments. -        When successful, returns the preprocessed file's contents.-        Errors from cpp will be printed out.+    When successful, returns the preprocessed file's contents.+    Errors from cpp will be printed out.     """@@ -34,3 +37,3 @@         path_list += cpp_args-    elif cpp_args != '':+    elif cpp_args != "":         path_list += [cpp_args]@@ -43,5 +46,7 @@     except OSError as e:-        raise RuntimeError("Unable to invoke 'cpp'.  " +-            'Make sure its path was passed correctly\n' +-            ('Original error: %s' % e))+        raise RuntimeError(+            "Unable to invoke 'cpp'.  "+            + "Make sure its path was passed correctly\n"+            + f"Original error: {e}"+        ) @@ -50,35 +55,36 @@ -def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',-               parser=None, encoding=None):-    """ Parse a C file using pycparser.+def parse_file(+    filename, use_cpp=False, cpp_path="cpp", cpp_args="", parser=None, encoding=None+):+    """Parse a C file using pycparser. -        filename:-            Name of the file you want to parse.+    filename:+        Name of the file you want to parse. -        use_cpp:-            Set to True if you want to execute the C pre-processor-            on the file prior to parsing it.+    use_cpp:+        Set to True if you want to execute the C pre-processor+        on the file prior to parsing it. -        cpp_path:-            If use_cpp is True, this is the path to 'cpp' on your-            system. If no path is provided, it attempts to just-            execute 'cpp', so it must be in your PATH.+    cpp_path:+        If use_cpp is True, this is the path to 'cpp' on your+        system. If no path is provided, it attempts to just+        execute 'cpp', so it must be in your PATH. -        cpp_args:-            If use_cpp is True, set this to the command line arguments strings-            to cpp. Be careful with quotes - it's best to pass a raw string-            (r'') here. For example:-            r'-I../utils/fake_libc_include'-            If several arguments are required, pass a list of strings.+    cpp_args:+        If use_cpp is True, set this to the command line arguments strings+        to cpp. Be careful with quotes - it's best to pass a raw string+        (r'') here. For example:+        r'-I../utils/fake_libc_include'+        If several arguments are required, pass a list of strings. -        encoding:-            Encoding to use for the file to parse+    encoding:+        Encoding to use for the file to parse -        parser:-            Optional parser object to be used instead of the default CParser+    parser:+        Optional parser object to be used instead of the default CParser -        When successful, an AST is returned. ParseError can be-        thrown if the file doesn't parse successfully.+    When successful, an AST is returned. ParseError can be+    thrown if the file doesn't parse successfully. -        Errors from cpp will be printed out.+    Errors from cpp will be printed out.     """
pycparser/_ast_gen.py +116 lines
--- +++ @@ -1,2 +1,2 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # _ast_gen.py@@ -4,3 +4,6 @@ # Generates the AST Node classes from a specification given in-# a configuration file+# a configuration file. This module can also be run as a script to+# regenerate c_ast.py from _c_ast.cfg (from the repo root or the+# pycparser/ directory). Use 'make check' to reformat the generated+# file after running this script. #@@ -11,20 +14,22 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- from string import Template---class ASTCodeGenerator(object):-    def __init__(self, cfg_filename='_c_ast.cfg'):-        """ Initialize the code generator from a configuration-            file.+import os+from typing import IO+++class ASTCodeGenerator:+    def __init__(self, cfg_filename="_c_ast.cfg"):+        """Initialize the code generator from a configuration+        file.         """         self.cfg_filename = cfg_filename-        self.node_cfg = [NodeCfg(name, contents)-            for (name, contents) in self.parse_cfgfile(cfg_filename)]--    def generate(self, file=None):-        """ Generates the code into file, an open file buffer.-        """-        src = Template(_PROLOGUE_COMMENT).substitute(-            cfg_filename=self.cfg_filename)+        self.node_cfg = [+            NodeCfg(name, contents)+            for (name, contents) in self.parse_cfgfile(cfg_filename)+        ]++    def generate(self, file: IO[str]) -> None:+        """Generates the code into file, an open file buffer."""+        src = Template(_PROLOGUE_COMMENT).substitute(cfg_filename=self.cfg_filename) @@ -32,3 +37,3 @@         for node_cfg in self.node_cfg:-            src += node_cfg.generate_source() + '\n\n'+            src += node_cfg.generate_source() + "\n\n" @@ -37,4 +42,4 @@     def parse_cfgfile(self, filename):-        """ Parse the configuration file and yield pairs of-            (name, contents) for each node.+        """Parse the configuration file and yield pairs of+        (name, contents) for each node.         """@@ -43,13 +48,13 @@                 line = line.strip()-                if not line or line.startswith('#'):+                if not line or line.startswith("#"):                     continue-                colon_i = line.find(':')-                lbracket_i = line.find('[')-                rbracket_i = line.find(']')+                colon_i = line.find(":")+                lbracket_i = line.find("[")+                rbracket_i = line.find("]")                 if colon_i < 1 or lbracket_i <= colon_i or rbracket_i <= lbracket_i:-                    raise RuntimeError("Invalid line in %s:\n%s\n" % (filename, line))+                    raise RuntimeError(f"Invalid line in {filename}:\n{line}\n")                  name = line[:colon_i]-                val = line[lbracket_i + 1:rbracket_i]-                vallist = [v.strip() for v in val.split(',')] if val else []+                val = line[lbracket_i + 1 : rbracket_i]+                vallist = [v.strip() for v in val.split(",")] if val else []                 yield name, vallist@@ -57,8 +62,8 @@ -class NodeCfg(object):-    """ Node configuration.--        name: node name-        contents: a list of contents - attributes and child nodes-        See comment at the top of the configuration file for details.+class NodeCfg:+    """Node configuration.++    name: node name+    contents: a list of contents - attributes and child nodes+    See comment at the top of the configuration file for details.     """@@ -73,8 +78,8 @@         for entry in contents:-            clean_entry = entry.rstrip('*')+            clean_entry = entry.rstrip("*")             self.all_entries.append(clean_entry) -            if entry.endswith('**'):+            if entry.endswith("**"):                 self.seq_child.append(clean_entry)-            elif entry.endswith('*'):+            elif entry.endswith("*"):                 self.child.append(clean_entry)@@ -85,5 +90,5 @@         src = self._gen_init()-        src += '\n' + self._gen_children()-        src += '\n' + self._gen_iter()-        src += '\n' + self._gen_attr_names()+        src += "\n" + self._gen_children()+        src += "\n" + self._gen_iter()+        src += "\n" + self._gen_attr_names()         return src@@ -91,18 +96,18 @@     def _gen_init(self):-        src = "class %s(Node):\n" % self.name+        src = f"class {self.name}(Node):\n"          if self.all_entries:-            args = ', '.join(self.all_entries)-            slots = ', '.join("'{0}'".format(e) for e in self.all_entries)+            args = ", ".join(self.all_entries)+            slots = ", ".join(f"'{e}'" for e in self.all_entries)             slots += ", 'coord', '__weakref__'"-            arglist = '(self, %s, coord=None)' % args+            arglist = f"(self, {args}, coord=None)"         else:             slots = "'coord', '__weakref__'"-            arglist = '(self, coord=None)'--        src += "    __slots__ = (%s)\n" % slots-        src += "    def __init__%s:\n" % arglist--        for name in self.all_entries + ['coord']:-            src += "        self.%s = %s\n" % (name, name)+            arglist = "(self, coord=None)"++        src += f"    __slots__ = ({slots})\n"+        src += f"    def __init__{arglist}:\n"++        for name in self.all_entries + ["coord"]:+            src += f"        self.{name} = {name}\n" @@ -111,22 +116,18 @@     def _gen_children(self):-        src = '    def children(self):\n'+        src = "    def children(self):\n"          if self.all_entries:-            src += '        nodelist = []\n'+            src += "        nodelist = []\n"              for child in self.child:-                src += (-                    '        if self.%(child)s is not None:' +-                    ' nodelist.append(("%(child)s", self.%(child)s))\n') % (-                        dict(child=child))+                src += f"        if self.{child} is not None:\n"+                src += f'            nodelist.append(("{child}", self.{child}))\n'              for seq_child in self.seq_child:-                src += (-                    '        for i, child in enumerate(self.%(child)s or []):\n'-                    '            nodelist.append(("%(child)s[%%d]" %% i, child))\n') % (-                        dict(child=seq_child))--            src += '        return tuple(nodelist)\n'+                src += f"        for i, child in enumerate(self.{seq_child} or []):\n"+                src += f'            nodelist.append((f"{seq_child}[{{i}}]", child))\n'++            src += "        return tuple(nodelist)\n"         else:-            src += '        return ()\n'+            src += "        return ()\n" @@ -135,3 +136,3 @@     def _gen_iter(self):-        src = '    def __iter__(self):\n'+        src = "    def __iter__(self):\n" @@ -139,10 +140,8 @@             for child in self.child:-                src += (-                    '        if self.%(child)s is not None:\n' +-                    '            yield self.%(child)s\n') % (dict(child=child))+                src += f"        if self.{child} is not None:\n"+                src += f"            yield self.{child}\n"              for seq_child in self.seq_child:-                src += (-                    '        for child in (self.%(child)s or []):\n'-                    '            yield child\n') % (dict(child=seq_child))+                src += f"        for child in (self.{seq_child} or []):\n"+                src += "            yield child\n" @@ -150,10 +149,6 @@                 # Empty generator-                src += (-                    '        return\n' +-                    '        yield\n')+                src += "        return\n" + "        yield\n"         else:             # Empty generator-            src += (-                '        return\n' +-                '        yield\n')+            src += "        return\n" + "        yield\n" @@ -162,11 +157,9 @@     def _gen_attr_names(self):-        src = "    attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')'-        return src---_PROLOGUE_COMMENT = \-r'''#-----------------------------------------------------------------+        src = "    attr_names = (" + "".join(f"{nm!r}, " for nm in self.attr) + ")"+        return src+++_PROLOGUE_COMMENT = r"""#----------------------------------------------------------------- # ** ATTENTION **-# This code was automatically generated from the file:-# $cfg_filename+# This code was automatically generated from _c_ast.cfg #@@ -184,6 +177,6 @@ -'''-+""" _PROLOGUE_CODE = r''' import sys+from typing import Any, ClassVar, IO, Optional @@ -198,3 +191,3 @@ -class Node(object):+class Node:     __slots__ = ()@@ -202,2 +195,4 @@     """
… 78 more lines (truncated)
pycparser/ast_transforms.py +82 lines
--- +++ @@ -1,2 +1,2 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: ast_transforms.py@@ -7,3 +7,5 @@ # License: BSD-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------++from typing import Any, List, Tuple, cast @@ -12,52 +14,52 @@ -def fix_switch_cases(switch_node):-    """ The 'case' statements in a 'switch' come out of parsing with one-        child node, so subsequent statements are just tucked to the parent-        Compound. Additionally, consecutive (fall-through) case statements-        come out messy. This is a peculiarity of the C grammar. The following:+def fix_switch_cases(switch_node: c_ast.Switch) -> c_ast.Switch:+    """The 'case' statements in a 'switch' come out of parsing with one+    child node, so subsequent statements are just tucked to the parent+    Compound. Additionally, consecutive (fall-through) case statements+    come out messy. This is a peculiarity of the C grammar. The following: -            switch (myvar) {-                case 10:-                    k = 10;-                    p = k + 1;-                    return 10;-                case 20:-                case 30:-                    return 20;-                default:-                    break;-            }+        switch (myvar) {+            case 10:+                k = 10;+                p = k + 1;+                return 10;+            case 20:+            case 30:+                return 20;+            default:+                break;+        } -        Creates this tree (pseudo-dump):+    Creates this tree (pseudo-dump): -            Switch-                ID: myvar-                Compound:-                    Case 10:-                        k = 10+        Switch+            ID: myvar+            Compound:+                Case 10:+                    k = 10+                p = k + 1+                return 10+                Case 20:+                    Case 30:+                        return 20+                Default:+                    break++    The goal of this transform is to fix this mess, turning it into the+    following:++        Switch+            ID: myvar+            Compound:+                Case 10:+                    k = 10                     p = k + 1                     return 10-                    Case 20:-                        Case 30:-                            return 20-                    Default:-                        break+                Case 20:+                Case 30:+                    return 20+                Default:+                    break -        The goal of this transform is to fix this mess, turning it into the-        following:--            Switch-                ID: myvar-                Compound:-                    Case 10:-                        k = 10-                        p = k + 1-                        return 10-                    Case 20:-                    Case 30:-                        return 20-                    Default:-                        break--        A fixed AST node is returned. The argument may be modified.+    A fixed AST node is returned. The argument may be modified.     """@@ -72,3 +74,3 @@     # The last Case/Default node-    last_case = None+    last_case: c_ast.Case | c_ast.Default | None = None @@ -77,3 +79,3 @@     # (for `switch(cond) {}`, block_items would have been None)-    for child in (switch_node.stmt.block_items or []):+    for child in switch_node.stmt.block_items or []:         if isinstance(child, (c_ast.Case, c_ast.Default)):@@ -98,18 +100,23 @@ -def _extract_nested_case(case_node, stmts_list):-    """ Recursively extract consecutive Case statements that are made nested-        by the parser and add them to the stmts_list.+def _extract_nested_case(+    case_node: c_ast.Case | c_ast.Default, stmts_list: List[c_ast.Node]+) -> None:+    """Recursively extract consecutive Case statements that are made nested+    by the parser and add them to the stmts_list.     """     if isinstance(case_node.stmts[0], (c_ast.Case, c_ast.Default)):-        stmts_list.append(case_node.stmts.pop())-        _extract_nested_case(stmts_list[-1], stmts_list)+        nested = case_node.stmts.pop()+        stmts_list.append(nested)+        _extract_nested_case(cast(Any, nested), stmts_list)  -def fix_atomic_specifiers(decl):-    """ Atomic specifiers like _Atomic(type) are unusually structured,-        conferring a qualifier upon the contained type.+def fix_atomic_specifiers(+    decl: c_ast.Decl | c_ast.Typedef,+) -> c_ast.Decl | c_ast.Typedef:+    """Atomic specifiers like _Atomic(type) are unusually structured,+    conferring a qualifier upon the contained type. -        This function fixes a decl with atomic specifiers to have a sane AST-        structure, by removing spurious Typename->TypeDecl pairs and attaching-        the _Atomic qualifier in the right place.+    This function fixes a decl with atomic specifiers to have a sane AST+    structure, by removing spurious Typename->TypeDecl pairs and attaching+    the _Atomic qualifier in the right place.     """@@ -125,3 +132,3 @@     # wrong place during construction).-    typ = decl+    typ: Any = decl     while not isinstance(typ, c_ast.TypeDecl):@@ -131,4 +138,4 @@             return decl-    if '_Atomic' in typ.quals and '_Atomic' not in decl.quals:-        decl.quals.append('_Atomic')+    if "_Atomic" in typ.quals and "_Atomic" not in decl.quals:+        decl.quals.append("_Atomic")     if typ.declname is None:@@ -139,11 +146,13 @@ -def _fix_atomic_specifiers_once(decl):-    """ Performs one 'fix' round of atomic specifiers.-        Returns (modified_decl, found) where found is True iff a fix was made.+def _fix_atomic_specifiers_once(+    decl: c_ast.Decl | c_ast.Typedef,+) -> Tuple[c_ast.Decl | c_ast.Typedef, bool]:+    """Performs one 'fix' round of atomic specifiers.+    Returns (modified_decl, found) where found is True iff a fix was made.     """-    parent = decl-    grandparent = None-    node = decl.type+    parent: Any = decl+    grandparent: Any = None+    node: Any = decl.type     while node is not None:-        if isinstance(node, c_ast.Typename) and '_Atomic' in node.quals:+        if isinstance(node, c_ast.Typename) and "_Atomic" in node.quals:             break@@ -160,5 +169,6 @@     assert isinstance(parent, c_ast.TypeDecl)-    grandparent.type = node.type-    if '_Atomic' not in node.type.quals:-        node.type.quals.append('_Atomic')+    assert grandparent is not None+    cast(Any, grandparent).type = node.type+    if "_Atomic" not in node.type.quals:+        node.type.quals.append("_Atomic")     return decl, True
pycparser/c_ast.py +493 lines
--- +++ @@ -1,5 +1,4 @@-#-----------------------------------------------------------------+# ----------------------------------------------------------------- # ** ATTENTION **-# This code was automatically generated from the file:-# _c_ast.cfg+# This code was automatically generated from _c_ast.cfg #@@ -15,3 +14,3 @@ # License: BSD-#-----------------------------------------------------------------+# ----------------------------------------------------------------- @@ -19,2 +18,4 @@ import sys+from typing import Any, ClassVar, IO, Optional+ @@ -25,3 +26,3 @@     if isinstance(obj, list):-        return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]'+        return "[" + (",\n ".join((_repr(e).replace("\n", "\n ") for e in obj))) + "\n]"     else:@@ -29,3 +30,4 @@ -class Node(object):++class Node:     __slots__ = ()@@ -33,9 +35,11 @@     """+    attr_names: ClassVar[tuple[str, ...]] = ()+    coord: Optional[Any]+     def __repr__(self):-        """ Generates a python representation of the current node-        """-        result = self.__class__.__name__ + '('--        indent = ''-        separator = ''+        """Generates a python representation of the current node"""+        result = self.__class__.__name__ + "("++        indent = ""+        separator = ""         for name in self.__slots__[:-2]:@@ -43,8 +47,17 @@             result += indent-            result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n  ' + (' ' * (len(name) + len(self.__class__.__name__)))))--            separator = ','-            indent = '\n ' + (' ' * len(self.__class__.__name__))--        result += indent + ')'+            result += (+                name+                + "="+                + (+                    _repr(getattr(self, name)).replace(+                        "\n",+                        "\n  " + (" " * (len(name) + len(self.__class__.__name__))),+                    )+                )+            )++            separator = ","+            indent = "\n " + (" " * len(self.__class__.__name__))++        result += indent + ")" @@ -53,41 +66,59 @@     def children(self):-        """ A sequence of all children that are Nodes+        """A sequence of all children that are Nodes"""+        pass++    def show(+        self,+        buf: IO[str] = sys.stdout,+        offset: int = 0,+        attrnames: bool = False,+        showemptyattrs: bool = True,+        nodenames: bool = False,+        showcoord: bool = False,+        _my_node_name: Optional[str] = None,+    ):+        """Pretty print the Node and all its attributes and+        children (recursively) to a buffer.++        buf:+            Open IO buffer into which the Node is printed.++        offset:+            Initial offset (amount of leading spaces)++        attrnames:+            True if you want to see the attribute names in+            name=value pairs. False to only see the values.++        showemptyattrs:+            False if you want to suppress printing empty attributes.++        nodenames:+            True if you want to see the actual node names+            within their parents.++        showcoord:+            Do you want the coordinates of each Node to be+            displayed.         """-        pass--    def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):-        """ Pretty print the Node and all its attributes and-            children (recursively) to a buffer.--            buf:-                Open IO buffer into which the Node is printed.--            offset:-                Initial offset (amount of leading spaces)--            attrnames:-                True if you want to see the attribute names in-                name=value pairs. False to only see the values.--            nodenames:-                True if you want to see the actual node names-                within their parents.--            showcoord:-                Do you want the coordinates of each Node to be-                displayed.-        """-        lead = ' ' * offset+        lead = " " * offset         if nodenames and _my_node_name is not None:-            buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ')+            buf.write(lead + self.__class__.__name__ + " <" + _my_node_name + ">: ")         else:-            buf.write(lead + self.__class__.__name__+ ': ')+            buf.write(lead + self.__class__.__name__ + ": ")          if self.attr_names:++            def is_empty(v):+                v is None or (hasattr(v, "__len__") and len(v) == 0)++            nvlist = [+                (n, getattr(self, n))+                for n in self.attr_names+                if showemptyattrs or not is_empty(getattr(self, n))+            ]             if attrnames:-                nvlist = [(n, getattr(self,n)) for n in self.attr_names]-                attrstr = ', '.join('%s=%s' % nv for nv in nvlist)+                attrstr = ", ".join(f"{name}={value}" for name, value in nvlist)             else:-                vlist = [getattr(self, n) for n in self.attr_names]-                attrstr = ', '.join('%s' % v for v in vlist)+                attrstr = ", ".join(f"{value}" for _, value in nvlist)             buf.write(attrstr)@@ -95,6 +126,6 @@         if showcoord:-            buf.write(' (at %s)' % self.coord)-        buf.write('\n')--        for (child_name, child) in self.children():+            buf.write(f" (at {self.coord})")+        buf.write("\n")++        for child_name, child in self.children():             child.show(@@ -103,39 +134,41 @@                 attrnames=attrnames,+                showemptyattrs=showemptyattrs,                 nodenames=nodenames,                 showcoord=showcoord,-                _my_node_name=child_name)---class NodeVisitor(object):-    """ A base NodeVisitor class for visiting c_ast nodes.-        Subclass it and define your own visit_XXX methods, where-        XXX is the class name you want to visit with these-        methods.--        For example:--        class ConstantVisitor(NodeVisitor):-            def __init__(self):-                self.values = []--            def visit_Constant(self, node):-                self.values.append(node.value)--        Creates a list of values of all the constant nodes-        encountered below the given node. To use it:--        cv = ConstantVisitor()-        cv.visit(node)--        Notes:--        *   generic_visit() will be called for AST nodes for which-            no visit_XXX method was defined.-        *   The children of nodes for which a visit_XXX was-            defined will not be visited - if you need this, call-            generic_visit() on the node.-            You can use:-                NodeVisitor.generic_visit(self, node)-        *   Modeled after Python's own AST visiting facilities-            (the ast module of Python 3.0)+                _my_node_name=child_name,+            )+++class NodeVisitor:+    """A base NodeVisitor class for visiting c_ast nodes.+    Subclass it and define your own visit_XXX methods, where+    XXX is the class name you want to visit with these+    methods.++    For example:++    class ConstantVisitor(NodeVisitor):+        def __init__(self):+            self.values = []++        def visit_Constant(self, node):+            self.values.append(node.value)++    Creates a list of values of all the constant nodes+    encountered below the given node. To use it:++    cv = ConstantVisitor()+    cv.visit(node)++    Notes:++    *   generic_visit() will be called for AST nodes for which+        no visit_XXX method was defined.+    *   The children of nodes for which a visit_XXX was+        defined will not be visited - if you need this, call+        generic_visit() on the node.+        You can use:+            NodeVisitor.generic_visit(self, node)
… 918 more lines (truncated)
pycparser/c_generator.py +415 lines
--- +++ @@ -1,2 +1,2 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: c_generator.py@@ -7,3 +7,5 @@ # License: BSD-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------+from typing import Callable, List, Optional+ from . import c_ast@@ -11,12 +13,16 @@ -class CGenerator(object):-    """ Uses the same visitor pattern as c_ast.NodeVisitor, but modified to-        return a value from each visit method, using string accumulation in-        generic_visit.+class CGenerator:+    """Uses the same visitor pattern as c_ast.NodeVisitor, but modified to+    return a value from each visit method, using string accumulation in+    generic_visit.     """-    def __init__(self, reduce_parentheses=False):-        """ Constructs C-code generator--            reduce_parentheses:-                if True, eliminates needless parentheses on binary operators++    indent_level: int+    reduce_parentheses: bool++    def __init__(self, reduce_parentheses: bool = False) -> None:+        """Constructs C-code generator++        reduce_parentheses:+            if True, eliminates needless parentheses on binary operators         """@@ -27,32 +33,32 @@ -    def _make_indent(self):-        return ' ' * self.indent_level--    def visit(self, node):-        method = 'visit_' + node.__class__.__name__+    def _make_indent(self) -> str:+        return " " * self.indent_level++    def visit(self, node: c_ast.Node) -> str:+        method = "visit_" + node.__class__.__name__         return getattr(self, method, self.generic_visit)(node) -    def generic_visit(self, node):+    def generic_visit(self, node: Optional[c_ast.Node]) -> str:         if node is None:-            return ''+            return ""         else:-            return ''.join(self.visit(c) for c_name, c in node.children())--    def visit_Constant(self, n):+            return "".join(self.visit(c) for c_name, c in node.children())++    def visit_Constant(self, n: c_ast.Constant) -> str:         return n.value -    def visit_ID(self, n):+    def visit_ID(self, n: c_ast.ID) -> str:         return n.name -    def visit_Pragma(self, n):-        ret = '#pragma'+    def visit_Pragma(self, n: c_ast.Pragma) -> str:+        ret = "#pragma"         if n.string:-            ret += ' ' + n.string+            ret += " " + n.string         return ret -    def visit_ArrayRef(self, n):+    def visit_ArrayRef(self, n: c_ast.ArrayRef) -> str:         arrref = self._parenthesize_unless_simple(n.name)-        return arrref + '[' + self.visit(n.subscript) + ']'--    def visit_StructRef(self, n):+        return arrref + "[" + self.visit(n.subscript) + "]"++    def visit_StructRef(self, n: c_ast.StructRef) -> str:         sref = self._parenthesize_unless_simple(n.name)@@ -60,19 +66,22 @@ -    def visit_FuncCall(self, n):+    def visit_FuncCall(self, n: c_ast.FuncCall) -> str:         fref = self._parenthesize_unless_simple(n.name)-        return fref + '(' + self.visit(n.args) + ')'--    def visit_UnaryOp(self, n):-        if n.op == 'sizeof':-            # Always parenthesize the argument of sizeof since it can be-            # a name.-            return 'sizeof(%s)' % self.visit(n.expr)-        else:-            operand = self._parenthesize_unless_simple(n.expr)-            if n.op == 'p++':-                return '%s++' % operand-            elif n.op == 'p--':-                return '%s--' % operand-            else:-                return '%s%s' % (n.op, operand)+        args = self.visit(n.args) if n.args is not None else ""+        return fref + "(" + args + ")"++    def visit_UnaryOp(self, n: c_ast.UnaryOp) -> str:+        match n.op:+            case "sizeof":+                # Always parenthesize the argument of sizeof since it can be+                # a name.+                return f"sizeof({self.visit(n.expr)})"+            case "p++":+                operand = self._parenthesize_unless_simple(n.expr)+                return f"{operand}++"+            case "p--":+                operand = self._parenthesize_unless_simple(n.expr)+                return f"{operand}--"+            case _:+                operand = self._parenthesize_unless_simple(n.expr)+                return f"{n.op}{operand}" @@ -82,15 +91,23 @@         # Higher numbers are stronger binding-        '||': 0,  # weakest binding-        '&&': 1,-        '|': 2,-        '^': 3,-        '&': 4,-        '==': 5, '!=': 5,-        '>': 6, '>=': 6, '<': 6, '<=': 6,-        '>>': 7, '<<': 7,-        '+': 8, '-': 8,-        '*': 9, '/': 9, '%': 9  # strongest binding+        "||": 0,  # weakest binding+        "&&": 1,+        "|": 2,+        "^": 3,+        "&": 4,+        "==": 5,+        "!=": 5,+        ">": 6,+        ">=": 6,+        "<": 6,+        "<=": 6,+        ">>": 7,+        "<<": 7,+        "+": 8,+        "-": 8,+        "*": 9,+        "/": 9,+        "%": 9,  # strongest binding     } -    def visit_BinaryOp(self, n):+    def visit_BinaryOp(self, n: c_ast.BinaryOp) -> str:         # Note: all binary operators are left-to-right associative@@ -106,5 +123,9 @@             n.left,-            lambda d: not (self._is_simple_node(d) or-                      self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and-                      self.precedence_map[d.op] >= self.precedence_map[n.op]))+            lambda d: not (+                self._is_simple_node(d)+                or self.reduce_parentheses+                and isinstance(d, c_ast.BinaryOp)+                and self.precedence_map[d.op] >= self.precedence_map[n.op]+            ),+        )         # If `n.right.op` has a stronger -but not equal- binding precedence,@@ -118,25 +139,30 @@             n.right,-            lambda d: not (self._is_simple_node(d) or-                      self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and-                      self.precedence_map[d.op] > self.precedence_map[n.op]))-        return '%s %s %s' % (lval_str, n.op, rval_str)--    def visit_Assignment(self, n):+            lambda d: not (+                self._is_simple_node(d)+                or self.reduce_parentheses+                and isinstance(d, c_ast.BinaryOp)+                and self.precedence_map[d.op] > self.precedence_map[n.op]+            ),+        )+        return f"{lval_str} {n.op} {rval_str}"++    def visit_Assignment(self, n: c_ast.Assignment) -> str:         rval_str = self._parenthesize_if(-                            n.rvalue,-                            lambda n: isinstance(n, c_ast.Assignment))-        return '%s %s %s' % (self.visit(n.lvalue), n.op, rval_str)--    def visit_IdentifierType(self, n):-        return ' '.join(n.names)--    def _visit_expr(self, n):-        if isinstance(n, c_ast.InitList):-            return '{' + self.visit(n) + '}'-        elif isinstance(n, (c_ast.ExprList, c_ast.Compound)):-            return '(' + self.visit(n) + ')'-        else:-            return self.visit(n)--    def visit_Decl(self, n, no_type=False):+            n.rvalue, lambda n: isinstance(n, c_ast.Assignment)+        )+        return f"{self.visit(n.lvalue)} {n.op} {rval_str}"++    def visit_IdentifierType(self, n: c_ast.IdentifierType) -> str:+        return " ".join(n.names)++    def _visit_expr(self, n: c_ast.Node) -> str:+        match n:+            case c_ast.InitList():+                return "{" + self.visit(n) + "}"+            case c_ast.ExprList() | c_ast.Compound():+                return "(" + self.visit(n) + ")"+            case _:+                return self.visit(n)++    def visit_Decl(self, n: c_ast.Decl, no_type: bool = False) -> str:         # no_type is used when a Decl is part of a DeclList, where the type is@@ -145,17 +171,20 @@         s = n.name if no_type else self._generate_decl(n)-        if n.bitsize: s += ' : ' + self.visit(n.bitsize)+        if n.bitsize:+            s += " : " + self.visit(n.bitsize)         if n.init:-            s += ' = ' + self._visit_expr(n.init)-        return s--    def visit_DeclList(self, n):+            s += " = " + self._visit_expr(n.init)+        return s++    def visit_DeclList(self, n: c_ast.DeclList) -> str:         s = self.visit(n.decls[0])         if len(n.decls) > 1:-            s += ', ' + ', '.join(self.visit_Decl(decl, no_type=True)-                                    for decl in n.decls[1:])-        return s-
… 641 more lines (truncated)
pycparser/c_lexer.py +691 lines
--- +++ @@ -1,2 +1,2 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: c_lexer.py@@ -7,36 +7,42 @@ # License: BSD-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ import re--from .ply import lex-from .ply.lex import TOKEN---class CLexer(object):-    """ A lexer for the C language. After building it, set the-        input text with input(), and call token() to get new-        tokens.--        The public attribute filename can be set to an initial-        filename, but the lexer will update it upon #line-        directives.+from dataclasses import dataclass+from enum import Enum+from typing import Callable, Dict, List, Optional, Tuple+++@dataclass(slots=True)+class _Token:+    type: str+    value: str+    lineno: int+    column: int+++class CLexer:+    """A standalone lexer for C.++    Parameters for construction:+        error_func:+            Called with (msg, line, column) on lexing errors.+        on_lbrace_func:+            Called when an LBRACE token is produced (used for scope tracking).+        on_rbrace_func:+            Called when an RBRACE token is produced (used for scope tracking).+        type_lookup_func:+            Called with an identifier name; expected to return True if it is+            a typedef name and should be tokenized as TYPEID.++    Call input(text) to initialize lexing, and then keep calling token() to+    get the next token, until it returns None (at end of input).     """-    def __init__(self, error_func, on_lbrace_func, on_rbrace_func,-                 type_lookup_func):-        """ Create a new Lexer.--            error_func:-                An error function. Will be called with an error-                message, line and column as arguments, in case of-                an error during lexing.--            on_lbrace_func, on_rbrace_func:-                Called when an LBRACE or RBRACE is encountered-                (likely to push/pop type_lookup_func's scope)--            type_lookup_func:-                A type lookup function. Given a string, it must-                return True IFF this string is a name of a type-                that was defined with a typedef earlier.-        """++    def __init__(+        self,+        error_func: Callable[[str, int, int], None],+        on_lbrace_func: Callable[[], None],+        on_rbrace_func: Callable[[], None],+        type_lookup_func: Callable[[str], bool],+    ) -> None:         self.error_func = error_func@@ -45,525 +51,656 @@         self.type_lookup_func = type_lookup_func-        self.filename = ''--        # Keeps track of the last token returned from self.token()-        self.last_token = None--        # Allow either "# line" or "# <num>" to support GCC's-        # cpp output-        #-        self.line_pattern = re.compile(r'([ \t]*line\W)|([ \t]*\d+)')-        self.pragma_pattern = re.compile(r'[ \t]*pragma\W')--    def build(self, **kwargs):-        """ Builds the lexer from the specification. Must be-            called after the lexer object is created.--            This method exists separately, because the PLY-            manual warns against calling lex.lex inside-            __init__+        self._init_state()++    def input(self, text: str, filename: str = "") -> None:+        """Initialize the lexer to the given input text.++        filename is an optional name identifying the file from which the input+        comes. The lexer can modify it if #line directives are encountered.         """-        self.lexer = lex.lex(object=self, **kwargs)--    def reset_lineno(self):-        """ Resets the internal line number counter of the lexer.+        self._init_state()+        self._lexdata = text+        self._filename = filename++    def _init_state(self) -> None:+        self._lexdata = ""+        self._filename = ""+        self._pos = 0+        self._line_start = 0+        self._pending_tok: Optional[_Token] = None+        self._lineno = 1++    @property+    def filename(self) -> str:+        return self._filename++    def token(self) -> Optional[_Token]:+        # Lexing strategy overview:+        #+        # - We maintain a current position (self._pos), line number, and the+        #   byte offset of the current line start. The lexer is a simple loop+        #   that skips whitespace/newlines and emits one token per call.+        # - A small amount of logic is handled manually before regex matching:+        #+        #   * Preprocessor-style directives: if we see '#', we check whether+        #     it's a #line or #pragma directive and consume it inline. #line+        #     updates lineno/filename and produces no tokens. #pragma can yield+        #     both PPPRAGMA and PPPRAGMASTR, but token() returns a single token,+        #     so we stash the PPPRAGMASTR as _pending_tok to return on the next+        #     token() call. Otherwise we return PPHASH.+        #   * Newlines update lineno/line-start tracking so tokens can record+        #     accurate columns.+        #+        # - The bulk of tokens are recognized in _match_token:+        #+        #   * _regex_rules: regex patterns for identifiers, literals, and other+        #     complex tokens (including error-producing patterns). The lexer+        #     uses a combined _regex_master to scan options at the same time.+        #   * _fixed_tokens: exact string matches for operators and punctuation,+        #     resolved by longest match.+        #+        # - Error patterns call the error callback and advance minimally, which+        #   keeps lexing resilient while reporting useful diagnostics.+        text = self._lexdata+        n = len(text)++        if self._pending_tok is not None:+            tok = self._pending_tok+            self._pending_tok = None+            return tok++        while self._pos < n:+            match text[self._pos]:+                case " " | "\t":+                    self._pos += 1+                case "\n":+                    self._lineno += 1+                    self._pos += 1+                    self._line_start = self._pos+                case "#":+                    if _line_pattern.match(text, self._pos + 1):+                        self._pos += 1+                        self._handle_ppline()+                        continue+                    if _pragma_pattern.match(text, self._pos + 1):+                        self._pos += 1+                        toks = self._handle_pppragma()+                        if len(toks) > 1:+                            self._pending_tok = toks[1]+                        if len(toks) > 0:+                            return toks[0]+                        continue+                    tok = self._make_token("PPHASH", "#", self._pos)+                    self._pos += 1+                    return tok+                case _:+                    if tok := self._match_token():+                        return tok+                    else:+                        continue++    def _match_token(self) -> Optional[_Token]:+        """Match one token at the current position.++        Returns a Token on success, or None if no token could be matched and+        an error was reported. This method always advances _pos by the matched+        length, or by 1 on error/no-match.         """-        self.lexer.lineno = 1--    def input(self, text):-        self.lexer.input(text)--    def token(self):-        self.last_token = self.lexer.token()-        return self.last_token--    def find_tok_column(self, token):-        """ Find the column of the token in its line.+        text = self._lexdata+        pos = self._pos+        # We pick the longest match between:+        # - the master regex (identifiers, literals, error patterns, etc.)+        # - fixed operator/punctuator literals from the bucket for text[pos]+        #+        # The longest match is required to ensure we properly lex something+        # like ".123" (a floating-point constant) as a single entity (with+        # FLOAT_CONST), rather than a PERIOD followed by a number.+        #+        # The fixed-literal buckets are already length-sorted, so within that+        # bucket we can take the first match. However, we still compare its+        # length to the regex match because the regex may have matched a longer+        # token that should take precedence.+        best = None++        if m := _regex_master.match(text, pos):+            tok_type = m.lastgroup+            # All master-regex alternatives are named; lastgroup shouldn't be None.+            assert tok_type is not None+            value = m.group(tok_type)+            length = len(value)+            action, msg = _regex_actions[tok_type]+            best = (length, tok_type, value, action, msg)++        if bucket := _fixed_tokens_by_first.get(text[pos]):+            for entry in bucket:+                if text.startswith(entry.literal, pos):+                    length = len(entry.literal)+                    if best is None or length > best[0]:+                        best = (+                            length,+                            entry.tok_type,+                            entry.literal,+                            _RegexAction.TOKEN,+                            None,+                        )+                    break
… 1009 more lines (truncated)
pycparser/c_parser.py +2162 lines
--- +++ @@ -1,5 +1,5 @@-#------------------------------------------------------------------------------+# ------------------------------------------------------------------------------ # pycparser: c_parser.py #-# CParser class: Parser and AST builder for the C language+# Recursive-descent parser for the C language. #@@ -7,8 +7,18 @@ # License: BSD-#-------------------------------------------------------------------------------from .ply import yacc+# ------------------------------------------------------------------------------+from dataclasses import dataclass+from typing import (+    Any,+    Dict,+    List,+    Literal,+    NoReturn,+    Optional,+    Tuple,+    TypedDict,+    cast,+)  from . import c_ast-from .c_lexer import CLexer-from .plyparser import PLYParser, ParseError, parameterized, template+from .c_lexer import CLexer, _Token from .ast_transforms import fix_switch_cases, fix_atomic_specifiers@@ -16,63 +26,48 @@ -@template-class CParser(PLYParser):+@dataclass+class Coord:+    """Coordinates of a syntactic element. Consists of:+    - File name+    - Line number+    - Column number+    """++    file: str+    line: int+    column: Optional[int] = None++    def __str__(self) -> str:+        text = f"{self.file}:{self.line}"+        if self.column:+            text += f":{self.column}"+        return text+++class ParseError(Exception):+    pass+++class CParser:+    """Recursive-descent C parser.++    Usage:+        parser = CParser()+        ast = parser.parse(text, filename)++    The `lexer` parameter lets you inject a lexer class (defaults to CLexer).+    The parameters after `lexer` are accepted for backward compatibility with+    the old PLY-based parser and are otherwise unused.+    """+     def __init__(-            self,-            lex_optimize=True,-            lexer=CLexer,-            lextab='pycparser.lextab',-            yacc_optimize=True,-            yacctab='pycparser.yacctab',-            yacc_debug=False,-            taboutputdir=''):-        """ Create a new CParser.--            Some arguments for controlling the debug/optimization-            level of the parser are provided. The defaults are-            tuned for release/performance mode.-            The simple rules for using them are:-            *) When tweaking CParser/CLexer, set these to False-            *) When releasing a stable parser, set to True--            lex_optimize:-                Set to False when you're modifying the lexer.-                Otherwise, changes in the lexer won't be used, if-                some lextab.py file exists.-                When releasing with a stable lexer, set to True-                to save the re-generation of the lexer table on-                each run.--            lexer:-                Set this parameter to define the lexer to use if-                you're not using the default CLexer.--            lextab:-                Points to the lex table that's used for optimized-                mode. Only if you're modifying the lexer and want-                some tests to avoid re-generating the table, make-                this point to a local lex table file (that's been-                earlier generated with lex_optimize=True)--            yacc_optimize:-                Set to False when you're modifying the parser.-                Otherwise, changes in the parser won't be used, if-                some parsetab.py file exists.-                When releasing with a stable parser, set to True-                to save the re-generation of the parser table on-                each run.--            yacctab:-                Points to the yacc table that's used for optimized-                mode. Only if you're modifying the parser, make-                this point to a local yacc table file--            yacc_debug:-                Generate a parser.out file that explains how yacc-                built the parsing table from the grammar.--            taboutputdir:-                Set this parameter to control the location of generated-                lextab and yacctab files.-        """-        self.clex = lexer(+        self,+        lex_optimize: bool = True,+        lexer: type[CLexer] = CLexer,+        lextab: str = "pycparser.lextab",+        yacc_optimize: bool = True,+        yacctab: str = "pycparser.yacctab",+        yacc_debug: bool = False,+        taboutputdir: str = "",+    ) -> None:+        self.clex: CLexer = lexer(             error_func=self._lex_error_func,@@ -80,37 +75,4 @@             on_rbrace_func=self._lex_on_rbrace_func,-            type_lookup_func=self._lex_type_lookup_func)--        self.clex.build(-            optimize=lex_optimize,-            lextab=lextab,-            outputdir=taboutputdir)-        self.tokens = self.clex.tokens--        rules_with_opt = [-            'abstract_declarator',-            'assignment_expression',-            'declaration_list',-            'declaration_specifiers_no_type',-            'designation',-            'expression',-            'identifier_list',-            'init_declarator_list',-            'id_init_declarator_list',-            'initializer_list',-            'parameter_type_list',-            'block_item_list',-            'type_qualifier_list',-            'struct_declarator_list'-        ]--        for rule in rules_with_opt:-            self._create_opt_rule(rule)--        self.cparser = yacc.yacc(-            module=self,-            start='translation_unit_or_empty',-            debug=yacc_debug,-            optimize=yacc_optimize,-            tabmodule=yacctab,-            outputdir=taboutputdir)+            type_lookup_func=self._lex_type_lookup_func,+        ) @@ -124,35 +86,43 @@         # in this scope at all.+        self._scope_stack: List[Dict[str, bool]] = [dict()]+        self._tokens: _TokenStream = _TokenStream(self.clex)++    def parse(+        self, text: str, filename: str = "", debug: bool = False+    ) -> c_ast.FileAST:+        """Parses C code and returns an AST.++        text:+            A string containing the C source code++        filename:+            Name of the file being parsed (for meaningful+            error messages)++        debug:+            Deprecated debug flag (unused); for backwards compatibility.+        """         self._scope_stack = [dict()]--        # Keeps track of the last token given to yacc (the lookahead token)-        self._last_yielded_token = None--    def parse(self, text, filename='', debug=False):-        """ Parses C code and returns an AST.--            text:-                A string containing the C source code--            filename:-                Name of the file being parsed (for meaningful-                error messages)--            debug:-                Debug flag to YACC-        """-        self.clex.filename = filename-        self.clex.reset_lineno()-        self._scope_stack = [dict()]-        self._last_yielded_token = None-        return self.cparser.parse(-                input=text,-                lexer=self.clex,-                debug=debug)--    ######################--   PRIVATE   --######################--    def _push_scope(self):+        self.clex.input(text, filename)+        self._tokens = _TokenStream(self.clex)++        ast = self._parse_translation_unit_or_empty()+        tok = self._peek()+        if tok is not None:+            self._parse_error(f"before: {tok.value}", self._tok_coord(tok))+        return ast++    # ------------------------------------------------------------------+    # Scope and declaration helpers+    # ------------------------------------------------------------------+    def _coord(self, lineno: int, column: Optional[int] = None) -> Coord:+        return Coord(file=self.clex.filename, line=lineno, column=column)++    def _parse_error(self, msg: str, coord: Coord | str | None) -> NoReturn:+        raise ParseError(f"{coord}: {msg}")+
… 3795 more lines (truncated)
pyproject.toml +38 lines
--- +++ @@ -0,0 +1,38 @@+[build-system]+requires = ["setuptools>=69", "wheel"]+build-backend = "setuptools.build_meta"++[project]+name = "pycparser"+version = "3.00"+description = "C parser in Python"+readme = "README.rst"+license = "BSD-3-Clause"+license-files = ["LICENSE"]+requires-python = ">=3.10"+authors = [{name = "Eli Bendersky", email = "[email protected]"}]+maintainers = [{name = "Eli Bendersky", email = "[email protected]"}]+classifiers = [+  "Development Status :: 5 - Production/Stable",+  "Programming Language :: Python :: 3",+  "Programming Language :: Python :: 3.10",+  "Programming Language :: Python :: 3.11",+  "Programming Language :: Python :: 3.12",+  "Programming Language :: Python :: 3.13",+  "Programming Language :: Python :: 3.14",+]++[project.urls]+Homepage = "https://github.com/eliben/pycparser"++[tool.setuptools]+packages = ["pycparser"]++[tool.setuptools.package-data]+pycparser = ["*.cfg"]++[tool.ruff.lint]+ignore = ["F403", "F405"]++[tool.ty.src]+exclude = ["setup.py", "utils/internal/memprofiling.py"]
tests/test_c_ast.py +69 lines
--- +++ @@ -4,5 +4,5 @@ -sys.path.insert(0, '..')+sys.path.insert(0, "..") import pycparser.c_ast as c_ast-import pycparser.plyparser as plyparser+from pycparser.c_parser import Coord @@ -12,18 +12,21 @@         b1 = c_ast.BinaryOp(-            op='+',-            left=c_ast.Constant(type='int', value='6'),-            right=c_ast.ID(name='joe'))+            op="+",+            left=c_ast.Constant(type="int", value="6"),+            right=c_ast.ID(name="joe"),+        )          self.assertIsInstance(b1.left, c_ast.Constant)-        self.assertEqual(b1.left.type, 'int')-        self.assertEqual(b1.left.value, '6')+        self.assertEqual(b1.left.type, "int")+        self.assertEqual(b1.left.value, "6")          self.assertIsInstance(b1.right, c_ast.ID)-        self.assertEqual(b1.right.name, 'joe')+        self.assertEqual(b1.right.name, "joe")      def test_weakref_works_on_nodes(self):-        c1 = c_ast.Constant(type='float', value='3.14')+        c1 = c_ast.Constant(type="float", value="3.14")         wr = weakref.ref(c1)         cref = wr()-        self.assertEqual(cref.type, 'float')+        self.assertIsNotNone(cref)+        assert cref is not None+        self.assertEqual(cref.type, "float")         self.assertEqual(weakref.getweakrefcount(c1), 1)@@ -31,5 +34,7 @@     def test_weakref_works_on_coord(self):-        coord = plyparser.Coord(file='a', line=2)+        coord = Coord(file="a", line=2)         wr = weakref.ref(coord)         cref = wr()+        self.assertIsNotNone(cref)+        assert cref is not None         self.assertEqual(cref.line, 2)@@ -48,5 +53,6 @@         b1 = c_ast.BinaryOp(-            op='+',-            left=c_ast.Constant(type='int', value='6'),-            right=c_ast.ID(name='joe'))+            op="+",+            left=c_ast.Constant(type="int", value="6"),+            right=c_ast.ID(name="joe"),+        ) @@ -55,13 +61,9 @@ -        self.assertEqual(cv.values, ['6'])+        self.assertEqual(cv.values, ["6"])          b2 = c_ast.BinaryOp(-            op='*',-            left=c_ast.Constant(type='int', value='111'),-            right=b1)+            op="*", left=c_ast.Constant(type="int", value="111"), right=b1+        ) -        b3 = c_ast.BinaryOp(-            op='^',-            left=b2,-            right=b1)+        b3 = c_ast.BinaryOp(op="^", left=b2, right=b1) @@ -70,20 +72,13 @@ -        self.assertEqual(cv.values, ['111', '6', '6'])+        self.assertEqual(cv.values, ["111", "6", "6"])      def tests_list_children(self):-        c1 = c_ast.Constant(type='float', value='5.6')-        c2 = c_ast.Constant(type='char', value='t')+        c1 = c_ast.Constant(type="float", value="5.6")+        c2 = c_ast.Constant(type="char", value="t") -        b1 = c_ast.BinaryOp(-            op='+',-            left=c1,-            right=c2)+        b1 = c_ast.BinaryOp(op="+", left=c1, right=c2) -        b2 = c_ast.BinaryOp(-            op='-',-            left=b1,-            right=c2)+        b2 = c_ast.BinaryOp(op="-", left=b1, right=c2) -        comp = c_ast.Compound(-            block_items=[b1, b2, c1, c2])+        comp = c_ast.Compound(block_items=[b1, b2, c1, c2]) @@ -92,57 +87,50 @@ -        self.assertEqual(cv.values,-                         ['5.6', 't', '5.6', 't', 't', '5.6', 't'])+        self.assertEqual(cv.values, ["5.6", "t", "5.6", "t", "t", "5.6", "t"])      def test_repr(self):-        c1 = c_ast.Constant(type='float', value='5.6')-        c2 = c_ast.Constant(type='char', value='t')+        c1 = c_ast.Constant(type="float", value="5.6")+        c2 = c_ast.Constant(type="char", value="t") -        b1 = c_ast.BinaryOp(-            op='+',-            left=c1,-            right=c2)+        b1 = c_ast.BinaryOp(op="+", left=c1, right=c2) -        b2 = c_ast.BinaryOp(-            op='-',-            left=b1,-            right=c2)+        b2 = c_ast.BinaryOp(op="-", left=b1, right=c2) -        comp = c_ast.Compound(-            block_items=[b1, b2, c1, c2])+        comp = c_ast.Compound(block_items=[b1, b2, c1, c2]) -        expected = ("Compound(block_items=[BinaryOp(op='+',\n"-                    "                               left=Constant(type='float',\n"-                    "                                             value='5.6'\n"-                    "                                             ),\n"-                    "                               right=Constant(type='char',\n"-                    "                                              value='t'\n"-                    "                                              )\n"-                    "                               ),\n"-                    "                      BinaryOp(op='-',\n"-                    "                               left=BinaryOp(op='+',\n"-                    "                                             left=Constant(type='float',\n"-                    "                                                           value='5.6'\n"-                    "                                                           ),\n"-                    "                                             right=Constant(type='char',\n"-                    "                                                            value='t'\n"-                    "                                                            )\n"-                    "                                             ),\n"-                    "                               right=Constant(type='char',\n"-                    "                                              value='t'\n"-                    "                                              )\n"-                    "                               ),\n"-                    "                      Constant(type='float',\n"-                    "                               value='5.6'\n"-                    "                               ),\n"-                    "                      Constant(type='char',\n"-                    "                               value='t'\n"-                    "                               )\n"-                    "                     ]\n"-                    "         )")+        expected = (+            "Compound(block_items=[BinaryOp(op='+',\n"+            "                               left=Constant(type='float',\n"+            "                                             value='5.6'\n"+            "                                             ),\n"+            "                               right=Constant(type='char',\n"+            "                                              value='t'\n"+            "                                              )\n"+            "                               ),\n"+            "                      BinaryOp(op='-',\n"+            "                               left=BinaryOp(op='+',\n"+            "                                             left=Constant(type='float',\n"+            "                                                           value='5.6'\n"+            "                                                           ),\n"+            "                                             right=Constant(type='char',\n"+            "                                                            value='t'\n"+            "                                                            )\n"+            "                                             ),\n"+            "                               right=Constant(type='char',\n"+            "                                              value='t'\n"+            "                                              )\n"+            "                               ),\n"+            "                      Constant(type='float',\n"+            "                               value='5.6'\n"+            "                               ),\n"+            "                      Constant(type='char',\n"+            "                               value='t'\n"+            "                               )\n"+            "                     ]\n"+            "         )"+        ) -        self.assertEqual(repr(comp),-                         expected)+        self.assertEqual(repr(comp), expected)  -if __name__ == '__main__':+if __name__ == "__main__":     unittest.main()
tests/test_c_generator.py +195 lines
--- +++ @@ -5,3 +5,3 @@ # Run from the root dir-sys.path.insert(0, '.')+sys.path.insert(0, ".") @@ -10,7 +10,3 @@ -_c_parser = c_parser.CParser(-                lex_optimize=False,-                yacc_debug=True,-                yacc_optimize=False,-                yacctab='yacctab')+_c_parser = c_parser.CParser() @@ -26,3 +22,3 @@     # ast1 and ast2 are the same.-    if type(ast1) != type(ast2):+    if type(ast1) is not type(ast2):         return False@@ -67,6 +63,6 @@     def test_partial_funcdecl_generation(self):-        src = r'''+        src = r"""             void noop(void);             void *something(void *thing);-            int add(int x, int y);'''+            int add(int x, int y);"""         ast = parse_to_ast(src)@@ -75,5 +71,5 @@         self.assertEqual(len(v.stubs), 3)-        self.assertTrue(r'void noop(void)' in v.stubs)-        self.assertTrue(r'void *something(void *thing)' in v.stubs)-        self.assertTrue(r'int add(int x, int y)' in v.stubs)+        self.assertTrue(r"void noop(void)" in v.stubs)+        self.assertTrue(r"void *something(void *thing)" in v.stubs)+        self.assertTrue(r"int add(int x, int y)" in v.stubs) @@ -87,11 +83,13 @@     def _assert_ctoc_correct(self, src, *args, **kwargs):-        """ Checks that the c2c translation was correct by parsing the code-            generated by c2c for src and comparing the AST with the original-            AST.--            Additional arguments are passed to CGenerator.__init__.+        """Checks that the c2c translation was correct by parsing the code+        generated by c2c for src and comparing the AST with the original+        AST.++        Additional arguments are passed to CGenerator.__init__.         """         src2 = self._run_c_to_c(src, *args, **kwargs)-        self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)),-                        "{!r} != {!r}".format(src, src2))+        self.assertTrue(+            compare_asts(parse_to_ast(src), parse_to_ast(src2)),+            "{!r} != {!r}".format(src, src2),+        )         return src2@@ -99,26 +97,26 @@     def test_trivial_decls(self):-        self._assert_ctoc_correct('int a;')-        self._assert_ctoc_correct('int b, a;')-        self._assert_ctoc_correct('int c, b, a;')-        self._assert_ctoc_correct('auto int a;')-        self._assert_ctoc_correct('register int a;')-        self._assert_ctoc_correct('_Thread_local int a;')+        self._assert_ctoc_correct("int a;")+        self._assert_ctoc_correct("int b, a;")+        self._assert_ctoc_correct("int c, b, a;")+        self._assert_ctoc_correct("auto int a;")+        self._assert_ctoc_correct("register int a;")+        self._assert_ctoc_correct("_Thread_local int a;")      def test_complex_decls(self):-        self._assert_ctoc_correct('int** (*a)(void);')-        self._assert_ctoc_correct('int** (*a)(void*, int);')-        self._assert_ctoc_correct('int (*b)(char * restrict k, float);')-        self._assert_ctoc_correct('int (*b)(char * _Atomic k, float);')-        self._assert_ctoc_correct('int (*b)(char * _Atomic volatile k, float);')-        self._assert_ctoc_correct('int test(const char* const* arg);')-        self._assert_ctoc_correct('int test(const char** const arg);')+        self._assert_ctoc_correct("int** (*a)(void);")+        self._assert_ctoc_correct("int** (*a)(void*, int);")+        self._assert_ctoc_correct("int (*b)(char * restrict k, float);")+        self._assert_ctoc_correct("int (*b)(char * _Atomic k, float);")+        self._assert_ctoc_correct("int (*b)(char * _Atomic volatile k, float);")+        self._assert_ctoc_correct("int test(const char* const* arg);")+        self._assert_ctoc_correct("int test(const char** const arg);")      def test_alignment(self):-        self._assert_ctoc_correct('_Alignas(32) int b;')-        self._assert_ctoc_correct('int _Alignas(32) a;')-        self._assert_ctoc_correct('_Alignas(32) _Atomic(int) b;')-        self._assert_ctoc_correct('_Atomic(int) _Alignas(32) b;')-        self._assert_ctoc_correct('_Alignas(long long) int a;')-        self._assert_ctoc_correct('int _Alignas(long long) a;')-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct("_Alignas(32) int b;")+        self._assert_ctoc_correct("int _Alignas(32) a;")+        self._assert_ctoc_correct("_Alignas(32) _Atomic(int) b;")+        self._assert_ctoc_correct("_Atomic(int) _Alignas(32) b;")+        self._assert_ctoc_correct("_Alignas(long long) int a;")+        self._assert_ctoc_correct("int _Alignas(long long) a;")+        self._assert_ctoc_correct(r"""             typedef struct node_t {@@ -127,4 +125,4 @@             } node;-            ''')-        self._assert_ctoc_correct(r'''+            """)+        self._assert_ctoc_correct(r"""             typedef struct node_t {@@ -133,6 +131,6 @@             } node;-            ''')+            """)      def test_ternary(self):-        self._assert_ctoc_correct('''+        self._assert_ctoc_correct("""             int main(void)@@ -141,6 +139,6 @@                 (a == 0) ? (b = 1) : (b = 2);-            }''')+            }""")      def test_casts(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             int main() {@@ -148,4 +146,4 @@                 int c = (int*) f;-            }''')-        self._assert_ctoc_correct(r'''+            }""")+        self._assert_ctoc_correct(r"""             int main() {@@ -154,9 +152,9 @@             }-        ''')+        """)      def test_initlist(self):-        self._assert_ctoc_correct('int arr[] = {1, 2, 3};')+        self._assert_ctoc_correct("int arr[] = {1, 2, 3};")      def test_exprs(self):-        self._assert_ctoc_correct('''+        self._assert_ctoc_correct("""             int main(void)@@ -168,3 +166,3 @@                 int e = --a;-            }''')+            }""") @@ -172,3 +170,3 @@         # note two minuses here-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             int main() {@@ -179,6 +177,6 @@                 return a;-            }''')+            }""")      def test_struct_decl(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             typedef struct node_t {@@ -187,6 +185,6 @@             } node;-            ''')+            """)      def test_krstyle(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             int main(argc, argv)@@ -197,6 +195,6 @@             }-        ''')+        """)      def test_switchcase(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""         int main() {@@ -216,6 +214,6 @@         }-        ''')+        """)      def test_nest_initializer_list(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""         int main()@@ -223,6 +221,6 @@            int i[1][1] = { { 1 } };-        }''')+        }""")      def test_nest_named_initializer(self):-        self._assert_ctoc_correct(r'''struct test+        self._assert_ctoc_correct(r"""struct test             {@@ -236,6 +234,6 @@             struct test test_var = {.i = 0, .test_i = {.k = 1}, .j = 2};-        ''')+        """)      def test_expr_list_in_initializer_list(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""         int main()@@ -243,11 +241,11 @@            int i[1] = { (1, 2) };-        }''')+        }""")      def test_issue36(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             int main() {-            }''')+            }""")      def test_issue37(self):-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             int main(void)@@ -257,3 +255,3 @@               return 0;-            }''')+            }""") @@ -262,13 +260,13 @@         # (previous valid behavior, still working)-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             struct foo;-            ''')+            """)         # An empty body must be generated         # (added behavior)-        self._assert_ctoc_correct(r'''+        self._assert_ctoc_correct(r"""             struct foo {};-            ''')
… 369 more lines (truncated)
tests/test_c_lexer.py +372 lines
--- +++ @@ -3,5 +3,13 @@ import unittest--sys.path.insert(0, '..')-from pycparser.c_lexer import CLexer+from typing import Optional++sys.path.insert(0, "..")+from pycparser.c_lexer import CLexer, _Token+++def require_token(tok: Optional[_Token]) -> _Token:+    # In tests we know token() should produce a token here; this helper asserts+    # that and narrows Optional[_Token] to _Token, avoiding repeated casts/guards.+    assert tok is not None+    return tok @@ -17,6 +25,7 @@ class TestCLexerNoErrors(unittest.TestCase):-    """ Test lexing of strings that are not supposed to cause-        errors. Therefore, the error_func passed to the lexer-        raises an exception.+    """Test lexing of strings that are not supposed to cause+    errors. Therefore, the error_func passed to the lexer+    raises an exception.     """+     def error_func(self, msg, line, column):@@ -31,3 +40,3 @@     def type_lookup_func(self, typ):-        if typ.startswith('mytype'):+        if typ.startswith("mytype"):             return True@@ -37,5 +46,5 @@     def setUp(self):-        self.clex = CLexer(self.error_func, lambda: None, lambda: None,-                           self.type_lookup_func)-        self.clex.build(optimize=False)+        self.clex = CLexer(+            self.error_func, lambda: None, lambda: None, self.type_lookup_func+        ) @@ -46,91 +55,91 @@     def test_trivial_tokens(self):-        self.assertTokensTypes('1', ['INT_CONST_DEC'])-        self.assertTokensTypes('-', ['MINUS'])-        self.assertTokensTypes('volatile', ['VOLATILE'])-        self.assertTokensTypes('...', ['ELLIPSIS'])-        self.assertTokensTypes('++', ['PLUSPLUS'])-        self.assertTokensTypes('case int', ['CASE', 'INT'])-        self.assertTokensTypes('caseint', ['ID'])-        self.assertTokensTypes('$dollar cent$', ['ID', 'ID'])-        self.assertTokensTypes('i ^= 1;', ['ID', 'XOREQUAL', 'INT_CONST_DEC', 'SEMI'])+        self.assertTokensTypes("1", ["INT_CONST_DEC"])+        self.assertTokensTypes("-", ["MINUS"])+        self.assertTokensTypes("volatile", ["VOLATILE"])+        self.assertTokensTypes("...", ["ELLIPSIS"])+        self.assertTokensTypes("++", ["PLUSPLUS"])+        self.assertTokensTypes("case int", ["CASE", "INT"])+        self.assertTokensTypes("caseint", ["ID"])+        self.assertTokensTypes("$dollar cent$", ["ID", "ID"])+        self.assertTokensTypes("i ^= 1;", ["ID", "XOREQUAL", "INT_CONST_DEC", "SEMI"])      def test_id_typeid(self):-        self.assertTokensTypes('myt', ['ID'])-        self.assertTokensTypes('mytype', ['TYPEID'])-        self.assertTokensTypes('mytype6 var', ['TYPEID', 'ID'])+        self.assertTokensTypes("myt", ["ID"])+        self.assertTokensTypes("mytype", ["TYPEID"])+        self.assertTokensTypes("mytype6 var", ["TYPEID", "ID"])      def test_integer_constants(self):-        self.assertTokensTypes('12', ['INT_CONST_DEC'])-        self.assertTokensTypes('12u', ['INT_CONST_DEC'])-        self.assertTokensTypes('12l', ['INT_CONST_DEC'])-        self.assertTokensTypes('199872Ul', ['INT_CONST_DEC'])-        self.assertTokensTypes('199872lU', ['INT_CONST_DEC'])-        self.assertTokensTypes('199872LL', ['INT_CONST_DEC'])-        self.assertTokensTypes('199872ull', ['INT_CONST_DEC'])-        self.assertTokensTypes('199872llu', ['INT_CONST_DEC'])-        self.assertTokensTypes('1009843200000uLL', ['INT_CONST_DEC'])-        self.assertTokensTypes('1009843200000LLu', ['INT_CONST_DEC'])--        self.assertTokensTypes('077', ['INT_CONST_OCT'])-        self.assertTokensTypes('0123456L', ['INT_CONST_OCT'])--        self.assertTokensTypes('0xf7', ['INT_CONST_HEX'])-        self.assertTokensTypes('0b110', ['INT_CONST_BIN'])-        self.assertTokensTypes('0x01202AAbbf7Ul', ['INT_CONST_HEX'])-        self.assertTokensTypes("'12'", ['INT_CONST_CHAR'])-        self.assertTokensTypes("'123'", ['INT_CONST_CHAR'])-        self.assertTokensTypes("'1AB4'", ['INT_CONST_CHAR'])-        self.assertTokensTypes(r"'1A\n4'", ['INT_CONST_CHAR'])+        self.assertTokensTypes("12", ["INT_CONST_DEC"])+        self.assertTokensTypes("12u", ["INT_CONST_DEC"])+        self.assertTokensTypes("12l", ["INT_CONST_DEC"])+        self.assertTokensTypes("199872Ul", ["INT_CONST_DEC"])+        self.assertTokensTypes("199872lU", ["INT_CONST_DEC"])+        self.assertTokensTypes("199872LL", ["INT_CONST_DEC"])+        self.assertTokensTypes("199872ull", ["INT_CONST_DEC"])+        self.assertTokensTypes("199872llu", ["INT_CONST_DEC"])+        self.assertTokensTypes("1009843200000uLL", ["INT_CONST_DEC"])+        self.assertTokensTypes("1009843200000LLu", ["INT_CONST_DEC"])++        self.assertTokensTypes("077", ["INT_CONST_OCT"])+        self.assertTokensTypes("0123456L", ["INT_CONST_OCT"])++        self.assertTokensTypes("0xf7", ["INT_CONST_HEX"])+        self.assertTokensTypes("0b110", ["INT_CONST_BIN"])+        self.assertTokensTypes("0x01202AAbbf7Ul", ["INT_CONST_HEX"])+        self.assertTokensTypes("'12'", ["INT_CONST_CHAR"])+        self.assertTokensTypes("'123'", ["INT_CONST_CHAR"])+        self.assertTokensTypes("'1AB4'", ["INT_CONST_CHAR"])+        self.assertTokensTypes(r"'1A\n4'", ["INT_CONST_CHAR"])          # no 0 before x, so ID catches it-        self.assertTokensTypes('xf7', ['ID'])+        self.assertTokensTypes("xf7", ["ID"])          # - is MINUS, the rest a constnant-        self.assertTokensTypes('-1', ['MINUS', 'INT_CONST_DEC'])+        self.assertTokensTypes("-1", ["MINUS", "INT_CONST_DEC"])      def test_special_names(self):-        self.assertTokensTypes('sizeof offsetof', ['SIZEOF', 'OFFSETOF'])+        self.assertTokensTypes("sizeof offsetof", ["SIZEOF", "OFFSETOF"])      def test_new_keywords(self):-        self.assertTokensTypes('_Bool', ['_BOOL'])-        self.assertTokensTypes('_Atomic', ['_ATOMIC'])-        self.assertTokensTypes('_Alignas _Alignof', ['_ALIGNAS', '_ALIGNOF'])+        self.assertTokensTypes("_Bool", ["_BOOL"])+        self.assertTokensTypes("_Atomic", ["_ATOMIC"])+        self.assertTokensTypes("_Alignas _Alignof", ["_ALIGNAS", "_ALIGNOF"])      def test_floating_constants(self):-        self.assertTokensTypes('1.5f', ['FLOAT_CONST'])-        self.assertTokensTypes('01.5', ['FLOAT_CONST'])-        self.assertTokensTypes('.15L', ['FLOAT_CONST'])-        self.assertTokensTypes('0.', ['FLOAT_CONST'])+        self.assertTokensTypes("1.5f", ["FLOAT_CONST"])+        self.assertTokensTypes("01.5", ["FLOAT_CONST"])+        self.assertTokensTypes(".15L", ["FLOAT_CONST"])+        self.assertTokensTypes("0.", ["FLOAT_CONST"])          # but just a period is a period-        self.assertTokensTypes('.', ['PERIOD'])--        self.assertTokensTypes('3.3e-3', ['FLOAT_CONST'])-        self.assertTokensTypes('.7e25L', ['FLOAT_CONST'])-        self.assertTokensTypes('6.e+125f', ['FLOAT_CONST'])-        self.assertTokensTypes('666e666', ['FLOAT_CONST'])-        self.assertTokensTypes('00666e+3', ['FLOAT_CONST'])+        self.assertTokensTypes(".", ["PERIOD"])++        self.assertTokensTypes("3.3e-3", ["FLOAT_CONST"])+        self.assertTokensTypes(".7e25L", ["FLOAT_CONST"])+        self.assertTokensTypes("6.e+125f", ["FLOAT_CONST"])+        self.assertTokensTypes("666e666", ["FLOAT_CONST"])+        self.assertTokensTypes("00666e+3", ["FLOAT_CONST"])          # but this is a hex integer + 3-        self.assertTokensTypes('0x0666e+3', ['INT_CONST_HEX', 'PLUS', 'INT_CONST_DEC'])+        self.assertTokensTypes("0x0666e+3", ["INT_CONST_HEX", "PLUS", "INT_CONST_DEC"])      def test_hexadecimal_floating_constants(self):-        self.assertTokensTypes('0xDE.488641p0', ['HEX_FLOAT_CONST'])-        self.assertTokensTypes('0x.488641p0', ['HEX_FLOAT_CONST'])-        self.assertTokensTypes('0X12.P0', ['HEX_FLOAT_CONST'])+        self.assertTokensTypes("0xDE.488641p0", ["HEX_FLOAT_CONST"])+        self.assertTokensTypes("0x.488641p0", ["HEX_FLOAT_CONST"])+        self.assertTokensTypes("0X12.P0", ["HEX_FLOAT_CONST"])      def test_char_constants(self):-        self.assertTokensTypes(r"""'x'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""L'x'""", ['WCHAR_CONST'])-        self.assertTokensTypes(r"""u8'x'""", ['U8CHAR_CONST'])-        self.assertTokensTypes(r"""u'x'""", ['U16CHAR_CONST'])-        self.assertTokensTypes(r"""U'x'""", ['U32CHAR_CONST'])-        self.assertTokensTypes(r"""'\t'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\''""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\?'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\0'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\012'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\x2f'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""'\x2f12'""", ['CHAR_CONST'])-        self.assertTokensTypes(r"""L'\xaf'""", ['WCHAR_CONST'])+        self.assertTokensTypes(r"""'x'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""L'x'""", ["WCHAR_CONST"])+        self.assertTokensTypes(r"""u8'x'""", ["U8CHAR_CONST"])+        self.assertTokensTypes(r"""u'x'""", ["U16CHAR_CONST"])+        self.assertTokensTypes(r"""U'x'""", ["U32CHAR_CONST"])+        self.assertTokensTypes(r"""'\t'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\''""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\?'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\0'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\012'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\x2f'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""'\x2f12'""", ["CHAR_CONST"])+        self.assertTokensTypes(r"""L'\xaf'""", ["WCHAR_CONST"]) @@ -138,49 +147,42 @@         braces = []+         def on_lbrace():-            braces.append('{')+            braces.append("{")+         def on_rbrace():-            braces.append('}')-        clex = CLexer(self.error_func, on_lbrace, on_rbrace,-                      self.type_lookup_func)-        clex.build(optimize=False)-        clex.input('hello { there } } and again }}{')+            braces.append("}")++        clex = CLexer(self.error_func, on_lbrace, on_rbrace, self.type_lookup_func)+        clex.input("hello { there } } and again }}{")         token_list(clex)-        self.assertEqual(braces, ['{', '}', '}', '}', '}', '{'])+        self.assertEqual(braces, ["{", "}", "}", "}", "}", "{"])      def test_string_literal(self):-        self.assertTokensTypes('"a string"', ['STRING_LITERAL'])-        self.assertTokensTypes('L"ing"', ['WSTRING_LITERAL'])-        self.assertTokensTypes('u8"ing"', ['U8STRING_LITERAL'])-        self.assertTokensTypes('u"ing"', ['U16STRING_LITERAL'])-        self.assertTokensTypes('U"ing"', ['U32STRING_LITERAL'])-        self.assertTokensTypes(-            '"i am a string too \t"',-            ['STRING_LITERAL'])-        self.assertTokensTypes(-            r'''"esc\ape \"\'\? \0234 chars \rule"''',-            ['STRING_LITERAL'])-        self.assertTokensTypes(-            r'''"hello 'joe' wanna give it a \"go\"?"''',-            ['STRING_LITERAL'])+        self.assertTokensTypes('"a string"', ["STRING_LITERAL"])+        self.assertTokensTypes('L"ing"', ["WSTRING_LITERAL"])+        self.assertTokensTypes('u8"ing"', ["U8STRING_LITERAL"])+        self.assertTokensTypes('u"ing"', ["U16STRING_LITERAL"])+        self.assertTokensTypes('U"ing"', ["U32STRING_LITERAL"])+        self.assertTokensTypes('"i am a string too \t"', ["STRING_LITERAL"])+        self.assertTokensTypes(+            r'''"esc\ape \"\'\? \0234 chars \rule"''', ["STRING_LITERAL"]+        )+        self.assertTokensTypes(+            r'''"hello 'joe' wanna give it a \"go\"?"''', ["STRING_LITERAL"]
… 544 more lines (truncated)
pygments pypi
2.21.0 5d ago nominal
no findings
latest 2.21.0 versions 69 maintainers 1
2.15.1
2.16.0
2.16.1
2.17.0
2.17.1
2.17.2
2.18.0
2.19.0
2.19.1
2.19.2
2.20.0
2.21.0
CLEAN
no findings — nominal
release diff 2.20.0 → 2.21.0
+90 added · -3 removed · ~155 modified
+109 more files not shown
doc/_static/demo-worker.js +4 lines
--- +++ @@ -1,2 +1,4 @@-importScripts('/_static/pyodide/pyodide.js');+import { loadPyodide } from "https://cdn.jsdelivr.net/pyodide/v314.0.2/full/pyodide.mjs";++const wheelName = new URLSearchParams(self.location.search).get('wheel'); @@ -4,3 +6,3 @@     self.pyodide = await loadPyodide();-    await self.pyodide.loadPackage(["Pygments"]);+    await self.pyodide.loadPackage(new URL(`/_static/${wheelName}`, self.location).href);     const styles = self.pyodide.runPython(`
doc/_static/demo.js +3 lines
--- +++ @@ -81,3 +81,5 @@ -const highlightWorker = new Worker("/_static/demo-worker.js");+const highlightWorker = new Worker(+    `/_static/demo-worker.js?wheel=${encodeURIComponent(pygmentsWheelName)}`,+    { type: 'module' }); highlightWorker.onmessage = (msg) => {
doc/conf.py +7 lines
--- +++ @@ -7,2 +7,3 @@ import sys+import glob @@ -143,3 +144,3 @@     html_additional_pages['demo'] = 'demo.html'-    html_static_path.append('_build/pyodide')+    html_static_path.append('_build/wheel') @@ -240,2 +241,5 @@         ctx['lexers'] = sorted(pygments.lexers.get_all_lexers(plugins=False), key=lambda x: x[0].lower())+        # We need the wheel name for the demo to work, and we don't want to pass+        # the version in here, so we just glob any wheel as there's only one+        ctx['wheel_filename'] = os.path.basename(glob.glob('_build/wheel/pygments-*.whl')[0]) @@ -271,3 +275,4 @@         # the default style is always displayed first-        default_style = ctx['styles_aa'].pop(0)+        default_style = next(s for s in ctx['styles_aa'] if s['name'] == 'default')+        ctx['styles_aa'].remove(default_style)         ctx['styles_aa'].sort(key=sortkey)
pygments/__init__.py +1 lines
--- +++ @@ -28,3 +28,3 @@ -__version__ = '2.20.0'+__version__ = '2.21.0' __docformat__ = 'restructuredtext'
pygments/cmdline.py +4 lines
--- +++ @@ -208,5 +208,2 @@ -        # print version-        if not argns.json:-            main(['', '-V'])         allowed_types = {'lexer', 'formatter', 'filter', 'style'}@@ -215,3 +212,6 @@             parser.print_help(sys.stderr)-            return 0+            return 2+        # print version+        if not argns.json:+            main(['', '-V'])         if not largs:
pygments/formatters/groff.py +1 lines
--- +++ @@ -106,3 +106,3 @@             if remainder > 0:-                newline += line[-remainder-1:]+                newline += line[length-remainder:]                 self._linelen = remainder
pygments/formatters/html.py +47 lines
--- +++ @@ -15,2 +15,3 @@ from io import StringIO+from html import escape as _escape @@ -18,5 +19,3 @@ from pygments.token import Token, Text, STANDARD_TYPES-from pygments.util import get_bool_opt, get_int_opt, get_list_opt--import html+from pygments.util import get_bool_opt, get_int_opt, get_list_opt, html_escape @@ -30,18 +29,4 @@ -_escape_html_table = {-    ord('&'): '&amp;',-    ord('<'): '&lt;',-    ord('>'): '&gt;',-    ord('"'): '&quot;',-    ord("'"): '&#39;',-}---def escape_html(text, table=_escape_html_table):-    """Escape &, <, > as well as single and double quotes for HTML."""-    return text.translate(table)-- def webify(color):-    if color.startswith('calc') or color.startswith('var'):+    if color == 'transparent' or color.startswith('calc') or color.startswith('var'):         return color@@ -426,4 +411,4 @@         self.classprefix = options.get('classprefix', '')-        self.cssclass = html.escape(self._decodeifneeded(options.get('cssclass', 'highlight')))-        self.cssstyles = html.escape(self._decodeifneeded(options.get('cssstyles', '')))+        self.cssclass = html_escape(self._decodeifneeded(options.get('cssclass', 'highlight')))+        self.cssstyles = html_escape(self._decodeifneeded(options.get('cssstyles', '')))         self.prestyles = self._decodeifneeded(options.get('prestyles', ''))@@ -433,3 +418,3 @@         self.tagurlformat = self._decodeifneeded(options.get('tagurlformat', ''))-        self.filename = html.escape(self._decodeifneeded(options.get('filename', '')))+        self.filename = html_escape(self._decodeifneeded(options.get('filename', '')))         self.wrapcode = get_bool_opt(options, 'wrapcode', False)@@ -456,5 +441,5 @@         self.nobackground = get_bool_opt(options, 'nobackground', False)-        self.lineseparator = html.escape(options.get('lineseparator', '\n'))-        self.lineanchors = html.escape(options.get('lineanchors', ''))-        self.linespans = html.escape(options.get('linespans', ''))+        self.lineseparator = html_escape(options.get('lineseparator', '\n'))+        self.lineanchors = html_escape(options.get('lineanchors', ''))+        self.linespans = html_escape(options.get('linespans', ''))         self.anchorlinenos = get_bool_opt(options, 'anchorlinenos', False)@@ -835,4 +820,10 @@     def _translate_parts(self, value):-        """HTML-escape a value and split it by newlines."""-        return value.translate(_escape_html_table).split('\n')+        """HTML-escape a value and split it by newlines.++        ``quote=False`` is intentional: token values are emitted as element+        text content (inside ``<span>``/``<pre>``), where ``"`` and ``'`` do+        not need escaping.  Skipping those two replacements is measurably+        faster on the per-token hot path.+        """+        return _escape(value, quote=False).split('\n') @@ -846,2 +837,4 @@         tagsfile = self.tagsfile+        span_openers = self.span_element_openers+        translate = self._translate_parts @@ -851,3 +844,3 @@             try:-                cspan = self.span_element_openers[ttype]+                cspan = span_openers[ttype]             except KeyError:@@ -867,5 +860,5 @@                         cspan = ''-                self.span_element_openers[ttype] = cspan--            parts = self._translate_parts(value)+                span_openers[ttype] = cspan++            parts = translate(value) @@ -884,27 +877,30 @@ -            # for all but the last line-            for part in parts[:-1]:-                if line:-                    # Also check for part being non-empty, so we avoid creating-                    # empty <span> tags-                    if lspan != cspan and part:-                        line.extend(((lspan and '</span>'), cspan, part,-                                     (cspan and '</span>'), lsep))-                    else:  # both are the same, or the current part was empty-                        line.extend((part, (lspan and '</span>'), lsep))-                    yield 1, ''.join(line)-                    line = []-                elif part:-                    yield 1, ''.join((cspan, part, (cspan and '</span>'), lsep))-                else:-                    yield 1, lsep+            # for all but the last line (skipped entirely for single-line+            # tokens, which are the common case, to avoid the parts[:-1] slice)+            if len(parts) > 1:+                for part in parts[:-1]:+                    if line:+                        # Also check for part being non-empty, so we avoid+                        # creating empty <span> tags+                        if lspan != cspan and part:+                            line.extend(((lspan and '</span>'), cspan, part,+                                         (cspan and '</span>'), lsep))+                        else:  # both are the same, or the current part was empty+                            line.extend((part, (lspan and '</span>'), lsep))+                        yield 1, ''.join(line)+                        line = []+                    elif part:+                        yield 1, ''.join((cspan, part, (cspan and '</span>'), lsep))+                    else:+                        yield 1, lsep             # for the last line-            if line and parts[-1]:+            last = parts[-1]+            if line and last:                 if lspan != cspan:-                    line.extend(((lspan and '</span>'), cspan, parts[-1]))+                    line.extend(((lspan and '</span>'), cspan, last))                     lspan = cspan                 else:-                    line.append(parts[-1])-            elif parts[-1]:-                line = [cspan, parts[-1]]+                    line.append(last)+            elif last:+                line = [cspan, last]                 lspan = cspan
pygments/formatters/latex.py +9 lines
--- +++ @@ -451,3 +451,11 @@         self.lang = lang-        Lexer.__init__(self, **options)+        # Inherit the wrapped lexer's options so that wrapping is+        # transparent: input-preprocessing options such as ``stripnl``,+        # ``stripall``, ``ensurenl`` and ``tabsize`` are applied by+        # ``Lexer.get_tokens`` on *this* lexer, so they must match the+        # wrapped lexer or its settings are silently overridden by our+        # defaults (e.g. ``stripnl=False`` would be ignored, stripping+        # leading/trailing blank lines). Options passed explicitly to this+        # lexer still take precedence.+        Lexer.__init__(self, **{**lang.options, **options}) 
pygments/formatters/other.py +1 lines
--- +++ @@ -108,3 +108,3 @@                 if ttype is Token.Error:-                    write(colorize(self.error_color, line))+                    write(colorize(self.error_color, line.decode()).encode())                 else:
pygments/formatters/svg.py +2 lines
--- +++ @@ -12,14 +12,5 @@ from pygments.token import Comment-from pygments.util import get_bool_opt, get_int_opt+from pygments.util import get_bool_opt, get_int_opt, html_escape  __all__ = ['SvgFormatter']---def escape_html(text):-    """Escape &, <, > as well as single and double quotes for HTML."""-    return text.replace('&', '&amp;').  \-                replace('<', '&lt;').   \-                replace('>', '&gt;').   \-                replace('"', '&quot;'). \-                replace("'", '&#39;') @@ -150,3 +141,3 @@             tspanend = tspan and '</tspan>' or ''-            value = escape_html(value)+            value = html_escape(value)             if self.spacehack:
pygments/formatters/terminal256.py +1 lines
--- +++ @@ -18,3 +18,3 @@ #  - Options to map style's bold/underline/italic/border attributes-#    to some ANSI attrbutes (something like 'italic=underline')+#    to some ANSI attributes (something like 'italic=underline') #  - An option to output "style RGB to xterm RGB/index" conversion table
pygments/lexer.py +1 lines
--- +++ @@ -336,3 +336,3 @@     """-    Indicates the a state should inherit from its superclass.+    Indicates that a state should inherit from its superclass.     """
pygments/lexers/_lua_builtins.py +1 lines
--- +++ @@ -183,3 +183,3 @@     # have only its name. Because of this, here are some callback functions-    # that recognize if a gioven function belongs to a specific module+    # that recognize if a given function belongs to a specific module     def module_callbacks():
pygments/lexers/_mapping.py +7 lines
--- +++ @@ -55,2 +55,3 @@     'BibTeXLexer': ('pygments.lexers.bibtex', 'BibTeX', ('bibtex', 'bib'), ('*.bib',), ('text/x-bibtex',)),+    'BitBakeLexer': ('pygments.lexers.bitbake', 'BitBake', ('bitbake',), ('*.bbclass', '*.bbappend'), ('text/x-bitbake',)),     'BlitzBasicLexer': ('pygments.lexers.basic', 'BlitzBasic', ('blitzbasic', 'b3d', 'bplus'), ('*.bb', '*.decls'), ('text/x-bb',)),@@ -65,2 +66,3 @@     'CAmkESLexer': ('pygments.lexers.esoteric', 'CAmkES', ('camkes', 'idl4'), ('*.camkes', '*.idl4'), ()),+    'CELLexer': ('pygments.lexers.cel', 'CEL', ('cel',), ('*.cel',), ()),     'CLexer': ('pygments.lexers.c_cpp', 'C', ('c',), ('*.c', '*.h', '*.idc', '*.x[bp]m'), ('text/x-chdr', 'text/x-csrc', 'image/x-xbitmap', 'image/x-xpixmap')),@@ -73,2 +75,3 @@     'Ca65Lexer': ('pygments.lexers.asm', 'ca65 assembler', ('ca65',), ('*.s',), ()),+    'CaddyfileLexer': ('pygments.lexers.configs', 'Caddyfile', ('caddyfile', 'caddy'), ('Caddyfile',), ()),     'CadlLexer': ('pygments.lexers.archetype', 'cADL', ('cadl',), ('*.cadl',), ()),@@ -104,3 +107,3 @@     'CplintLexer': ('pygments.lexers.cplint', 'cplint', ('cplint',), ('*.ecl', '*.prolog', '*.pro', '*.pl', '*.P', '*.lpad', '*.cpl'), ('text/x-cplint',)),-    'CppLexer': ('pygments.lexers.c_cpp', 'C++', ('cpp', 'c++'), ('*.cpp', '*.hpp', '*.c++', '*.h++', '*.cc', '*.hh', '*.cxx', '*.hxx', '*.C', '*.H', '*.cp', '*.CPP', '*.tpp', '*.cppm', '*.ixx', '*.mxx'), ('text/x-c++hdr', 'text/x-c++src')),+    'CppLexer': ('pygments.lexers.c_cpp', 'C++', ('cpp', 'c++'), ('*.cpp', '*.hpp', '*.c++', '*.h++', '*.cc', '*.hh', '*.cxx', '*.hxx', '*.C', '*.H', '*.cp', '*.CPP', '*.tpp', '*.cppm', '*.ixx', '*.mxx', '*.ipp'), ('text/x-c++hdr', 'text/x-c++src')),     'CppObjdumpLexer': ('pygments.lexers.asm', 'cpp-objdump', ('cpp-objdump', 'c++-objdumb', 'cxx-objdump'), ('*.cpp-objdump', '*.c++-objdump', '*.cxx-objdump'), ('text/x-cpp-objdump',)),@@ -413,2 +416,3 @@     'PuppetLexer': ('pygments.lexers.dsls', 'Puppet', ('puppet',), ('*.pp',), ()),+    'PureScriptLexer': ('pygments.lexers.purescript', 'PureScript', ('purescript', 'purs'), ('*.purs',), ('text/x-purescript',)),     'PyPyLogLexer': ('pygments.lexers.console', 'PyPy Log', ('pypylog', 'pypy'), ('*.pypylog',), ('application/x-pypylog',)),@@ -586,3 +590,3 @@     'XmlErbLexer': ('pygments.lexers.templates', 'XML+Ruby', ('xml+ruby', 'xml+erb'), (), ('application/xml+ruby',)),-    'XmlLexer': ('pygments.lexers.html', 'XML', ('xml',), ('*.xml', '*.xsl', '*.rss', '*.xslt', '*.xsd', '*.wsdl', '*.wsf', '*.xbrl', '*.pom'), ('text/xml', 'application/xml', 'image/svg+xml', 'application/rss+xml', 'application/atom+xml')),+    'XmlLexer': ('pygments.lexers.html', 'XML', ('xml',), ('*.xml', '*.xsl', '*.rss', '*.xslt', '*.xsd', '*.wsdl', '*.wsf', '*.xbrl', '*.pom', '*.svg'), ('text/xml', 'application/xml', 'image/svg+xml', 'application/rss+xml', 'application/atom+xml')),     'XmlPhpLexer': ('pygments.lexers.templates', 'XML+PHP', ('xml+php',), (), ('application/xml+php',)),@@ -595,3 +599,3 @@     'YamlJinjaLexer': ('pygments.lexers.templates', 'YAML+Jinja', ('yaml+jinja', 'salt', 'sls'), ('*.sls', '*.yaml.j2', '*.yml.j2', '*.yaml.jinja2', '*.yml.jinja2'), ('text/x-yaml+jinja', 'text/x-sls')),-    'YamlLexer': ('pygments.lexers.data', 'YAML', ('yaml',), ('*.yaml', '*.yml'), ('text/x-yaml',)),+    'YamlLexer': ('pygments.lexers.data', 'YAML', ('yaml', 'yml'), ('*.yaml', '*.yml'), ('text/x-yaml',)),     'YangLexer': ('pygments.lexers.yang', 'YANG', ('yang',), ('*.yang',), ('application/yang',)),
pygments/lexers/_vim_builtins.py +3748 lines
--- +++ @@ -12,2 +12,3697 @@ # per-method size limit.++def _getcommand():+    var = (+        ('a','a'),+        ('ab','abbreviate'),+        ('abc','abclear'),+        ('abs','abs'),+        ('acos','acos'),+        ('add','add'),+        ('al','all'),+        ('am','amenu'),+        ('an','anoremenu'),+        ('and','and'),+        ('append','append'),+        ('appendbufline','appendbufline'),+        ('ar','args'),+        ('arga','argadd'),+        ('argc','argc'),+        ('argd','argdelete'),+        ('argded','argdedupe'),+        ('arge','argedit'),+        ('argg','argglobal'),+        ('argidx','argidx'),+        ('argl','arglocal'),+        ('arglistid','arglistid'),+        ('argu','argument'),+        ('argv','argv'),+        ('argv','argv'),+        ('as','ascii'),+        ('asin','asin'),+        ('assert_beeps','assert_beeps'),+        ('assert_equal','assert_equal'),+        ('assert_equalfile','assert_equalfile'),+        ('assert_exception','assert_exception'),+        ('assert_fails','assert_fails'),+        ('assert_false','assert_false'),+        ('assert_inrange','assert_inrange'),+        ('assert_match','assert_match'),+        ('assert_nobeep','assert_nobeep'),+        ('assert_notequal','assert_notequal'),+        ('assert_notmatch','assert_notmatch'),+        ('assert_report','assert_report'),+        ('assert_true','assert_true'),+        ('atan','atan'),+        ('atan2','atan2'),+        ('aun','aunmenu'),+        ('autocmd_add','autocmd_add'),+        ('autocmd_delete','autocmd_delete'),+        ('autocmd_get','autocmd_get'),+        ('b','buffer'),+        ('bN','bNext'),+        ('ba','ball'),+        ('bad','badd'),+        ('balloon_gettext','balloon_gettext'),+        ('balloon_show','balloon_show'),+        ('balloon_split','balloon_split'),+        ('balt','balt'),+        ('base64_decode','base64_decode'),+        ('base64_encode','base64_encode'),+        ('bd','bdelete'),+        ('beval_bufnr','beval_bufnr'),+        ('beval_col','beval_col'),+        ('beval_lnum','beval_lnum'),+        ('beval_text','beval_text'),+        ('beval_winid','beval_winid'),+        ('beval_winnr','beval_winnr'),+        ('bf','bfirst'),+        ('bindtextdomain','bindtextdomain'),+        ('bl','blast'),+        ('blob2list','blob2list'),+        ('blob2str','blob2str'),+        ('bm','bmodified'),+        ('bn','bnext'),+        ('bp','bprevious'),+        ('br','brewind'),+        ('brea','break'),+        ('browse','browse'),+        ('browsedir','browsedir'),+        ('bufadd','bufadd'),+        ('bufexists','bufexists'),+        ('buffers','buffers'),+        ('buflisted','buflisted'),+        ('bufload','bufload'),+        ('bufloaded','bufloaded'),+        ('bufname','bufname'),+        ('bufnr','bufnr'),+        ('bufwinid','bufwinid'),+        ('bufwinnr','bufwinnr'),+        ('bun','bunload'),+        ('bw','bwipeout'),+        ('byte2line','byte2line'),+        ('byteidx','byteidx'),+        ('byteidxcomp','byteidxcomp'),+        ('cN','cNext'),+        ('cNf','cNfile'),+        ('ca','cabbrev'),+        ('cabc','cabclear'),+        ('cabo','cabove'),+        ('cad','caddbuffer'),+        ('cadde','caddexpr'),+        ('caddf','caddfile'),+        ('caf','cafter'),+        ('call','call'),+        ('cb','cbuffer'),+        ('cbe','cbefore'),+        ('cbel','cbelow'),+        ('cbo','cbottom'),+        ('cc','cc'),+        ('ccl','cclose'),+        ('ce','center'),+        ('ceil','ceil'),+        ('cex','cexpr'),+        ('cf','cfile'),+        ('cfir','cfirst'),+        ('cg','cgetfile'),+        ('cgetb','cgetbuffer'),+        ('cgete','cgetexpr'),+        ('ch_canread','ch_canread'),+        ('ch_close','ch_close'),+        ('ch_close_in','ch_close_in'),+        ('ch_evalexpr','ch_evalexpr'),+        ('ch_evalraw','ch_evalraw'),+        ('ch_getbufnr','ch_getbufnr'),+        ('ch_getjob','ch_getjob'),+        ('ch_info','ch_info'),+        ('ch_listen','ch_listen'),+        ('ch_log','ch_log'),+        ('ch_logfile','ch_logfile'),+        ('ch_open','ch_open'),+        ('ch_read','ch_read'),+        ('ch_readblob','ch_readblob'),+        ('ch_readraw','ch_readraw'),+        ('ch_sendexpr','ch_sendexpr'),+        ('ch_sendraw','ch_sendraw'),+        ('ch_setoptions','ch_setoptions'),+        ('ch_status','ch_status'),+        ('changenr','changenr'),+        ('changes','changes'),+        ('char','char'),+        ('char2nr','char2nr'),+        ('charclass','charclass'),+        ('charcol','charcol'),+        ('charconvert_from','charconvert_from'),+        ('charconvert_to','charconvert_to'),+        ('charidx','charidx'),+        ('chdir','chdir'),+        ('che','checkpath'),+        ('checkt','checktime'),+        ('chi','chistory'),+        ('cindent','cindent'),+        ('cl','clist'),+        ('cla','clast'),+        ('cle','clearjumps'),+        ('clearmatches','clearmatches'),+        ('clip','clipreset'),+        ('clipmethod','clipmethod'),+        ('clipproviders','clipproviders'),+        ('clo','close'),+        ('cm','cmap'),+        ('cmapc','cmapclear'),+        ('cmdarg','cmdarg'),+        ('cmdbang','cmdbang'),+        ('cmdcomplete_info','cmdcomplete_info'),+        ('cme','cmenu'),+        ('cn','cnext'),+        ('cnew','cnewer'),+        ('cnf','cnfile'),+        ('cno','cnoremap'),+        ('cnorea','cnoreabbrev'),+        ('cnoreme','cnoremenu'),+        ('col','col'),+        ('col','colder'),+        ('collate','collate'),+        ('colo','colorscheme'),+        ('colornames','colornames'),+        ('comc','comclear'),+        ('comp','compiler'),+        ('complete','complete'),+        ('complete_add','complete_add'),+        ('complete_check','complete_check'),+        ('complete_info','complete_info'),+        ('completed_item','completed_item'),+        ('con','continue'),+        ('confirm','confirm'),+        ('cope','copen'),+        ('copy','copy'),+        ('cos','cos'),+        ('cosh','cosh'),+        ('count','count'),+        ('count','count'),+        ('count1','count1'),+        ('cp','cprevious'),+        ('cpf','cpfile'),+        ('cq','cquit'),+        ('cr','crewind'),+        ('cs','cscope'),+        ('cscope_connection','cscope_connection'),+        ('cst','cstag'),+        ('ctype','ctype'),+        ('cuna','cunabbrev'),+        ('cunme','cunmenu'),+        ('cursor','cursor'),+        ('cw','cwindow'),+        ('debugbreak','debugbreak'),+        ('deepcopy','deepcopy'),+        ('defc','defcompile'),+        ('delel','delel'),+        ('delep','delep'),+        ('delete','delete'),+        ('deletebufline','deletebufline'),+        ('deletel','deletel'),+        ('deletep','deletep'),+        ('deletl','deletl'),+        ('deletp','deletp'),+        ('dell','dell'),+        ('delm','delmarks'),+        ('delp','delp'),+        ('dep','dep'),+        ('di','display'),+        ('did_filetype','did_filetype'),+        ('dif','diffupdate'),+        ('diff','diff'),+        ('diff_filler','diff_filler'),+        ('diff_hlID','diff_hlID'),+        ('diffg','diffget'),+        ('diffo','diffoff'),+        ('diffp','diffpatch'),+        ('diffpu','diffput'),+        ('diffs','diffsplit'),+        ('difft','diffthis'),+        ('dig','digraphs'),+        ('digraph_get','digraph_get'),+        ('digraph_getlist','digraph_getlist'),+        ('digraph_set','digraph_set'),+        ('digraph_setlist','digraph_setlist'),+        ('disa','disassemble'),+        ('dj','djump'),+        ('dl','dl'),+        ('dli','dlist'),+        ('dp','dp'),+        ('dr','drop'),+        ('ds','dsearch'),+        ('dsp','dsplit'),+        ('dying','dying'),+        ('e','edit'),+        ('ea','earlier'),
… 5376 more lines (truncated)
pygments/lexers/actionscript.py +1 lines
--- +++ @@ -71,3 +71,3 @@                 'GradientGlowFilter', 'GradientType', 'Graphics', 'GridFitType', 'HTTPStatusEvent',-                'IBitmapDrawable', 'ID3Info', 'IDataInput', 'IDataOutput', 'IDynamicPropertyOutput'+                'IBitmapDrawable', 'ID3Info', 'IDataInput', 'IDataOutput', 'IDynamicPropertyOutput',                 'IDynamicPropertyWriter', 'IEventDispatcher', 'IExternalizable',
pygments/lexers/ada.py +0 lines
--- +++ @@ -39,3 +39,2 @@             (r'--.*?\n', Comment.Single),-            (r'[^\S\n]+', Text),             (r'function|procedure|entry', Keyword.Declaration, 'subprogram'),
pygments/lexers/algebra.py +3 lines
--- +++ @@ -179,2 +179,5 @@ +            # Named character escapes, e.g. \[Nu], \[CapitalAlpha].+            (r'\\\[[A-Za-z][A-Za-z0-9]*\]', String.Escape),+             (r'([a-zA-Z]+[A-Za-z0-9]*`)', Name.Namespace),
pygments/lexers/amdgpu.py +1 lines
--- +++ @@ -47,3 +47,3 @@             (r'(_L[0-9]*)', Name.Variable),-            (r'(s|v)_[a-z0-9_]+', Keyword),+            (r'[sv]_[a-z0-9_]+', Keyword),             (r'(v[0-9.]+|vcc|exec|v)', Name.Variable),
pygments/lexers/ampl.py +1 lines
--- +++ @@ -32,3 +32,3 @@             (r'#.*?\n', Comment.Single),-            (r'/[*](.|\n)*?[*]/', Comment.Multiline),+            (r'/[*][\s\S]*?[*]/', Comment.Multiline),             (words((
pygments/lexers/asm.py +6 lines
--- +++ @@ -260,3 +260,3 @@     hexfloat = r'0[xX](([0-9a-fA-F]+\.[0-9a-fA-F]*)|([0-9a-fA-F]*\.[0-9a-fA-F]+))[pP][+-]?\d+'-    ieeefloat = r'0((h|H)[0-9a-fA-F]{4}|(f|F)[0-9a-fA-F]{8}|(d|D)[0-9a-fA-F]{16})'+    ieeefloat = r'0(?:[hH][0-9a-fA-F]{4}|[fF][0-9a-fA-F]{8}|[dD][0-9a-fA-F]{16})' @@ -287,3 +287,3 @@         'whitespace': [-            (r'(\n|\s)+', Whitespace),+            (r'\s+', Whitespace),         ],@@ -398,3 +398,3 @@         'whitespace': [-            (r'(\n|\s+)+', Whitespace),+            (r'\s+', Whitespace),             (r';.*?\n', Comment),@@ -678,3 +678,3 @@             # Delegate to the LlvmLexer-            (r'((?:.|\n)+?)(?=(\.\.\.|---))', bygroups(using(LlvmLexer))),+            (r'([\s\S]+?)(?=(\.\.\.|---))', bygroups(using(LlvmLexer))),         ],@@ -719,6 +719,6 @@             # Delegate the body block to the LlvmMirBodyLexer-            (r'((?:.|\n)+?)(?=\.\.\.|---)', bygroups(using(LlvmMirBodyLexer))),+            (r'([\s\S]+?)(?=\.\.\.|---)', bygroups(using(LlvmMirBodyLexer))),             # The '...' is optional. If we didn't already find it then it isn't             # there. There might be a '---' instead though.-            (r'(?!\.\.\.|---)((?:.|\n)+)', bygroups(using(LlvmMirBodyLexer))),+            (r'(?!\.\.\.|---)([\s\S]+)', bygroups(using(LlvmMirBodyLexer))),         ],
pygments/lexers/automation.py +1 lines
--- +++ @@ -317,3 +317,3 @@             (r';.*\n', Comment.Single),-            (r'(#comments-start|#cs)(.|\n)*?(#comments-end|#ce)',+            (r'(#comments-start|#cs)[\s\S]*?(#comments-end|#ce)',              Comment.Multiline),
pygments/lexers/basic.py +1 lines
--- +++ @@ -50,3 +50,3 @@             (r"'.*?\n", Comment.Single),-            (r'([ \t]*)\bRem\n(\n|.)*?\s*\bEnd([ \t]*)Rem', Comment.Multiline),+            (r'([ \t]*)\bRem\n[\s\S]*?\s*\bEnd([ \t]*)Rem', Comment.Multiline),             # Data types@@ -459,3 +459,2 @@             (r'\-?\d+#?', Number.Integer.Long),-            (r'\-?\d+#?', Number.Integer),             (r'!=|==|:=|\.=|<<|>>|[-~+/\\*%=<>&^|?:!.]', Operator),
pygments/lexers/berry.py +1 lines
--- +++ @@ -56,3 +56,3 @@             (r'\s+', Whitespace),-            (r'#-(.|\n)*?-#', Comment.Multiline),+            (r'#-[\s\S]*?-#', Comment.Multiline),             (r'#.*?$', Comment.Single)
pygments/lexers/business.py +2 lines
--- +++ @@ -89,3 +89,3 @@                 'ALPHABET', 'ALPHABETIC', 'ALPHABETIC-LOWER', 'ALPHABETIC-UPPER',-                'ALPHANUMERIC', 'ALPHANUMERIC-EDITED', 'ALSO', 'ALTER', 'ALTERNATE'+                'ALPHANUMERIC', 'ALPHANUMERIC-EDITED', 'ALSO', 'ALTER', 'ALTERNATE',                 'ANY', 'ARE', 'AREA', 'AREAS', 'ARGUMENT-NUMBER', 'ARGUMENT-VALUE', 'AS',@@ -287,3 +287,3 @@             # call methodnames returning style-            (r'(?<=(=|-)>)([\w\-~]+)(?=\()', Name.Function),+            (r'(?<=[=-]>)([\w\-~]+)(?=\()', Name.Function), 
python-dateutil pypi
2.9.0.post0 2y ago nominal
INSTALL-EXEC
latest 2.9.0.post0 versions 34 maintainers 1
2.6.0
2.6.1
2.7.0
2.7.1
2.7.2
2.7.3
2.7.4
2.7.5
2.8.0
2.8.1
2.8.2
2.9.0
INSTALL-EXEC
setup.py in sdist uses install-hook (runs at pip install)
warn · snapshot-derived
release diff 2.8.2 → 2.9.0
+43 added · -41 removed · ~20 modified
new files touching dangerous APIs: src/dateutil/zoneinfo/rebuild.py, tests/_common.py, tests/test_tz.py
+15 more files not shown
src/dateutil/zoneinfo/rebuild.py +75 lines · 1 flagged
--- +++ @@ -0,0 +1,75 @@+import logging+import os+import tempfile+import shutil+import json+from subprocess import check_call, check_output+from tarfile import TarFile++from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME+++def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):+    """Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar*++    filename is the timezone tarball from ``ftp.iana.org/tz``.++    """+    tmpdir = tempfile.mkdtemp()+    zonedir = os.path.join(tmpdir, "zoneinfo")+    moduledir = os.path.dirname(__file__)+    try:+        with TarFile.open(filename) as tf:+            for name in zonegroups:+                tf.extract(name, tmpdir)+            filepaths = [os.path.join(tmpdir, n) for n in zonegroups]++            _run_zic(zonedir, filepaths)++        # write metadata file+        with open(os.path.join(zonedir, METADATA_FN), 'w') as f:+            json.dump(metadata, f, indent=4, sort_keys=True)+        target = os.path.join(moduledir, ZONEFILENAME)+        with TarFile.open(target, "w:%s" % format) as tf:+            for entry in os.listdir(zonedir):+                entrypath = os.path.join(zonedir, entry)+                tf.add(entrypath, entry)+    finally:+        shutil.rmtree(tmpdir)+++def _run_zic(zonedir, filepaths):+    """Calls the ``zic`` compiler in a compatible way to get a "fat" binary.++    Recent versions of ``zic`` default to ``-b slim``, while older versions+    don't even have the ``-b`` option (but default to "fat" binaries). The+    current version of dateutil does not support Version 2+ TZif files, which+    causes problems when used in conjunction with "slim" binaries, so this+    function is used to ensure that we always get a "fat" binary.+    """++    try:+        help_text = check_output(["zic", "--help"])+    except OSError as e:+        _print_on_nosuchfile(e)+        raise++    if b"-b " in help_text:+        bloat_args = ["-b", "fat"]+    else:+        bloat_args = []++    check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths)+++def _print_on_nosuchfile(e):+    """Print helpful troubleshooting message++    e is an exception raised by subprocess.check_call()++    """+    if e.errno == 2:+        logging.error(+            "Could not find zic. Perhaps you need to install "+            "libc-bin or some other package that provides it, "+            "or it's not in your PATH?")
tests/_common.py +233 lines · 2 flagged
--- +++ @@ -0,0 +1,233 @@+from __future__ import unicode_literals+import os+import time+import subprocess+import warnings+import tempfile+import pickle++import pytest+++class PicklableMixin(object):+    def _get_nobj_bytes(self, obj, dump_kwargs, load_kwargs):+        """+        Pickle and unpickle an object using ``pickle.dumps`` / ``pickle.loads``+        """+        pkl = pickle.dumps(obj, **dump_kwargs)+        return pickle.loads(pkl, **load_kwargs)++    def _get_nobj_file(self, obj, dump_kwargs, load_kwargs):+        """+        Pickle and unpickle an object using ``pickle.dump`` / ``pickle.load`` on+        a temporary file.+        """+        with tempfile.TemporaryFile('w+b') as pkl:+            pickle.dump(obj, pkl, **dump_kwargs)+            pkl.seek(0)         # Reset the file to the beginning to read it+            nobj = pickle.load(pkl, **load_kwargs)++        return nobj++    def assertPicklable(self, obj, singleton=False, asfile=False,+                        dump_kwargs=None, load_kwargs=None):+        """+        Assert that an object can be pickled and unpickled. This assertion+        assumes that the desired behavior is that the unpickled object compares+        equal to the original object, but is not the same object.+        """+        get_nobj = self._get_nobj_file if asfile else self._get_nobj_bytes+        dump_kwargs = dump_kwargs or {}+        load_kwargs = load_kwargs or {}++        nobj = get_nobj(obj, dump_kwargs, load_kwargs)+        if not singleton:+            self.assertIsNot(obj, nobj)+        self.assertEqual(obj, nobj)+++class TZContextBase(object):+    """+    Base class for a context manager which allows changing of time zones.++    Subclasses may define a guard variable to either block or or allow time+    zone changes by redefining ``_guard_var_name`` and ``_guard_allows_change``.+    The default is that the guard variable must be affirmatively set.++    Subclasses must define ``get_current_tz`` and ``set_current_tz``.+    """+    _guard_var_name = "DATEUTIL_MAY_CHANGE_TZ"+    _guard_allows_change = True++    def __init__(self, tzval):+        self.tzval = tzval+        self._old_tz = None++    @classmethod+    def tz_change_allowed(cls):+        """+        Class method used to query whether or not this class allows time zone+        changes.+        """+        guard = bool(os.environ.get(cls._guard_var_name, False))++        # _guard_allows_change gives the "default" behavior - if True, the+        # guard is overcoming a block. If false, the guard is causing a block.+        # Whether tz_change is allowed is therefore the XNOR of the two.+        return guard == cls._guard_allows_change++    @classmethod+    def tz_change_disallowed_message(cls):+        """ Generate instructions on how to allow tz changes """+        msg = ('Changing time zone not allowed. Set {envar} to {gval} '+               'if you would like to allow this behavior')++        return msg.format(envar=cls._guard_var_name,+                          gval=cls._guard_allows_change)++    def __enter__(self):+        if not self.tz_change_allowed():+            msg = self.tz_change_disallowed_message()+            pytest.skip(msg)++            # If this is used outside of a test suite, we still want an error.+            raise ValueError(msg)  # pragma: no cover++        self._old_tz = self.get_current_tz()+        self.set_current_tz(self.tzval)++    def __exit__(self, type, value, traceback):+        if self._old_tz is not None:+            self.set_current_tz(self._old_tz)++        self._old_tz = None++    def get_current_tz(self):+        raise NotImplementedError++    def set_current_tz(self):+        raise NotImplementedError+++class TZEnvContext(TZContextBase):+    """+    Context manager that temporarily sets the `TZ` variable (for use on+    *nix-like systems). Because the effect is local to the shell anyway, this+    will apply *unless* a guard is set.++    If you do not want the TZ environment variable set, you may set the+    ``DATEUTIL_MAY_NOT_CHANGE_TZ_VAR`` variable to a truthy value.+    """+    _guard_var_name = "DATEUTIL_MAY_NOT_CHANGE_TZ_VAR"+    _guard_allows_change = False++    def get_current_tz(self):+        return os.environ.get('TZ', UnsetTz)++    def set_current_tz(self, tzval):+        if tzval is UnsetTz and 'TZ' in os.environ:+            del os.environ['TZ']+        else:+            os.environ['TZ'] = tzval++        time.tzset()+++class TZWinContext(TZContextBase):+    """+    Context manager for changing local time zone on Windows.++    Because the effect of this is system-wide and global, it may have+    unintended side effect. Set the ``DATEUTIL_MAY_CHANGE_TZ`` environment+    variable to a truthy value before using this context manager.+    """+    def get_current_tz(self):+        p = subprocess.Popen(['tzutil', '/g'], stdout=subprocess.PIPE)++        ctzname, err = p.communicate()+        ctzname = ctzname.decode()     # Popen returns++        if p.returncode:+            raise OSError('Failed to get current time zone: ' + err)++        return ctzname++    def set_current_tz(self, tzname):+        p = subprocess.Popen('tzutil /s "' + tzname + '"')++        out, err = p.communicate()++        if p.returncode:+            raise OSError('Failed to set current time zone: ' ++                          (err or 'Unknown error.'))+++###+# Utility classes+class NotAValueClass(object):+    """+    A class analogous to NaN that has operations defined for any type.+    """+    def _op(self, other):+        return self             # Operation with NotAValue returns NotAValue++    def _cmp(self, other):+        return False++    __add__ = __radd__ = _op+    __sub__ = __rsub__ = _op+    __mul__ = __rmul__ = _op+    __div__ = __rdiv__ = _op+    __truediv__ = __rtruediv__ = _op+    __floordiv__ = __rfloordiv__ = _op++    __lt__ = __rlt__ = _op+    __gt__ = __rgt__ = _op+    __eq__ = __req__ = _op+    __le__ = __rle__ = _op+    __ge__ = __rge__ = _op+++NotAValue = NotAValueClass()+++class ComparesEqualClass(object):+    """+    A class that is always equal to whatever you compare it to.+    """++    def __eq__(self, other):+        return True++    def __ne__(self, other):+        return False++    def __le__(self, other):+        return True++    def __ge__(self, other):+        return True++    def __lt__(self, other):+        return False++    def __gt__(self, other):+        return False++    __req__ = __eq__+    __rne__ = __ne__+    __rle__ = __le__+    __rge__ = __ge__+    __rlt__ = __lt__+    __rgt__ = __gt__+++ComparesEqual = ComparesEqualClass()+++class UnsetTzClass(object):+    """ Sentinel class for unset time zone variable """+    pass+++UnsetTz = UnsetTzClass()
tests/test_tz.py +2811 lines · 14 flagged
--- +++ @@ -0,0 +1,2811 @@+# -*- coding: utf-8 -*-+from __future__ import unicode_literals+from ._common import PicklableMixin+from ._common import TZEnvContext, TZWinContext+from ._common import ComparesEqual++from datetime import datetime, timedelta+from datetime import time as dt_time+from datetime import tzinfo+from six import PY2+from io import BytesIO, StringIO+import unittest++import sys+import base64+import copy+import gc+import weakref++from functools import partial++IS_WIN = sys.platform.startswith('win')++import pytest++# dateutil imports+from dateutil.relativedelta import relativedelta, SU, TH+from dateutil.parser import parse+from dateutil import tz as tz+from dateutil import zoneinfo++try:+    from dateutil import tzwin+except ImportError as e:+    if IS_WIN:+        raise e+    else:+        pass++MISSING_TARBALL = ("This test fails if you don't have the dateutil "+                   "timezone file installed. Please read the README")++TZFILE_EST5EDT = b"""+VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAADrAAAABAAAABCeph5wn7rrYKCGAHCh+ms1gomXicKOD6eCkaq5wpTWnYKZTyvCnFYlgqDOs8Kj+peCqE47wqt6H4KvzcPCsvmngrdNS8K6e+S+CvszTwsH4t4LGcUXCyZ0pgs3wzcLRHLGC1XBVwticOYLc793C4BvBguRvZcLnm0mC7BPXwu8a0+YLzk1/C9r9DgvsS58L+PsuDApJvwwW+U4MKEffDDT3bgxGRf8MUvWODGTXxwxw864MgtXnDI+Fdg+yg1AcMrYOWDLiPBw0iP0cNJg++DTdeTw1EDd4NVVxvDWIL/g1zWo8NgAoeDZFYrw2eCD4Nr+p3Db+wGXg3N6JcN2pgmDevmtw34lkYOCeTXDhaUZg4n4vcONJKGDkXhFw5Vcu4OZHLfDnNxDg6CcP8OkW+8uDqBvHw6vbU4Ovm0/Ds1rbg7ca18O6/02Dvr9Jw8J+1YPGPtHDyf5dg82+WcPRfeWD1T3hw9j9b+YPcvWnD4KHfg+Q88cPoIWeD6+Fjw++g74PzYOvD9yB3g/rgc8P+n/+AAl/7wAYfh4AJ34PADcP5g+BGD9cAVQ4GAGQN9wBzDCYAeNGXAJEKRgCa2U8ArwhmAL4IVwDNmi4A3AZ3AOuYTgD6mD8BCZZuAR+iWXwEnlI4BNpR/AUWSrgFUkp8BY5DOAXKQvwGCIpYBkI7fAaAgtgGvIKcBvh7WAc0exwHcHPYB6x+znAfobFgIHYA8CGBk2AiVeLwI2qv4CQ1xPAlSpHgJhWm8Ccqc+An/sNwKQpV4CnepXAq6jfgK76H+cCzTVGAtnmlwLrM2YC9+S3AwkxhgMWdn8DJy+mAzR0nwNFLcYDUnK/A2Mr5gNwcN8Dgb2uA45u/w+Ofu84DrG0fA7257gPK/ucD27gOA+j9BwP5ti4EBvsnBBhH9gQk+UcENkYWBEL3ZwRURDYEYPWHBH+JCVgR/h08EkEB2BJ2FbwSuPpYEu4OPBMzQXgTZga8E6s5+BPd/zwUIzJ4FFhGXBSbKvgU0D7cFRM+jeBVIN1wVixv4FcAv3BYFYxgWOChcFn1bmBawINwW9VQYFypn/BdtTJgXomB8F+VFGBgaWPwYX4w+4GJJRfBjXhLgZCkn8GU99OBmEkRwZx3W4GfyJnBo/bjgadIIcGrdmuBrsepwbMa3YG2RzHBupplg+b3GucHCGe2BxWsrwcmZdYHM6rPB0Rj9gdRqO8HYvW+B2+nDweA894HjaUvB57x/gero08HvPAeB8+o1Fwfa7j4H6DM3B/jsXgAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAgMBAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA+AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAAEAAQABAAEAAQABAAEAAf//x8ABAP//ubAABP//x8ABCP//x8ABDEVEVABFU1QARVdU+AEVQVAAAAAABAAAAAQ==+"""++EUROPE_HELSINKI = b"""+VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABQAAAAAAAAB1AAAABQAAAA2kc28Yy85RYMy/hdAV+I+uQFhPckBcDzZAX876QGOOvkBnToJAaw5GQG7y9EBysrhAdnJ8QHoyQEB98gRAgbHIQIVxjECJM+VBAjPEUQJCw2ECUcJxAmDBgQJwVDkCf1NJAo5SWQKdUWkCrFB5ArtPiQLKTpkC2U2pAuhMuQL3S8+kDBkrZAxXdkQMnK0EDM9uxA0UpYQNR2dEDYyeBA2/X8QOBuUkDjdYRA5+3aQOr1DEDvbWJA8pl+Q+Pbs6kD6GQZA/mxyQQGYjkEGEORBCRgWQQ2QbEEQl55BFQ/0QRgXJkEcj3xBH7uYQSQPBEEnOyBBK+46MQS66qEEzMv5BNjowQTqyhkE9ubhBQjIOQUVeKkFJsZZBTN2yQVExHkFUXTpBWLCmQVvcwkFgV+RhBY1xKQWfUoEFq29JBb1QoQXKAREF207BBef/MQX5TOEGBf1RBhfeqQYj+3EGNdzJBkH5kQZT2u+kGYItZBnHZCQZ+iXkGj9cpBpyHmQat1UkGuoW5BsxnEQbYg9kG6mUxBvaB+QcIY1EHFRPBByZhcQ+czEeEHRF+RB1EQAQdi8VkHbw4hB4DveQeNDEEHnu2ZB6sKYQe867kHyZwpB9rp2QfnmkkH+Of5AC+AQIDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQD+BAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAMEAwQDBAME+AwQAABdoAAAAACowAQQAABwgAAkAACowAQQAABwgAAlITVQARUVTVABFRVQAAAAAAQEAAAABAQ==+"""++NEW_YORK = b"""+VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABcAAADrAAAABAAAABCeph5wn7rrYKCGAHCh+ms1gomXicKOD6eCkaq5wpTWnYKZTyvCnFYlgqDOs8Kj+peCqE47wqt6H4KvzcPCsvmngrdNS8K6e+S+CvszTwsH4t4LGcUXCyZ0pgs3wzcLRHLGC1XBVwticOYLc793C4BvBguRvZcLnm0mC7BPXwu8a0+YLzk1/C9r9DgvsS58L+PsuDApJvwwW+U4MKEffDDT3bgxGRf8MUvWODGTXxwxw864MgtXnDI+Fdg+yg1AcMrYOWDLiPBw0iP0cNJg++DTdeTw1EDd4NVVxvDWIL/g1zWo8NgAoeDZFYrw2eCD4Nr+p3Db+wGXg3N6JcN2pgmDevmtw34lkYOCeTXDhaUZg4n4vcONJKGDkXhFw5Vcu4OZHLfDnNxDg6CcP8OkW+8uDqBvHw6vbU4Ovm0/Ds1rbg7ca18O6/02Dvr9Jw8J+1YPGPtHDyf5dg82+WcPRfeWD1T3hw9j9b+YPcvWnD4KHfg+Q88cPoIWeD6+Fjw++g74PzYOvD9yB3g/rgc8P+n/+AAl/7wAYfh4AJ34PADcP5g+BGD9cAVQ4GEGQN9yBzDCYgeNGXMJEKRjCa2U9ArwhmQL4IV1DNmi5Q3AZ3YOuYTmD6mD9xCZZucR+iWX4EnlI6BNpR/kUWSrpFUkp+RY5DOoXKQv6GCIpaxkI7fsaAgtsGvIKfBvh7Wwc0ex8HcHPbR6x+zn0fobFtIHYA/SGBk20iVeL+I2qv7iQ1xP4lSpHuJhWm/ycqc+8n/sOAKQpV8CnepYAq6jfxK76H+gSzTVHItnmmCLrM2cy9+S4MwkxhzMWdoBDJy+nQzR0oENFLcdTUnLAU2Mr51NwcOBjgb2vY45vAG+Ofu89jrG0gY72572PK/uhj27gPY+j9CGP5ti9kBvsoZBhH92Qk+UhkNkYXZEL3aHRURDd0XzqQdH+LV/3R9OLB0kNQfdJs20HSu0j90uciYdM1kB3TXxrh062IndPXE2HUJYEd1E8L4dSdeZ3UxwRh1RV+yHdU+/OHVjWqd1blEAdYHsb3WMTyB1n+qPdapNQHW96K91yEtgddvmz3XmSYB1+eTvdgTbSHYYdr+d2ItlodjZ013ZA14h2VHL3dl7VqHZycRd2fNPIdpBvN3aa0eh2rm1XdrljsHbM/x9212HQdur9P3+b1X/B3CPtfdxNeEHcm+X93MVwwd0T3n3dP7fh3Y4lnd23sGHeBh4d3i+o4d5+Fp3ep6Fh3vYPHd8+fmeHfbged35eSYd/mAB3AAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAgMBAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEA+AQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAB+AAEAAQABAAEAAQABAAEAAQABAAEAAf//x8ABAP//ubAABP//x8ABCP//x8ABDEVEVABFU1QARVdU+AEVQVAAEslgAAAAAAQWk7AEAAAACB4YfggAAAAMJZ1MDAAAABAtIhoQAAAAFDSsLhQAAAAYPDD8G+AAAABxDtcocAAAAIEs6mCAAAAAkVn8qJAAAACheA/goAAAALGWIxiwAAAAwdJeoMAAAADSHa5Q0A+AAAOJZ6djgAAAA8nf9EPAAAAECpQ9ZAAAAARLDIpEQAAABIuE1ySAAAAEzDnJBMAAAAUM7hIlAAA+ABU2jBAVAAAAFkO3G5YAAAAXAAAAAQAAAAE=+"""++TZICAL_EST5EDT = """+BEGIN:VTIMEZONE+TZID:US-Eastern+LAST-MODIFIED:19870101T000000Z+TZURL:http://zones.stds_r_us.net/tz/US-Eastern+BEGIN:STANDARD+DTSTART:19671029T020000+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10+TZOFFSETFROM:-0400+TZOFFSETTO:-0500+TZNAME:EST+END:STANDARD+BEGIN:DAYLIGHT+DTSTART:19870405T020000+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4+TZOFFSETFROM:-0500+TZOFFSETTO:-0400+TZNAME:EDT+END:DAYLIGHT+END:VTIMEZONE+"""++TZICAL_PST8PDT = """+BEGIN:VTIMEZONE+TZID:US-Pacific+LAST-MODIFIED:19870101T000000Z+BEGIN:STANDARD+DTSTART:19671029T020000+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10+TZOFFSETFROM:-0700+TZOFFSETTO:-0800+TZNAME:PST+END:STANDARD+BEGIN:DAYLIGHT+DTSTART:19870405T020000+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4+TZOFFSETFROM:-0800+TZOFFSETTO:-0700+TZNAME:PDT+END:DAYLIGHT+END:VTIMEZONE+"""++EST_TUPLE = ('EST', timedelta(hours=-5), timedelta(hours=0))+EDT_TUPLE = ('EDT', timedelta(hours=-4), timedelta(hours=1))++SUPPORTS_SUB_MINUTE_OFFSETS = sys.version_info >= (3, 6)+++###+# Helper functions+def get_timezone_tuple(dt):+    """Retrieve a (tzname, utcoffset, dst) tuple for a given DST"""+    return dt.tzname(), dt.utcoffset(), dt.dst()+++###+# Mix-ins+class context_passthrough(object):+    def __init__(*args, **kwargs):+        pass++    def __enter__(*args, **kwargs):+        pass++    def __exit__(*args, **kwargs):+        pass+++class TzFoldMixin(object):+    """ Mix-in class for testing ambiguous times """+    def gettz(self, tzname):+        raise NotImplementedError++    def _get_tzname(self, tzname):+        return tzname++    def _gettz_context(self, tzname):+        return context_passthrough()++    def testFoldPositiveUTCOffset(self):+        # Test that we can resolve ambiguous times+        tzname = self._get_tzname('Australia/Sydney')++        with self._gettz_context(tzname):+            SYD = self.gettz(tzname)++            t0_u = datetime(2012, 3, 31, 15, 30, tzinfo=tz.UTC)  # AEST+            t1_u = datetime(2012, 3, 31, 16, 30, tzinfo=tz.UTC)  # AEDT++            t0_syd0 = t0_u.astimezone(SYD)+            t1_syd1 = t1_u.astimezone(SYD)++            self.assertEqual(t0_syd0.replace(tzinfo=None),+                             datetime(2012, 4, 1, 2, 30))++            self.assertEqual(t1_syd1.replace(tzinfo=None),+                             datetime(2012, 4, 1, 2, 30))++            self.assertEqual(t0_syd0.utcoffset(), timedelta(hours=11))+            self.assertEqual(t1_syd1.utcoffset(), timedelta(hours=10))++    def testGapPositiveUTCOffset(self):+        # Test that we don't have a problem around gaps.+        tzname = self._get_tzname('Australia/Sydney')++        with self._gettz_context(tzname):+            SYD = self.gettz(tzname)++            t0_u = datetime(2012, 10, 6, 15, 30, tzinfo=tz.UTC)  # AEST+            t1_u = datetime(2012, 10, 6, 16, 30, tzinfo=tz.UTC)  # AEDT++            t0 = t0_u.astimezone(SYD)+            t1 = t1_u.astimezone(SYD)++            self.assertEqual(t0.replace(tzinfo=None),+                             datetime(2012, 10, 7, 1, 30))++            self.assertEqual(t1.replace(tzinfo=None),+                             datetime(2012, 10, 7, 3, 30))++            self.assertEqual(t0.utcoffset(), timedelta(hours=10))+            self.assertEqual(t1.utcoffset(), timedelta(hours=11))++    def testFoldNegativeUTCOffset(self):+            # Test that we can resolve ambiguous times+            tzname = self._get_tzname('America/Toronto')++            with self._gettz_context(tzname):+                TOR = self.gettz(tzname)++                t0_u = datetime(2011, 11, 6, 5, 30, tzinfo=tz.UTC)+                t1_u = datetime(2011, 11, 6, 6, 30, tzinfo=tz.UTC)++                t0_tor = t0_u.astimezone(TOR)
… 2564 more lines (truncated)
ci_tools/run_tz_master_env.sh +2 lines
--- +++ @@ -13,3 +13,3 @@ -REPO_TARBALL=${REPO_DIR}/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz+REPO_TARBALL=${REPO_DIR}/src/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz TMP_TARBALL=${TMP_DIR}/dateutil-zoneinfo.tar.gz@@ -95,3 +95,3 @@ # Run the tests-python -m pytest ${REPO_DIR}/dateutil/test $EXTRA_TEST_ARGS+python -m pytest ${REPO_DIR}/tests $EXTRA_TEST_ARGS 
pyproject.toml +18 lines
--- +++ @@ -48 +48,19 @@ +[tool.black]+line-length = 80++[tool.isort]+atomic=true+force_grid_wrap=0+include_trailing_comma=true+known_first_party = ["dateutil"]+known_third_party=[+    "pytest",+    "hypothesis",+    "six",+    "freezegun",+    "mock",+]+multi_line_output=3+use_parentheses=true+
setup.cfg +6 lines
--- +++ @@ -33,2 +33,5 @@ 	Programming Language :: Python :: 3.9+	Programming Language :: Python :: 3.10+	Programming Language :: Python :: 3.11+	Programming Language :: Python :: 3.12 	Topic :: Software Development :: Libraries@@ -39,9 +42,9 @@ install_requires = six >= 1.5+package_dir = +	=src python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.* packages = find:-test_suite = dateutil.test  [options.packages.find]-exclude = -	dateutil.test+where = src 
setup.py +1 lines
--- +++ @@ -50,3 +50,3 @@       use_scm_version={-          'write_to': 'dateutil/_version.py',+          'write_to': 'src/dateutil/_version.py',       },
src/dateutil/__init__.py +24 lines
--- +++ @@ -0,0 +1,24 @@+# -*- coding: utf-8 -*-+import sys++try:+    from ._version import version as __version__+except ImportError:+    __version__ = 'unknown'++__all__ = ['easter', 'parser', 'relativedelta', 'rrule', 'tz',+           'utils', 'zoneinfo']++def __getattr__(name):+    import importlib++    if name in __all__:+        return importlib.import_module("." + name, __name__)+    raise AttributeError(+        "module {!r} has not attribute {!r}".format(__name__, name)+    )+++def __dir__():+    # __dir__ should include all the lazy-importable modules as well.+    return [x for x in globals() if x not in sys.modules] + __all__
src/dateutil/_common.py +43 lines
--- +++ @@ -0,0 +1,43 @@+"""+Common code used in multiple modules.+"""+++class weekday(object):+    __slots__ = ["weekday", "n"]++    def __init__(self, weekday, n=None):+        self.weekday = weekday+        self.n = n++    def __call__(self, n):+        if n == self.n:+            return self+        else:+            return self.__class__(self.weekday, n)++    def __eq__(self, other):+        try:+            if self.weekday != other.weekday or self.n != other.n:+                return False+        except AttributeError:+            return False+        return True++    def __hash__(self):+        return hash((+          self.weekday,+          self.n,+        ))++    def __ne__(self, other):+        return not (self == other)++    def __repr__(self):+        s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]+        if not self.n:+            return s+        else:+            return "%s(%+d)" % (s, self.n)++# vim:ts=4:sw=4:et
src/dateutil/_version.py +16 lines
--- +++ @@ -0,0 +1,16 @@+# file generated by setuptools_scm+# don't change, don't track in version control+TYPE_CHECKING = False+if TYPE_CHECKING:+    from typing import Tuple, Union+    VERSION_TUPLE = Tuple[Union[int, str], ...]+else:+    VERSION_TUPLE = object++version: str+__version__: str+__version_tuple__: VERSION_TUPLE+version_tuple: VERSION_TUPLE++__version__ = version = '2.9.0'+__version_tuple__ = version_tuple = (2, 9, 0)
src/dateutil/easter.py +89 lines
--- +++ @@ -0,0 +1,89 @@+# -*- coding: utf-8 -*-+"""+This module offers a generic Easter computing method for any given year, using+Western, Orthodox or Julian algorithms.+"""++import datetime++__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"]++EASTER_JULIAN = 1+EASTER_ORTHODOX = 2+EASTER_WESTERN = 3+++def easter(year, method=EASTER_WESTERN):+    """+    This method was ported from the work done by GM Arts,+    on top of the algorithm by Claus Tondering, which was+    based in part on the algorithm of Ouding (1940), as+    quoted in "Explanatory Supplement to the Astronomical+    Almanac", P.  Kenneth Seidelmann, editor.++    This algorithm implements three different Easter+    calculation methods:++    1. Original calculation in Julian calendar, valid in+       dates after 326 AD+    2. Original method, with date converted to Gregorian+       calendar, valid in years 1583 to 4099+    3. Revised method, in Gregorian calendar, valid in+       years 1583 to 4099 as well++    These methods are represented by the constants:++    * ``EASTER_JULIAN   = 1``+    * ``EASTER_ORTHODOX = 2``+    * ``EASTER_WESTERN  = 3``++    The default method is method 3.++    More about the algorithm may be found at:++    `GM Arts: Easter Algorithms <http://www.gmarts.org/index.php?go=415>`_++    and++    `The Calendar FAQ: Easter <https://www.tondering.dk/claus/cal/easter.php>`_++    """++    if not (1 <= method <= 3):+        raise ValueError("invalid method")++    # g - Golden year - 1+    # c - Century+    # h - (23 - Epact) mod 30+    # i - Number of days from March 21 to Paschal Full Moon+    # j - Weekday for PFM (0=Sunday, etc)+    # p - Number of days from March 21 to Sunday on or before PFM+    #     (-6 to 28 methods 1 & 3, to 56 for method 2)+    # e - Extra days to add for method 2 (converting Julian+    #     date to Gregorian date)++    y = year+    g = y % 19+    e = 0+    if method < 3:+        # Old method+        i = (19*g + 15) % 30+        j = (y + y//4 + i) % 7+        if method == 2:+            # Extra dates to convert Julian to Gregorian date+            e = 10+            if y > 1600:+                e = e + y//100 - 16 - (y//100 - 16)//4+    else:+        # New method+        c = y//100+        h = (c - c//4 - (8*c + 13)//25 + 19*g + 15) % 30+        i = h - (h//28)*(1 - (h//28)*(29//(h + 1))*((21 - g)//11))+        j = (y + y//4 + i + 2 - c + c//4) % 7++    # p can be from -6 to 56 corresponding to dates 22 March to 23 May+    # (later dates apply to method 2, although 23 May never actually occurs)+    p = i - j + e+    d = 1 + (p + 27 + (p + 6)//40) % 31+    m = 3 + (p + 26)//30+    return datetime.date(int(y), int(m), int(d))
src/dateutil/parser/__init__.py +61 lines
--- +++ @@ -0,0 +1,61 @@+# -*- coding: utf-8 -*-+from ._parser import parse, parser, parserinfo, ParserError+from ._parser import DEFAULTPARSER, DEFAULTTZPARSER+from ._parser import UnknownTimezoneWarning++from ._parser import __doc__++from .isoparser import isoparser, isoparse++__all__ = ['parse', 'parser', 'parserinfo',+           'isoparse', 'isoparser',+           'ParserError',+           'UnknownTimezoneWarning']+++###+# Deprecate portions of the private interface so that downstream code that+# is improperly relying on it is given *some* notice.+++def __deprecated_private_func(f):+    from functools import wraps+    import warnings++    msg = ('{name} is a private function and may break without warning, '+           'it will be moved and or renamed in future versions.')+    msg = msg.format(name=f.__name__)++    @wraps(f)+    def deprecated_func(*args, **kwargs):+        warnings.warn(msg, DeprecationWarning)+        return f(*args, **kwargs)++    return deprecated_func++def __deprecate_private_class(c):+    import warnings++    msg = ('{name} is a private class and may break without warning, '+           'it will be moved and or renamed in future versions.')+    msg = msg.format(name=c.__name__)++    class private_class(c):+        __doc__ = c.__doc__++        def __init__(self, *args, **kwargs):+            warnings.warn(msg, DeprecationWarning)+            super(private_class, self).__init__(*args, **kwargs)++    private_class.__name__ = c.__name__++    return private_class+++from ._parser import _timelex, _resultbase+from ._parser import _tzparser, _parsetz++_timelex = __deprecate_private_class(_timelex)+_tzparser = __deprecate_private_class(_tzparser)+_resultbase = __deprecate_private_class(_resultbase)+_parsetz = __deprecated_private_func(_parsetz)
src/dateutil/parser/_parser.py +1613 lines
--- +++ @@ -0,0 +1,1613 @@+# -*- coding: utf-8 -*-+"""+This module offers a generic date/time string parser which is able to parse+most known formats to represent a date and/or time.++This module attempts to be forgiving with regards to unlikely input formats,+returning a datetime object even for dates which are ambiguous. If an element+of a date/time stamp is omitted, the following rules are applied:++- If AM or PM is left unspecified, a 24-hour clock is assumed, however, an hour+  on a 12-hour clock (``0 <= hour <= 12``) *must* be specified if AM or PM is+  specified.+- If a time zone is omitted, a timezone-naive datetime is returned.++If any other elements are missing, they are taken from the+:class:`datetime.datetime` object passed to the parameter ``default``. If this+results in a day number exceeding the valid number of days per month, the+value falls back to the end of the month.++Additional resources about date/time string formats can be found below:++- `A summary of the international standard date and time notation+  <https://www.cl.cam.ac.uk/~mgk25/iso-time.html>`_+- `W3C Date and Time Formats <https://www.w3.org/TR/NOTE-datetime>`_+- `Time Formats (Planetary Rings Node) <https://pds-rings.seti.org:443/tools/time_formats.html>`_+- `CPAN ParseDate module+  <https://metacpan.org/pod/release/MUIR/Time-modules-2013.0912/lib/Time/ParseDate.pm>`_+- `Java SimpleDateFormat Class+  <https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>`_+"""+from __future__ import unicode_literals++import datetime+import re+import string+import time+import warnings++from calendar import monthrange+from io import StringIO++import six+from six import integer_types, text_type++from decimal import Decimal++from warnings import warn++from .. import relativedelta+from .. import tz++__all__ = ["parse", "parserinfo", "ParserError"]+++# TODO: pandas.core.tools.datetimes imports this explicitly.  Might be worth+# making public and/or figuring out if there is something we can+# take off their plate.+class _timelex(object):+    # Fractional seconds are sometimes split by a comma+    _split_decimal = re.compile("([.,])")++    def __init__(self, instream):+        if isinstance(instream, (bytes, bytearray)):+            instream = instream.decode()++        if isinstance(instream, text_type):+            instream = StringIO(instream)+        elif getattr(instream, 'read', None) is None:+            raise TypeError('Parser must be a string or character stream, not '+                            '{itype}'.format(itype=instream.__class__.__name__))++        self.instream = instream+        self.charstack = []+        self.tokenstack = []+        self.eof = False++    def get_token(self):+        """+        This function breaks the time string into lexical units (tokens), which+        can be parsed by the parser. Lexical units are demarcated by changes in+        the character set, so any continuous string of letters is considered+        one unit, any continuous string of numbers is considered one unit.++        The main complication arises from the fact that dots ('.') can be used+        both as separators (e.g. "Sep.20.2009") or decimal points (e.g.+        "4:30:21.447"). As such, it is necessary to read the full context of+        any dot-separated strings before breaking it into tokens; as such, this+        function maintains a "token stack", for when the ambiguous context+        demands that multiple tokens be parsed at once.+        """+        if self.tokenstack:+            return self.tokenstack.pop(0)++        seenletters = False+        token = None+        state = None++        while not self.eof:+            # We only realize that we've reached the end of a token when we+            # find a character that's not part of the current token - since+            # that character may be part of the next token, it's stored in the+            # charstack.+            if self.charstack:+                nextchar = self.charstack.pop(0)+            else:+                nextchar = self.instream.read(1)+                while nextchar == '\x00':+                    nextchar = self.instream.read(1)++            if not nextchar:+                self.eof = True+                break+            elif not state:+                # First character of the token - determines if we're starting+                # to parse a word, a number or something else.+                token = nextchar+                if self.isword(nextchar):+                    state = 'a'+                elif self.isnum(nextchar):+                    state = '0'+                elif self.isspace(nextchar):+                    token = ' '+                    break  # emit token+                else:+                    break  # emit token+            elif state == 'a':+                # If we've already started reading a word, we keep reading+                # letters until we find something that's not part of a word.+                seenletters = True+                if self.isword(nextchar):+                    token += nextchar+                elif nextchar == '.':+                    token += nextchar+                    state = 'a.'+                else:+                    self.charstack.append(nextchar)+                    break  # emit token+            elif state == '0':+                # If we've already started reading a number, we keep reading+                # numbers until we find something that doesn't fit.+                if self.isnum(nextchar):+                    token += nextchar+                elif nextchar == '.' or (nextchar == ',' and len(token) >= 2):+                    token += nextchar+                    state = '0.'+                else:+                    self.charstack.append(nextchar)+                    break  # emit token+            elif state == 'a.':+                # If we've seen some letters and a dot separator, continue+                # parsing, and the tokens will be broken up later.+                seenletters = True+                if nextchar == '.' or self.isword(nextchar):+                    token += nextchar+                elif self.isnum(nextchar) and token[-1] == '.':+                    token += nextchar+                    state = '0.'+                else:+                    self.charstack.append(nextchar)+                    break  # emit token+            elif state == '0.':+                # If we've seen at least one dot separator, keep going, we'll+                # break up the tokens later.+                if nextchar == '.' or self.isnum(nextchar):+                    token += nextchar+                elif self.isword(nextchar) and token[-1] == '.':+                    token += nextchar+                    state = 'a.'+                else:+                    self.charstack.append(nextchar)+                    break  # emit token++        if (state in ('a.', '0.') and (seenletters or token.count('.') > 1 or+                                       token[-1] in '.,')):+            l = self._split_decimal.split(token)+            token = l[0]+            for tok in l[1:]:+                if tok:+                    self.tokenstack.append(tok)++        if state == '0.' and token.count('.') == 0:+            token = token.replace(',', '.')++        return token++    def __iter__(self):+        return self++    def __next__(self):+        token = self.get_token()+        if token is None:+            raise StopIteration++        return token++    def next(self):+        return self.__next__()  # Python 2.x support++    @classmethod+    def split(cls, s):+        return list(cls(s))++    @classmethod+    def isword(cls, nextchar):+        """ Whether or not the next character is part of a word """+        return nextchar.isalpha()++    @classmethod+    def isnum(cls, nextchar):+        """ Whether the next character is part of a number """+        return nextchar.isdigit()++    @classmethod+    def isspace(cls, nextchar):+        """ Whether the next character is whitespace """+        return nextchar.isspace()+++class _resultbase(object):++    def __init__(self):+        for attr in self.__slots__:+            setattr(self, attr, None)++    def _repr(self, classname):+        l = []+        for attr in self.__slots__:+            value = getattr(self, attr)+            if value is not None:+                l.append("%s=%s" % (attr, repr(value)))+        return "%s(%s)" % (classname, ", ".join(l))++    def __len__(self):+        return (sum(getattr(self, attr) is not None+                    for attr in self.__slots__))++    def __repr__(self):+        return self._repr(self.__class__.__name__)+++class parserinfo(object):+    """+    Class which handles what inputs are accepted. Subclass this to customize+    the language and acceptable values for each parameter.++    :param dayfirst:+        Whether to interpret the first value in an ambiguous 3-integer date
… 1366 more lines (truncated)
src/dateutil/parser/isoparser.py +416 lines
--- +++ @@ -0,0 +1,416 @@+# -*- coding: utf-8 -*-+"""+This module offers a parser for ISO-8601 strings++It is intended to support all valid date, time and datetime formats per the+ISO-8601 specification.++..versionadded:: 2.7.0+"""+from datetime import datetime, timedelta, time, date+import calendar+from dateutil import tz++from functools import wraps++import re+import six++__all__ = ["isoparse", "isoparser"]+++def _takes_ascii(f):+    @wraps(f)+    def func(self, str_in, *args, **kwargs):+        # If it's a stream, read the whole thing+        str_in = getattr(str_in, 'read', lambda: str_in)()++        # If it's unicode, turn it into bytes, since ISO-8601 only covers ASCII+        if isinstance(str_in, six.text_type):+            # ASCII is the same in UTF-8+            try:+                str_in = str_in.encode('ascii')+            except UnicodeEncodeError as e:+                msg = 'ISO-8601 strings should contain only ASCII characters'+                six.raise_from(ValueError(msg), e)++        return f(self, str_in, *args, **kwargs)++    return func+++class isoparser(object):+    def __init__(self, sep=None):+        """+        :param sep:+            A single character that separates date and time portions. If+            ``None``, the parser will accept any single character.+            For strict ISO-8601 adherence, pass ``'T'``.+        """+        if sep is not None:+            if (len(sep) != 1 or ord(sep) >= 128 or sep in '0123456789'):+                raise ValueError('Separator must be a single, non-numeric ' ++                                 'ASCII character')++            sep = sep.encode('ascii')++        self._sep = sep++    @_takes_ascii+    def isoparse(self, dt_str):+        """+        Parse an ISO-8601 datetime string into a :class:`datetime.datetime`.++        An ISO-8601 datetime string consists of a date portion, followed+        optionally by a time portion - the date and time portions are separated+        by a single character separator, which is ``T`` in the official+        standard. Incomplete date formats (such as ``YYYY-MM``) may *not* be+        combined with a time portion.++        Supported date formats are:++        Common:++        - ``YYYY``+        - ``YYYY-MM``+        - ``YYYY-MM-DD`` or ``YYYYMMDD``++        Uncommon:++        - ``YYYY-Www`` or ``YYYYWww`` - ISO week (day defaults to 0)+        - ``YYYY-Www-D`` or ``YYYYWwwD`` - ISO week and day++        The ISO week and day numbering follows the same logic as+        :func:`datetime.date.isocalendar`.++        Supported time formats are:++        - ``hh``+        - ``hh:mm`` or ``hhmm``+        - ``hh:mm:ss`` or ``hhmmss``+        - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits)++        Midnight is a special case for `hh`, as the standard supports both+        00:00 and 24:00 as a representation. The decimal separator can be+        either a dot or a comma.+++        .. caution::++            Support for fractional components other than seconds is part of the+            ISO-8601 standard, but is not currently implemented in this parser.++        Supported time zone offset formats are:++        - `Z` (UTC)+        - `±HH:MM`+        - `±HHMM`+        - `±HH`++        Offsets will be represented as :class:`dateutil.tz.tzoffset` objects,+        with the exception of UTC, which will be represented as+        :class:`dateutil.tz.tzutc`. Time zone offsets equivalent to UTC (such+        as `+00:00`) will also be represented as :class:`dateutil.tz.tzutc`.++        :param dt_str:+            A string or stream containing only an ISO-8601 datetime string++        :return:+            Returns a :class:`datetime.datetime` representing the string.+            Unspecified components default to their lowest value.++        .. warning::++            As of version 2.7.0, the strictness of the parser should not be+            considered a stable part of the contract. Any valid ISO-8601 string+            that parses correctly with the default settings will continue to+            parse correctly in future versions, but invalid strings that+            currently fail (e.g. ``2017-01-01T00:00+00:00:00``) are not+            guaranteed to continue failing in future versions if they encode+            a valid date.++        .. versionadded:: 2.7.0+        """+        components, pos = self._parse_isodate(dt_str)++        if len(dt_str) > pos:+            if self._sep is None or dt_str[pos:pos + 1] == self._sep:+                components += self._parse_isotime(dt_str[pos + 1:])+            else:+                raise ValueError('String contains unknown ISO components')++        if len(components) > 3 and components[3] == 24:+            components[3] = 0+            return datetime(*components) + timedelta(days=1)++        return datetime(*components)++    @_takes_ascii+    def parse_isodate(self, datestr):+        """+        Parse the date portion of an ISO string.++        :param datestr:+            The string portion of an ISO string, without a separator++        :return:+            Returns a :class:`datetime.date` object+        """+        components, pos = self._parse_isodate(datestr)+        if pos < len(datestr):+            raise ValueError('String contains unknown ISO ' ++                             'components: {!r}'.format(datestr.decode('ascii')))+        return date(*components)++    @_takes_ascii+    def parse_isotime(self, timestr):+        """+        Parse the time portion of an ISO string.++        :param timestr:+            The time portion of an ISO string, without a separator++        :return:+            Returns a :class:`datetime.time` object+        """+        components = self._parse_isotime(timestr)+        if components[0] == 24:+            components[0] = 0+        return time(*components)++    @_takes_ascii+    def parse_tzstr(self, tzstr, zero_as_utc=True):+        """+        Parse a valid ISO time zone string.++        See :func:`isoparser.isoparse` for details on supported formats.++        :param tzstr:+            A string representing an ISO time zone offset++        :param zero_as_utc:+            Whether to return :class:`dateutil.tz.tzutc` for zero-offset zones++        :return:+            Returns :class:`dateutil.tz.tzoffset` for offsets and+            :class:`dateutil.tz.tzutc` for ``Z`` and (if ``zero_as_utc`` is+            specified) offsets equivalent to UTC.+        """+        return self._parse_tzstr(tzstr, zero_as_utc=zero_as_utc)++    # Constants+    _DATE_SEP = b'-'+    _TIME_SEP = b':'+    _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)')++    def _parse_isodate(self, dt_str):+        try:+            return self._parse_isodate_common(dt_str)+        except ValueError:+            return self._parse_isodate_uncommon(dt_str)++    def _parse_isodate_common(self, dt_str):+        len_str = len(dt_str)+        components = [1, 1, 1]++        if len_str < 4:+            raise ValueError('ISO string too short')++        # Year+        components[0] = int(dt_str[0:4])+        pos = 4+        if pos >= len_str:+            return components, pos++        has_sep = dt_str[pos:pos + 1] == self._DATE_SEP+        if has_sep:+            pos += 1++        # Month+        if len_str - pos < 2:+            raise ValueError('Invalid common month')++        components[1] = int(dt_str[pos:pos + 2])+        pos += 2++        if pos >= len_str:+            if has_sep:+                return components, pos+            else:+                raise ValueError('Invalid ISO format')++        if has_sep:+            if dt_str[pos:pos + 1] != self._DATE_SEP:+                raise ValueError('Invalid separator in ISO string')+            pos += 1++        # Day
… 169 more lines (truncated)
src/dateutil/relativedelta.py +599 lines
--- +++ @@ -0,0 +1,599 @@+# -*- coding: utf-8 -*-+import datetime+import calendar++import operator+from math import copysign++from six import integer_types+from warnings import warn++from ._common import weekday++MO, TU, WE, TH, FR, SA, SU = weekdays = tuple(weekday(x) for x in range(7))++__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]+++class relativedelta(object):+    """+    The relativedelta type is designed to be applied to an existing datetime and+    can replace specific components of that datetime, or represents an interval+    of time.++    It is based on the specification of the excellent work done by M.-A. Lemburg+    in his+    `mx.DateTime <https://www.egenix.com/products/python/mxBase/mxDateTime/>`_ extension.+    However, notice that this type does *NOT* implement the same algorithm as+    his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.++    There are two different ways to build a relativedelta instance. The+    first one is passing it two date/datetime classes::++        relativedelta(datetime1, datetime2)++    The second one is passing it any number of the following keyword arguments::++        relativedelta(arg1=x,arg2=y,arg3=z...)++        year, month, day, hour, minute, second, microsecond:+            Absolute information (argument is singular); adding or subtracting a+            relativedelta with absolute information does not perform an arithmetic+            operation, but rather REPLACES the corresponding value in the+            original datetime with the value(s) in relativedelta.++        years, months, weeks, days, hours, minutes, seconds, microseconds:+            Relative information, may be negative (argument is plural); adding+            or subtracting a relativedelta with relative information performs+            the corresponding arithmetic operation on the original datetime value+            with the information in the relativedelta.++        weekday:+            One of the weekday instances (MO, TU, etc) available in the+            relativedelta module. These instances may receive a parameter N,+            specifying the Nth weekday, which could be positive or negative+            (like MO(+1) or MO(-2)). Not specifying it is the same as specifying+            +1. You can also use an integer, where 0=MO. This argument is always+            relative e.g. if the calculated date is already Monday, using MO(1)+            or MO(-1) won't change the day. To effectively make it absolute, use+            it in combination with the day argument (e.g. day=1, MO(1) for first+            Monday of the month).++        leapdays:+            Will add given days to the date found, if year is a leap+            year, and the date found is post 28 of february.++        yearday, nlyearday:+            Set the yearday or the non-leap year day (jump leap days).+            These are converted to day/month/leapdays information.++    There are relative and absolute forms of the keyword+    arguments. The plural is relative, and the singular is+    absolute. For each argument in the order below, the absolute form+    is applied first (by setting each attribute to that value) and+    then the relative form (by adding the value to the attribute).++    The order of attributes considered when this relativedelta is+    added to a datetime is:++    1. Year+    2. Month+    3. Day+    4. Hours+    5. Minutes+    6. Seconds+    7. Microseconds++    Finally, weekday is applied, using the rule described above.++    For example++    >>> from datetime import datetime+    >>> from dateutil.relativedelta import relativedelta, MO+    >>> dt = datetime(2018, 4, 9, 13, 37, 0)+    >>> delta = relativedelta(hours=25, day=1, weekday=MO(1))+    >>> dt + delta+    datetime.datetime(2018, 4, 2, 14, 37)++    First, the day is set to 1 (the first of the month), then 25 hours+    are added, to get to the 2nd day and 14th hour, finally the+    weekday is applied, but since the 2nd is already a Monday there is+    no effect.++    """++    def __init__(self, dt1=None, dt2=None,+                 years=0, months=0, days=0, leapdays=0, weeks=0,+                 hours=0, minutes=0, seconds=0, microseconds=0,+                 year=None, month=None, day=None, weekday=None,+                 yearday=None, nlyearday=None,+                 hour=None, minute=None, second=None, microsecond=None):++        if dt1 and dt2:+            # datetime is a subclass of date. So both must be date+            if not (isinstance(dt1, datetime.date) and+                    isinstance(dt2, datetime.date)):+                raise TypeError("relativedelta only diffs datetime/date")++            # We allow two dates, or two datetimes, so we coerce them to be+            # of the same type+            if (isinstance(dt1, datetime.datetime) !=+                    isinstance(dt2, datetime.datetime)):+                if not isinstance(dt1, datetime.datetime):+                    dt1 = datetime.datetime.fromordinal(dt1.toordinal())+                elif not isinstance(dt2, datetime.datetime):+                    dt2 = datetime.datetime.fromordinal(dt2.toordinal())++            self.years = 0+            self.months = 0+            self.days = 0+            self.leapdays = 0+            self.hours = 0+            self.minutes = 0+            self.seconds = 0+            self.microseconds = 0+            self.year = None+            self.month = None+            self.day = None+            self.weekday = None+            self.hour = None+            self.minute = None+            self.second = None+            self.microsecond = None+            self._has_time = 0++            # Get year / month delta between the two+            months = (dt1.year - dt2.year) * 12 + (dt1.month - dt2.month)+            self._set_months(months)++            # Remove the year/month delta so the timedelta is just well-defined+            # time units (seconds, days and microseconds)+            dtm = self.__radd__(dt2)++            # If we've overshot our target, make an adjustment+            if dt1 < dt2:+                compare = operator.gt+                increment = 1+            else:+                compare = operator.lt+                increment = -1++            while compare(dt1, dtm):+                months += increment+                self._set_months(months)+                dtm = self.__radd__(dt2)++            # Get the timedelta between the "months-adjusted" date and dt1+            delta = dt1 - dtm+            self.seconds = delta.seconds + delta.days * 86400+            self.microseconds = delta.microseconds+        else:+            # Check for non-integer values in integer-only quantities+            if any(x is not None and x != int(x) for x in (years, months)):+                raise ValueError("Non-integer years and months are "+                                 "ambiguous and not currently supported.")++            # Relative information+            self.years = int(years)+            self.months = int(months)+            self.days = days + weeks * 7+            self.leapdays = leapdays+            self.hours = hours+            self.minutes = minutes+            self.seconds = seconds+            self.microseconds = microseconds++            # Absolute information+            self.year = year+            self.month = month+            self.day = day+            self.hour = hour+            self.minute = minute+            self.second = second+            self.microsecond = microsecond++            if any(x is not None and int(x) != x+                   for x in (year, month, day, hour,+                             minute, second, microsecond)):+                # For now we'll deprecate floats - later it'll be an error.+                warn("Non-integer value passed as absolute information. " ++                     "This is not a well-defined condition and will raise " ++                     "errors in future versions.", DeprecationWarning)++            if isinstance(weekday, integer_types):+                self.weekday = weekdays[weekday]+            else:+                self.weekday = weekday++            yday = 0+            if nlyearday:+                yday = nlyearday+            elif yearday:+                yday = yearday+                if yearday > 59:+                    self.leapdays = -1+            if yday:+                ydayidx = [31, 59, 90, 120, 151, 181, 212,+                           243, 273, 304, 334, 366]+                for idx, ydays in enumerate(ydayidx):+                    if yday <= ydays:+                        self.month = idx+1+                        if idx == 0:+                            self.day = yday+                        else:+                            self.day = yday-ydayidx[idx-1]+                        break+                else:+                    raise ValueError("invalid year day (%d)" % yday)++        self._fix()++    def _fix(self):+        if abs(self.microseconds) > 999999:+            s = _sign(self.microseconds)+            div, mod = divmod(self.microseconds * s, 1000000)+            self.microseconds = mod * s+            self.seconds += div * s+        if abs(self.seconds) > 59:+            s = _sign(self.seconds)+            div, mod = divmod(self.seconds * s, 60)+            self.seconds = mod * s+            self.minutes += div * s+        if abs(self.minutes) > 59:+            s = _sign(self.minutes)+            div, mod = divmod(self.minutes * s, 60)+            self.minutes = mod * s+            self.hours += div * s+        if abs(self.hours) > 23:
… 352 more lines (truncated)
src/dateutil/rrule.py +1737 lines
--- +++ @@ -0,0 +1,1737 @@+# -*- coding: utf-8 -*-+"""+The rrule module offers a small, complete, and very fast, implementation of+the recurrence rules documented in the+`iCalendar RFC <https://tools.ietf.org/html/rfc5545>`_,+including support for caching of results.+"""+import calendar+import datetime+import heapq+import itertools+import re+import sys+from functools import wraps+# For warning about deprecation of until and count+from warnings import warn++from six import advance_iterator, integer_types++from six.moves import _thread, range++from ._common import weekday as weekdaybase++try:+    from math import gcd+except ImportError:+    from fractions import gcd++__all__ = ["rrule", "rruleset", "rrulestr",+           "YEARLY", "MONTHLY", "WEEKLY", "DAILY",+           "HOURLY", "MINUTELY", "SECONDLY",+           "MO", "TU", "WE", "TH", "FR", "SA", "SU"]++# Every mask is 7 days longer to handle cross-year weekly periods.+M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30 ++                 [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7)+M365MASK = list(M366MASK)+M29, M30, M31 = list(range(1, 30)), list(range(1, 31)), list(range(1, 32))+MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])+MDAY365MASK = list(MDAY366MASK)+M29, M30, M31 = list(range(-29, 0)), list(range(-30, 0)), list(range(-31, 0))+NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])+NMDAY365MASK = list(NMDAY366MASK)+M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366)+M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365)+WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55+del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31]+MDAY365MASK = tuple(MDAY365MASK)+M365MASK = tuple(M365MASK)++FREQNAMES = ['YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY']++(YEARLY,+ MONTHLY,+ WEEKLY,+ DAILY,+ HOURLY,+ MINUTELY,+ SECONDLY) = list(range(7))++# Imported on demand.+easter = None+parser = None+++class weekday(weekdaybase):+    """+    This version of weekday does not allow n = 0.+    """+    def __init__(self, wkday, n=None):+        if n == 0:+            raise ValueError("Can't create weekday with n==0")++        super(weekday, self).__init__(wkday, n)+++MO, TU, WE, TH, FR, SA, SU = weekdays = tuple(weekday(x) for x in range(7))+++def _invalidates_cache(f):+    """+    Decorator for rruleset methods which may invalidate the+    cached length.+    """+    @wraps(f)+    def inner_func(self, *args, **kwargs):+        rv = f(self, *args, **kwargs)+        self._invalidate_cache()+        return rv++    return inner_func+++class rrulebase(object):+    def __init__(self, cache=False):+        if cache:+            self._cache = []+            self._cache_lock = _thread.allocate_lock()+            self._invalidate_cache()+        else:+            self._cache = None+            self._cache_complete = False+            self._len = None++    def __iter__(self):+        if self._cache_complete:+            return iter(self._cache)+        elif self._cache is None:+            return self._iter()+        else:+            return self._iter_cached()++    def _invalidate_cache(self):+        if self._cache is not None:+            self._cache = []+            self._cache_complete = False+            self._cache_gen = self._iter()++            if self._cache_lock.locked():+                self._cache_lock.release()++        self._len = None++    def _iter_cached(self):+        i = 0+        gen = self._cache_gen+        cache = self._cache+        acquire = self._cache_lock.acquire+        release = self._cache_lock.release+        while gen:+            if i == len(cache):+                acquire()+                if self._cache_complete:+                    break+                try:+                    for j in range(10):+                        cache.append(advance_iterator(gen))+                except StopIteration:+                    self._cache_gen = gen = None+                    self._cache_complete = True+                    break+                release()+            yield cache[i]+            i += 1+        while i < self._len:+            yield cache[i]+            i += 1++    def __getitem__(self, item):+        if self._cache_complete:+            return self._cache[item]+        elif isinstance(item, slice):+            if item.step and item.step < 0:+                return list(iter(self))[item]+            else:+                return list(itertools.islice(self,+                                             item.start or 0,+                                             item.stop or sys.maxsize,+                                             item.step or 1))+        elif item >= 0:+            gen = iter(self)+            try:+                for i in range(item+1):+                    res = advance_iterator(gen)+            except StopIteration:+                raise IndexError+            return res+        else:+            return list(iter(self))[item]++    def __contains__(self, item):+        if self._cache_complete:+            return item in self._cache+        else:+            for i in self:+                if i == item:+                    return True+                elif i > item:+                    return False+        return False++    # __len__() introduces a large performance penalty.+    def count(self):+        """ Returns the number of recurrences in this set. It will have go+            through the whole recurrence, if this hasn't been done before. """+        if self._len is None:+            for x in self:+                pass+        return self._len++    def before(self, dt, inc=False):+        """ Returns the last recurrence before the given datetime instance. The+            inc keyword defines what happens if dt is an occurrence. With+            inc=True, if dt itself is an occurrence, it will be returned. """+        if self._cache_complete:+            gen = self._cache+        else:+            gen = self+        last = None+        if inc:+            for i in gen:+                if i > dt:+                    break+                last = i+        else:+            for i in gen:+                if i >= dt:+                    break+                last = i+        return last++    def after(self, dt, inc=False):+        """ Returns the first recurrence after the given datetime instance. The+            inc keyword defines what happens if dt is an occurrence. With+            inc=True, if dt itself is an occurrence, it will be returned.  """+        if self._cache_complete:+            gen = self._cache+        else:+            gen = self+        if inc:+            for i in gen:+                if i >= dt:+                    return i+        else:+            for i in gen:+                if i > dt:+                    return i+        return None++    def xafter(self, dt, count=None, inc=False):+        """+        Generator which yields up to `count` recurrences after the given+        datetime instance, equivalent to `after`.++        :param dt:+            The datetime at which to start generating recurrences.++        :param count:+            The maximum number of recurrences to generate. If `None` (default),+            dates are generated until the recurrence rule is exhausted.++        :param inc:+            If `dt` is an instance of the rule and `inc` is `True`, it is+            included in the output.++        :yields: Yields a sequence of `datetime` objects.+        """
… 1490 more lines (truncated)
src/dateutil/tz/__init__.py +12 lines
--- +++ @@ -0,0 +1,12 @@+# -*- coding: utf-8 -*-+from .tz import *+from .tz import __doc__++__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",+           "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz",+           "enfold", "datetime_ambiguous", "datetime_exists",+           "resolve_imaginary", "UTC", "DeprecatedTzFormatWarning"]+++class DeprecatedTzFormatWarning(Warning):+    """Warning raised when time zones are parsed from deprecated formats."""
src/dateutil/tz/_common.py +419 lines
--- +++ @@ -0,0 +1,419 @@+from six import PY2++from functools import wraps++from datetime import datetime, timedelta, tzinfo+++ZERO = timedelta(0)++__all__ = ['tzname_in_python2', 'enfold']+++def tzname_in_python2(namefunc):+    """Change unicode output into bytestrings in Python 2++    tzname() API changed in Python 3. It used to return bytes, but was changed+    to unicode strings+    """+    if PY2:+        @wraps(namefunc)+        def adjust_encoding(*args, **kwargs):+            name = namefunc(*args, **kwargs)+            if name is not None:+                name = name.encode()++            return name++        return adjust_encoding+    else:+        return namefunc+++# The following is adapted from Alexander Belopolsky's tz library+# https://github.com/abalkin/tz+if hasattr(datetime, 'fold'):+    # This is the pre-python 3.6 fold situation+    def enfold(dt, fold=1):+        """+        Provides a unified interface for assigning the ``fold`` attribute to+        datetimes both before and after the implementation of PEP-495.++        :param fold:+            The value for the ``fold`` attribute in the returned datetime. This+            should be either 0 or 1.++        :return:+            Returns an object for which ``getattr(dt, 'fold', 0)`` returns+            ``fold`` for all versions of Python. In versions prior to+            Python 3.6, this is a ``_DatetimeWithFold`` object, which is a+            subclass of :py:class:`datetime.datetime` with the ``fold``+            attribute added, if ``fold`` is 1.++        .. versionadded:: 2.6.0+        """+        return dt.replace(fold=fold)++else:+    class _DatetimeWithFold(datetime):+        """+        This is a class designed to provide a PEP 495-compliant interface for+        Python versions before 3.6. It is used only for dates in a fold, so+        the ``fold`` attribute is fixed at ``1``.++        .. versionadded:: 2.6.0+        """+        __slots__ = ()++        def replace(self, *args, **kwargs):+            """+            Return a datetime with the same attributes, except for those+            attributes given new values by whichever keyword arguments are+            specified. Note that tzinfo=None can be specified to create a naive+            datetime from an aware datetime with no conversion of date and time+            data.++            This is reimplemented in ``_DatetimeWithFold`` because pypy3 will+            return a ``datetime.datetime`` even if ``fold`` is unchanged.+            """+            argnames = (+                'year', 'month', 'day', 'hour', 'minute', 'second',+                'microsecond', 'tzinfo'+            )++            for arg, argname in zip(args, argnames):+                if argname in kwargs:+                    raise TypeError('Duplicate argument: {}'.format(argname))++                kwargs[argname] = arg++            for argname in argnames:+                if argname not in kwargs:+                    kwargs[argname] = getattr(self, argname)++            dt_class = self.__class__ if kwargs.get('fold', 1) else datetime++            return dt_class(**kwargs)++        @property+        def fold(self):+            return 1++    def enfold(dt, fold=1):+        """+        Provides a unified interface for assigning the ``fold`` attribute to+        datetimes both before and after the implementation of PEP-495.++        :param fold:+            The value for the ``fold`` attribute in the returned datetime. This+            should be either 0 or 1.++        :return:+            Returns an object for which ``getattr(dt, 'fold', 0)`` returns+            ``fold`` for all versions of Python. In versions prior to+            Python 3.6, this is a ``_DatetimeWithFold`` object, which is a+            subclass of :py:class:`datetime.datetime` with the ``fold``+            attribute added, if ``fold`` is 1.++        .. versionadded:: 2.6.0+        """+        if getattr(dt, 'fold', 0) == fold:+            return dt++        args = dt.timetuple()[:6]+        args += (dt.microsecond, dt.tzinfo)++        if fold:+            return _DatetimeWithFold(*args)+        else:+            return datetime(*args)+++def _validate_fromutc_inputs(f):+    """+    The CPython version of ``fromutc`` checks that the input is a ``datetime``+    object and that ``self`` is attached as its ``tzinfo``.+    """+    @wraps(f)+    def fromutc(self, dt):+        if not isinstance(dt, datetime):+            raise TypeError("fromutc() requires a datetime argument")+        if dt.tzinfo is not self:+            raise ValueError("dt.tzinfo is not self")++        return f(self, dt)++    return fromutc+++class _tzinfo(tzinfo):+    """+    Base class for all ``dateutil`` ``tzinfo`` objects.+    """++    def is_ambiguous(self, dt):+        """+        Whether or not the "wall time" of a given datetime is ambiguous in this+        zone.++        :param dt:+            A :py:class:`datetime.datetime`, naive or time zone aware.+++        :return:+            Returns ``True`` if ambiguous, ``False`` otherwise.++        .. versionadded:: 2.6.0+        """++        dt = dt.replace(tzinfo=self)++        wall_0 = enfold(dt, fold=0)+        wall_1 = enfold(dt, fold=1)++        same_offset = wall_0.utcoffset() == wall_1.utcoffset()+        same_dt = wall_0.replace(tzinfo=None) == wall_1.replace(tzinfo=None)++        return same_dt and not same_offset++    def _fold_status(self, dt_utc, dt_wall):+        """+        Determine the fold status of a "wall" datetime, given a representation+        of the same datetime as a (naive) UTC datetime. This is calculated based+        on the assumption that ``dt.utcoffset() - dt.dst()`` is constant for all+        datetimes, and that this offset is the actual number of hours separating+        ``dt_utc`` and ``dt_wall``.++        :param dt_utc:+            Representation of the datetime as UTC++        :param dt_wall:+            Representation of the datetime as "wall time". This parameter must+            either have a `fold` attribute or have a fold-naive+            :class:`datetime.tzinfo` attached, otherwise the calculation may+            fail.+        """+        if self.is_ambiguous(dt_wall):+            delta_wall = dt_wall - dt_utc+            _fold = int(delta_wall == (dt_utc.utcoffset() - dt_utc.dst()))+        else:+            _fold = 0++        return _fold++    def _fold(self, dt):+        return getattr(dt, 'fold', 0)++    def _fromutc(self, dt):+        """+        Given a timezone-aware datetime in a given timezone, calculates a+        timezone-aware datetime in a new timezone.++        Since this is the one time that we *know* we have an unambiguous+        datetime object, we take this opportunity to determine whether the+        datetime is ambiguous and in a "fold" state (e.g. if it's the first+        occurrence, chronologically, of the ambiguous datetime).++        :param dt:+            A timezone-aware :class:`datetime.datetime` object.+        """++        # Re-implement the algorithm from Python's datetime.py+        dtoff = dt.utcoffset()+        if dtoff is None:+            raise ValueError("fromutc() requires a non-None utcoffset() "+                             "result")++        # The original datetime.py code assumes that `dst()` defaults to+        # zero during ambiguous times. PEP 495 inverts this presumption, so+        # for pre-PEP 495 versions of python, we need to tweak the algorithm.+        dtdst = dt.dst()+        if dtdst is None:+            raise ValueError("fromutc() requires a non-None dst() result")+        delta = dtoff - dtdst++        dt += delta+        # Set fold=1 so we can default to being in the fold for+        # ambiguous dates.+        dtdst = enfold(dt, fold=1).dst()+        if dtdst is None:+            raise ValueError("fromutc(): dt.dst gave inconsistent "+                             "results; cannot convert")+        return dt + dtdst++    @_validate_fromutc_inputs+    def fromutc(self, dt):+        """+        Given a timezone-aware datetime in a given timezone, calculates a
… 172 more lines (truncated)
src/dateutil/tz/_factories.py +80 lines
--- +++ @@ -0,0 +1,80 @@+from datetime import timedelta+import weakref+from collections import OrderedDict++from six.moves import _thread+++class _TzSingleton(type):+    def __init__(cls, *args, **kwargs):+        cls.__instance = None+        super(_TzSingleton, cls).__init__(*args, **kwargs)++    def __call__(cls):+        if cls.__instance is None:+            cls.__instance = super(_TzSingleton, cls).__call__()+        return cls.__instance+++class _TzFactory(type):+    def instance(cls, *args, **kwargs):+        """Alternate constructor that returns a fresh instance"""+        return type.__call__(cls, *args, **kwargs)+++class _TzOffsetFactory(_TzFactory):+    def __init__(cls, *args, **kwargs):+        cls.__instances = weakref.WeakValueDictionary()+        cls.__strong_cache = OrderedDict()+        cls.__strong_cache_size = 8++        cls._cache_lock = _thread.allocate_lock()++    def __call__(cls, name, offset):+        if isinstance(offset, timedelta):+            key = (name, offset.total_seconds())+        else:+            key = (name, offset)++        instance = cls.__instances.get(key, None)+        if instance is None:+            instance = cls.__instances.setdefault(key,+                                                  cls.instance(name, offset))++        # This lock may not be necessary in Python 3. See GH issue #901+        with cls._cache_lock:+            cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)++            # Remove an item if the strong cache is overpopulated+            if len(cls.__strong_cache) > cls.__strong_cache_size:+                cls.__strong_cache.popitem(last=False)++        return instance+++class _TzStrFactory(_TzFactory):+    def __init__(cls, *args, **kwargs):+        cls.__instances = weakref.WeakValueDictionary()+        cls.__strong_cache = OrderedDict()+        cls.__strong_cache_size = 8++        cls.__cache_lock = _thread.allocate_lock()++    def __call__(cls, s, posix_offset=False):+        key = (s, posix_offset)+        instance = cls.__instances.get(key, None)++        if instance is None:+            instance = cls.__instances.setdefault(key,+                cls.instance(s, posix_offset))++        # This lock may not be necessary in Python 3. See GH issue #901+        with cls.__cache_lock:+            cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)++            # Remove an item if the strong cache is overpopulated+            if len(cls.__strong_cache) > cls.__strong_cache_size:+                cls.__strong_cache.popitem(last=False)++        return instance+
src/dateutil/tz/tz.py +1849 lines
--- +++ @@ -0,0 +1,1849 @@+# -*- coding: utf-8 -*-+"""+This module offers timezone implementations subclassing the abstract+:py:class:`datetime.tzinfo` type. There are classes to handle tzfile format+files (usually are in :file:`/etc/localtime`, :file:`/usr/share/zoneinfo`,+etc), TZ environment string (in all known formats), given ranges (with help+from relative deltas), local machine timezone, fixed offset timezone, and UTC+timezone.+"""+import datetime+import struct+import time+import sys+import os+import bisect+import weakref+from collections import OrderedDict++import six+from six import string_types+from six.moves import _thread+from ._common import tzname_in_python2, _tzinfo+from ._common import tzrangebase, enfold+from ._common import _validate_fromutc_inputs++from ._factories import _TzSingleton, _TzOffsetFactory+from ._factories import _TzStrFactory+try:+    from .win import tzwin, tzwinlocal+except ImportError:+    tzwin = tzwinlocal = None++# For warning about rounding tzinfo+from warnings import warn++ZERO = datetime.timedelta(0)+EPOCH = datetime.datetime(1970, 1, 1, 0, 0)+EPOCHORDINAL = EPOCH.toordinal()++[email protected]_metaclass(_TzSingleton)+class tzutc(datetime.tzinfo):+    """+    This is a tzinfo object that represents the UTC time zone.++    **Examples:**++    .. doctest::++        >>> from datetime import *+        >>> from dateutil.tz import *++        >>> datetime.now()+        datetime.datetime(2003, 9, 27, 9, 40, 1, 521290)++        >>> datetime.now(tzutc())+        datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc())++        >>> datetime.now(tzutc()).tzname()+        'UTC'++    .. versionchanged:: 2.7.0+        ``tzutc()`` is now a singleton, so the result of ``tzutc()`` will+        always return the same object.++        .. doctest::++            >>> from dateutil.tz import tzutc, UTC+            >>> tzutc() is tzutc()+            True+            >>> tzutc() is UTC+            True+    """+    def utcoffset(self, dt):+        return ZERO++    def dst(self, dt):+        return ZERO++    @tzname_in_python2+    def tzname(self, dt):+        return "UTC"++    def is_ambiguous(self, dt):+        """+        Whether or not the "wall time" of a given datetime is ambiguous in this+        zone.++        :param dt:+            A :py:class:`datetime.datetime`, naive or time zone aware.+++        :return:+            Returns ``True`` if ambiguous, ``False`` otherwise.++        .. versionadded:: 2.6.0+        """+        return False++    @_validate_fromutc_inputs+    def fromutc(self, dt):+        """+        Fast track version of fromutc() returns the original ``dt`` object for+        any valid :py:class:`datetime.datetime` object.+        """+        return dt++    def __eq__(self, other):+        if not isinstance(other, (tzutc, tzoffset)):+            return NotImplemented++        return (isinstance(other, tzutc) or+                (isinstance(other, tzoffset) and other._offset == ZERO))++    __hash__ = None++    def __ne__(self, other):+        return not (self == other)++    def __repr__(self):+        return "%s()" % self.__class__.__name__++    __reduce__ = object.__reduce__+++#: Convenience constant providing a :class:`tzutc()` instance+#:+#: .. versionadded:: 2.7.0+UTC = tzutc()++[email protected]_metaclass(_TzOffsetFactory)+class tzoffset(datetime.tzinfo):+    """+    A simple class for representing a fixed offset from UTC.++    :param name:+        The timezone name, to be returned when ``tzname()`` is called.+    :param offset:+        The time zone offset in seconds, or (since version 2.6.0, represented+        as a :py:class:`datetime.timedelta` object).+    """+    def __init__(self, name, offset):+        self._name = name++        try:+            # Allow a timedelta+            offset = offset.total_seconds()+        except (TypeError, AttributeError):+            pass++        self._offset = datetime.timedelta(seconds=_get_supported_offset(offset))++    def utcoffset(self, dt):+        return self._offset++    def dst(self, dt):+        return ZERO++    @tzname_in_python2+    def tzname(self, dt):+        return self._name++    @_validate_fromutc_inputs+    def fromutc(self, dt):+        return dt + self._offset++    def is_ambiguous(self, dt):+        """+        Whether or not the "wall time" of a given datetime is ambiguous in this+        zone.++        :param dt:+            A :py:class:`datetime.datetime`, naive or time zone aware.+        :return:+            Returns ``True`` if ambiguous, ``False`` otherwise.++        .. versionadded:: 2.6.0+        """+        return False++    def __eq__(self, other):+        if not isinstance(other, tzoffset):+            return NotImplemented++        return self._offset == other._offset++    __hash__ = None++    def __ne__(self, other):+        return not (self == other)++    def __repr__(self):+        return "%s(%s, %s)" % (self.__class__.__name__,+                               repr(self._name),+                               int(self._offset.total_seconds()))++    __reduce__ = object.__reduce__+++class tzlocal(_tzinfo):+    """+    A :class:`tzinfo` subclass built around the ``time`` timezone functions.+    """+    def __init__(self):+        super(tzlocal, self).__init__()++        self._std_offset = datetime.timedelta(seconds=-time.timezone)+        if time.daylight:+            self._dst_offset = datetime.timedelta(seconds=-time.altzone)+        else:+            self._dst_offset = self._std_offset++        self._dst_saved = self._dst_offset - self._std_offset+        self._hasdst = bool(self._dst_saved)+        self._tznames = tuple(time.tzname)++    def utcoffset(self, dt):+        if dt is None and self._hasdst:+            return None++        if self._isdst(dt):+            return self._dst_offset+        else:+            return self._std_offset++    def dst(self, dt):+        if dt is None and self._hasdst:+            return None++        if self._isdst(dt):+            return self._dst_offset - self._std_offset+        else:+            return ZERO++    @tzname_in_python2+    def tzname(self, dt):+        return self._tznames[self._isdst(dt)]++    def is_ambiguous(self, dt):+        """+        Whether or not the "wall time" of a given datetime is ambiguous in this+        zone.++        :param dt:+            A :py:class:`datetime.datetime`, naive or time zone aware.+
… 1602 more lines (truncated)
src/dateutil/tz/win.py +370 lines
--- +++ @@ -0,0 +1,370 @@+# -*- coding: utf-8 -*-+"""+This module provides an interface to the native time zone data on Windows,+including :py:class:`datetime.tzinfo` implementations.++Attempting to import this module on a non-Windows platform will raise an+:py:obj:`ImportError`.+"""+# This code was originally contributed by Jeffrey Harris.+import datetime+import struct++from six.moves import winreg+from six import text_type++try:+    import ctypes+    from ctypes import wintypes+except ValueError:+    # ValueError is raised on non-Windows systems for some horrible reason.+    raise ImportError("Running tzwin on non-Windows system")++from ._common import tzrangebase++__all__ = ["tzwin", "tzwinlocal", "tzres"]++ONEWEEK = datetime.timedelta(7)++TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"+TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"+TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"+++def _settzkeyname():+    handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)+    try:+        winreg.OpenKey(handle, TZKEYNAMENT).Close()+        TZKEYNAME = TZKEYNAMENT+    except WindowsError:+        TZKEYNAME = TZKEYNAME9X+    handle.Close()+    return TZKEYNAME+++TZKEYNAME = _settzkeyname()+++class tzres(object):+    """+    Class for accessing ``tzres.dll``, which contains timezone name related+    resources.++    .. versionadded:: 2.5.0+    """+    p_wchar = ctypes.POINTER(wintypes.WCHAR)        # Pointer to a wide char++    def __init__(self, tzres_loc='tzres.dll'):+        # Load the user32 DLL so we can load strings from tzres+        user32 = ctypes.WinDLL('user32')++        # Specify the LoadStringW function+        user32.LoadStringW.argtypes = (wintypes.HINSTANCE,+                                       wintypes.UINT,+                                       wintypes.LPWSTR,+                                       ctypes.c_int)++        self.LoadStringW = user32.LoadStringW+        self._tzres = ctypes.WinDLL(tzres_loc)+        self.tzres_loc = tzres_loc++    def load_name(self, offset):+        """+        Load a timezone name from a DLL offset (integer).++        >>> from dateutil.tzwin import tzres+        >>> tzr = tzres()+        >>> print(tzr.load_name(112))+        'Eastern Standard Time'++        :param offset:+            A positive integer value referring to a string from the tzres dll.++        .. note::++            Offsets found in the registry are generally of the form+            ``@tzres.dll,-114``. The offset in this case is 114, not -114.++        """+        resource = self.p_wchar()+        lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR)+        nchar = self.LoadStringW(self._tzres._handle, offset, lpBuffer, 0)+        return resource[:nchar]++    def name_from_string(self, tzname_str):+        """+        Parse strings as returned from the Windows registry into the time zone+        name as defined in the registry.++        >>> from dateutil.tzwin import tzres+        >>> tzr = tzres()+        >>> print(tzr.name_from_string('@tzres.dll,-251'))+        'Dateline Daylight Time'+        >>> print(tzr.name_from_string('Eastern Standard Time'))+        'Eastern Standard Time'++        :param tzname_str:+            A timezone name string as returned from a Windows registry key.++        :return:+            Returns the localized timezone string from tzres.dll if the string+            is of the form `@tzres.dll,-offset`, else returns the input string.+        """+        if not tzname_str.startswith('@'):+            return tzname_str++        name_splt = tzname_str.split(',-')+        try:+            offset = int(name_splt[1])+        except:+            raise ValueError("Malformed timezone string.")++        return self.load_name(offset)+++class tzwinbase(tzrangebase):+    """tzinfo class based on win32's timezones available in the registry."""+    def __init__(self):+        raise NotImplementedError('tzwinbase is an abstract base class')++    def __eq__(self, other):+        # Compare on all relevant dimensions, including name.+        if not isinstance(other, tzwinbase):+            return NotImplemented++        return  (self._std_offset == other._std_offset and+                 self._dst_offset == other._dst_offset and+                 self._stddayofweek == other._stddayofweek and+                 self._dstdayofweek == other._dstdayofweek and+                 self._stdweeknumber == other._stdweeknumber and+                 self._dstweeknumber == other._dstweeknumber and+                 self._stdhour == other._stdhour and+                 self._dsthour == other._dsthour and+                 self._stdminute == other._stdminute and+                 self._dstminute == other._dstminute and+                 self._std_abbr == other._std_abbr and+                 self._dst_abbr == other._dst_abbr)++    @staticmethod+    def list():+        """Return a list of all time zones known to the system."""+        with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:+            with winreg.OpenKey(handle, TZKEYNAME) as tzkey:+                result = [winreg.EnumKey(tzkey, i)+                          for i in range(winreg.QueryInfoKey(tzkey)[0])]+        return result++    def display(self):+        """+        Return the display name of the time zone.+        """+        return self._display++    def transitions(self, year):+        """+        For a given year, get the DST on and off transition times, expressed+        always on the standard time side. For zones with no transitions, this+        function returns ``None``.++        :param year:+            The year whose transitions you would like to query.++        :return:+            Returns a :class:`tuple` of :class:`datetime.datetime` objects,+            ``(dston, dstoff)`` for zones with an annual DST transition, or+            ``None`` for fixed offset zones.+        """++        if not self.hasdst:+            return None++        dston = picknthweekday(year, self._dstmonth, self._dstdayofweek,+                               self._dsthour, self._dstminute,+                               self._dstweeknumber)++        dstoff = picknthweekday(year, self._stdmonth, self._stddayofweek,+                                self._stdhour, self._stdminute,+                                self._stdweeknumber)++        # Ambiguous dates default to the STD side+        dstoff -= self._dst_base_offset++        return dston, dstoff++    def _get_hasdst(self):+        return self._dstmonth != 0++    @property+    def _dst_base_offset(self):+        return self._dst_base_offset_+++class tzwin(tzwinbase):+    """+    Time zone object created from the zone info in the Windows registry++    These are similar to :py:class:`dateutil.tz.tzrange` objects in that+    the time zone data is provided in the format of a single offset rule+    for either 0 or 2 time zone transitions per year.++    :param: name+        The name of a Windows time zone key, e.g. "Eastern Standard Time".+        The full list of keys can be retrieved with :func:`tzwin.list`.+    """++    def __init__(self, name):+        self._name = name++        with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:+            tzkeyname = text_type("{kn}\\{name}").format(kn=TZKEYNAME, name=name)+            with winreg.OpenKey(handle, tzkeyname) as tzkey:+                keydict = valuestodict(tzkey)++        self._std_abbr = keydict["Std"]+        self._dst_abbr = keydict["Dlt"]++        self._display = keydict["Display"]++        # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm+        tup = struct.unpack("=3l16h", keydict["TZI"])+        stdoffset = -tup[0]-tup[1]          # Bias + StandardBias * -1+        dstoffset = stdoffset-tup[2]        # + DaylightBias * -1+        self._std_offset = datetime.timedelta(minutes=stdoffset)+        self._dst_offset = datetime.timedelta(minutes=dstoffset)++        # for the meaning see the win32 TIME_ZONE_INFORMATION structure docs+        # http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx+        (self._stdmonth,+         self._stddayofweek,   # Sunday = 0+         self._stdweeknumber,  # Last = 5+         self._stdhour,+         self._stdminute) = tup[4:9]++        (self._dstmonth,+         self._dstdayofweek,   # Sunday = 0+         self._dstweeknumber,  # Last = 5+         self._dsthour,+         self._dstminute) = tup[12:17]
… 123 more lines (truncated)
src/dateutil/tzwin.py +2 lines
--- +++ @@ -0,0 +1,2 @@+# tzwin has moved to dateutil.tz.win+from .tz.win import *
src/dateutil/utils.py +71 lines
--- +++ @@ -0,0 +1,71 @@+# -*- coding: utf-8 -*-+"""+This module offers general convenience and utility functions for dealing with+datetimes.++.. versionadded:: 2.7.0+"""+from __future__ import unicode_literals++from datetime import datetime, time+++def today(tzinfo=None):+    """+    Returns a :py:class:`datetime` representing the current day at midnight++    :param tzinfo:+        The time zone to attach (also used to determine the current day).++    :return:+        A :py:class:`datetime.datetime` object representing the current day+        at midnight.+    """++    dt = datetime.now(tzinfo)+    return datetime.combine(dt.date(), time(0, tzinfo=tzinfo))+++def default_tzinfo(dt, tzinfo):+    """+    Sets the ``tzinfo`` parameter on naive datetimes only++    This is useful for example when you are provided a datetime that may have+    either an implicit or explicit time zone, such as when parsing a time zone+    string.++    .. doctest::++        >>> from dateutil.tz import tzoffset+        >>> from dateutil.parser import parse+        >>> from dateutil.utils import default_tzinfo+        >>> dflt_tz = tzoffset("EST", -18000)+        >>> print(default_tzinfo(parse('2014-01-01 12:30 UTC'), dflt_tz))+        2014-01-01 12:30:00+00:00+        >>> print(default_tzinfo(parse('2014-01-01 12:30'), dflt_tz))+        2014-01-01 12:30:00-05:00++    :param dt:+        The datetime on which to replace the time zone++    :param tzinfo:+        The :py:class:`datetime.tzinfo` subclass instance to assign to+        ``dt`` if (and only if) it is naive.++    :return:+        Returns an aware :py:class:`datetime.datetime`.+    """+    if dt.tzinfo is not None:+        return dt+    else:+        return dt.replace(tzinfo=tzinfo)+++def within_delta(dt1, dt2, delta):+    """+    Useful for comparing two datetimes that may have a negligible difference+    to be considered equal.+    """+    delta = abs(delta)+    difference = dt1 - dt2+    return -delta <= difference <= delta
src/dateutil/zoneinfo/__init__.py +167 lines
--- +++ @@ -0,0 +1,167 @@+# -*- coding: utf-8 -*-+import warnings+import json++from tarfile import TarFile+from pkgutil import get_data+from io import BytesIO++from dateutil.tz import tzfile as _tzfile++__all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"]++ZONEFILENAME = "dateutil-zoneinfo.tar.gz"+METADATA_FN = 'METADATA'+++class tzfile(_tzfile):+    def __reduce__(self):+        return (gettz, (self._filename,))+++def getzoneinfofile_stream():+    try:+        return BytesIO(get_data(__name__, ZONEFILENAME))+    except IOError as e:  # TODO  switch to FileNotFoundError?+        warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror))+        return None+++class ZoneInfoFile(object):+    def __init__(self, zonefile_stream=None):+        if zonefile_stream is not None:+            with TarFile.open(fileobj=zonefile_stream) as tf:+                self.zones = {zf.name: tzfile(tf.extractfile(zf), filename=zf.name)+                              for zf in tf.getmembers()+                              if zf.isfile() and zf.name != METADATA_FN}+                # deal with links: They'll point to their parent object. Less+                # waste of memory+                links = {zl.name: self.zones[zl.linkname]+                         for zl in tf.getmembers() if+                         zl.islnk() or zl.issym()}+                self.zones.update(links)+                try:+                    metadata_json = tf.extractfile(tf.getmember(METADATA_FN))+                    metadata_str = metadata_json.read().decode('UTF-8')+                    self.metadata = json.loads(metadata_str)+                except KeyError:+                    # no metadata in tar file+                    self.metadata = None+        else:+            self.zones = {}+            self.metadata = None++    def get(self, name, default=None):+        """+        Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method+        for retrieving zones from the zone dictionary.++        :param name:+            The name of the zone to retrieve. (Generally IANA zone names)++        :param default:+            The value to return in the event of a missing key.++        .. versionadded:: 2.6.0++        """+        return self.zones.get(name, default)+++# The current API has gettz as a module function, although in fact it taps into+# a stateful class. So as a workaround for now, without changing the API, we+# will create a new "global" class instance the first time a user requests a+# timezone. Ugly, but adheres to the api.+#+# TODO: Remove after deprecation period.+_CLASS_ZONE_INSTANCE = []+++def get_zonefile_instance(new_instance=False):+    """+    This is a convenience function which provides a :class:`ZoneInfoFile`+    instance using the data provided by the ``dateutil`` package. By default, it+    caches a single instance of the ZoneInfoFile object and returns that.++    :param new_instance:+        If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and+        used as the cached instance for the next call. Otherwise, new instances+        are created only as necessary.++    :return:+        Returns a :class:`ZoneInfoFile` object.++    .. versionadded:: 2.6+    """+    if new_instance:+        zif = None+    else:+        zif = getattr(get_zonefile_instance, '_cached_instance', None)++    if zif is None:+        zif = ZoneInfoFile(getzoneinfofile_stream())++        get_zonefile_instance._cached_instance = zif++    return zif+++def gettz(name):+    """+    This retrieves a time zone from the local zoneinfo tarball that is packaged+    with dateutil.++    :param name:+        An IANA-style time zone name, as found in the zoneinfo file.++    :return:+        Returns a :class:`dateutil.tz.tzfile` time zone object.++    .. warning::+        It is generally inadvisable to use this function, and it is only+        provided for API compatibility with earlier versions. This is *not*+        equivalent to ``dateutil.tz.gettz()``, which selects an appropriate+        time zone based on the inputs, favoring system zoneinfo. This is ONLY+        for accessing the dateutil-specific zoneinfo (which may be out of+        date compared to the system zoneinfo).++    .. deprecated:: 2.6+        If you need to use a specific zoneinfofile over the system zoneinfo,+        instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call+        :func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead.++        Use :func:`get_zonefile_instance` to retrieve an instance of the+        dateutil-provided zoneinfo.+    """+    warnings.warn("zoneinfo.gettz() will be removed in future versions, "+                  "to use the dateutil-provided zoneinfo files, instantiate a "+                  "ZoneInfoFile object and use ZoneInfoFile.zones.get() "+                  "instead. See the documentation for details.",+                  DeprecationWarning)++    if len(_CLASS_ZONE_INSTANCE) == 0:+        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))+    return _CLASS_ZONE_INSTANCE[0].zones.get(name)+++def gettz_db_metadata():+    """ Get the zonefile metadata++    See `zonefile_metadata`_++    :returns:+        A dictionary with the database metadata++    .. deprecated:: 2.6+        See deprecation warning in :func:`zoneinfo.gettz`. To get metadata,+        query the attribute ``zoneinfo.ZoneInfoFile.metadata``.+    """+    warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future "+                  "versions, to use the dateutil-provided zoneinfo files, "+                  "ZoneInfoFile object and query the 'metadata' attribute "+                  "instead. See the documentation for details.",+                  DeprecationWarning)++    if len(_CLASS_ZONE_INSTANCE) == 0:+        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))+    return _CLASS_ZONE_INSTANCE[0].metadata
tests/__init__.py +0 lines
binary or empty diff
pyyaml pypi
6.0.3 11mo ago nominal
INSTALL-EXEC
latest 6.0.3 versions 40 maintainers 1
5.1
5.1.1
5.1.2
5.2
5.3
5.3.1
5.4
5.4.1
6.0
6.0.1
6.0.2
6.0.3
INSTALL-EXEC
setup.py in sdist uses install-hook (runs at pip install)
warn · snapshot-derived
release diff 6.0.2 → 6.0.3
+1 added · -1 removed · ~9 modified
lib/yaml/__init__.py +1 lines
--- +++ @@ -10,3 +10,3 @@ -__version__ = '6.0.2'+__version__ = '6.0.3' try:
packaging/build/libyaml.sh +15 lines
--- +++ @@ -3,2 +3,10 @@ set -eux++# build the requested version of libyaml locally+echo "::group::fetch libyaml ${LIBYAML_REF}"+git config --global advice.detachedHead false+git clone --branch "$LIBYAML_REF" "$LIBYAML_REPO" libyaml+pushd libyaml+git reset --hard "$LIBYAML_REF"+echo "::endgroup::" @@ -14,10 +22,10 @@ fi-echo "::endgroup::" -# build the requested version of libyaml locally-echo "::group::fetch libyaml ${LIBYAML_REF}"-git config --global advice.detachedHead false-git clone --branch "$LIBYAML_REF" "$LIBYAML_REPO" libyaml-pushd libyaml-git reset --hard "$LIBYAML_REF"+# hack to fix up locally musl1.2 libtool macros+if grep -m 1 alpine /etc/os-release; then+  if ! grep -E 'AC_CONFIG_MACRO_DIRS\(\[m4])' configure.ac; then+    echo 'AC_CONFIG_MACRO_DIRS([m4])' >> configure.ac+    ACLOCAL_PATH=/usr/local/share/libtool/ libtoolize+  fi+fi echo "::endgroup::"
pyproject.toml +0 lines
--- +++ @@ -3,3 +3,2 @@     "setuptools",  # FIXME: declare min/max setuptools versions?-    "wheel",     "Cython; python_version < '3.13'",
setup.py +2 lines
--- +++ @@ -2,3 +2,3 @@ NAME = 'PyYAML'-VERSION = '6.0.2'+VERSION = '6.0.3' DESCRIPTION = "YAML parser and emitter for Python"@@ -36,2 +36,3 @@     "Programming Language :: Python :: 3.13",+    "Programming Language :: Python :: 3.14",     "Programming Language :: Python :: Implementation :: CPython",
six pypi
1.17.0 1y ago nominal
BURST ×2
latest 1.17.0 versions 29 maintainers 1
1.7.2
1.7.3
1.8.0
1.9.0
1.10.0
1.11.0
1.12.0
1.13.0
1.14.0
1.15.0
1.16.0
1.17.0
BURST
2 releases in 28m: 1.6.0, 1.6.1
info · registry-verified · 2014-03-14 · 12y ago
BURST
2 releases in 18m: 1.7.1, 1.7.2
info · registry-verified · 2014-06-09 · 12y ago
release diff 1.16.0 → 1.17.0
+0 added · -0 removed · ~11 modified
six.py +10 lines · 3 flagged
--- +++ @@ -1,2 +1,2 @@-# Copyright (c) 2010-2020 Benjamin Peterson+# Copyright (c) 2010-2024 Benjamin Peterson #@@ -31,3 +31,3 @@ __author__ = "Benjamin Peterson <[email protected]>"-__version__ = "1.16.0"+__version__ = "1.17.0" @@ -265,3 +265,3 @@     MovedAttribute("StringIO", "StringIO", "io"),-    MovedAttribute("UserDict", "UserDict", "collections"),+    MovedAttribute("UserDict", "UserDict", "collections", "IterableUserDict", "UserDict"),     MovedAttribute("UserList", "UserList", "collections"),@@ -437,4 +437,2 @@     MovedAttribute("urlcleanup", "urllib", "urllib.request"),-    MovedAttribute("URLopener", "urllib", "urllib.request"),-    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),     MovedAttribute("proxy_bypass", "urllib", "urllib.request"),@@ -443,2 +441,9 @@ ]+if sys.version_info[:2] < (3, 14):+    _urllib_request_moved_attributes.extend(+        [+            MovedAttribute("URLopener", "urllib", "urllib.request"),+            MovedAttribute("FancyURLopener", "urllib", "urllib.request"),+        ]+    ) for attr in _urllib_request_moved_attributes:
documentation/conf.py +1 lines
--- +++ @@ -35,3 +35,3 @@ project = u"six"-copyright = u"2010-2020, Benjamin Peterson"+copyright = u"2010-2024, Benjamin Peterson" 
setup.cfg +1 lines
--- +++ @@ -8,3 +8,3 @@ [metadata]-license_file = LICENSE+license_files = LICENSE @@ -12,9 +12,2 @@ minversion = 2.2.0-pep8ignore = -	documentation/*.py ALL-	test_six.py ALL-flakes-ignore = -	documentation/*.py ALL-	test_six.py ALL-	six.py UndefinedName 
setup.py +1 lines
--- +++ @@ -1,2 +1,2 @@-# Copyright (c) 2010-2020 Benjamin Peterson+# Copyright (c) 2010-2024 Benjamin Peterson #
test_six.py +17 lines
--- +++ @@ -1,2 +1,2 @@-# Copyright (c) 2010-2020 Benjamin Peterson+# Copyright (c) 2010-2024 Benjamin Peterson #@@ -115,2 +115,11 @@ +have_ndbm = True+try:+    import dbm+except ImportError:+    try:+        import dbm.ndbm+    except ImportError:+        have_ndbm = False+ @pytest.mark.parametrize("item_name",@@ -129,4 +138,8 @@                 pytest.skip("requires tkinter")-        if item_name.startswith("dbm_gnu") and not have_gdbm:+            if item_name == "tkinter_tix" and sys.version_info >= (3, 13):+                pytest.skip("tkinter.tix removed from Python 3.13")+        if item_name == "dbm_gnu" and not have_gdbm:             pytest.skip("requires gdbm")+        if item_name == "dbm_ndbm":+            pytest.skip("requires ndbm")         raise@@ -222,4 +235,4 @@     from six.moves import getoutput-    output = getoutput('echo "foo"')-    assert output == 'foo'+    output = getoutput('dir' if sys.platform.startswith('win') else 'echo foo')+    assert output != '' 
typing-extensions pypi
4.16.0 1mo ago nominal
critical-tier no findings
latest 4.16.0 versions 52 maintainers 1 critical-tier (snapshotted)
4.10.0
4.11.0
4.12.0
4.12.1
4.12.2
4.13.0
4.13.1
4.13.2
4.14.0
4.14.1
4.15.0
4.16.0
CLEAN
no findings — nominal
release diff 4.15.0 → 4.16.0
+0 added · -0 removed · ~5 modified
src/test_typing_extensions.py +465 lines · 4 flagged
--- +++ @@ -12,2 +12,3 @@ import itertools+import os import pickle@@ -104,2 +105,3 @@     runtime_checkable,+    sentinel,     type_repr,@@ -133,2 +135,22 @@ TYPING_3_14_0 = sys.version_info[:3] >= (3, 14, 0)++TYPING_3_15_0 = sys.version_info[:3] >= (3, 15, 0)++TYPING_3_15_0_BETA_1 = sys.version_info[:5] == (3, 15, 0, 'beta', 1)++# We cannot control the repr of `TypeVarTuple` on versions of Python+# where `typing_extensions.TypeVarTuple()` does not return an instance+# of `typing_extensions.TypeVarTuple`. At time of writing, that's Python+# versions 3.11-3.14 inclusive (but not 3.10 or 3.15+). The exact version+# range has changed in the past and may do so again in the future.+#+# Note that we do not do an `isinstance()` check here because+# `typing_extensions.TypeVarTuple` does some trickery to pretend that+# instances of `typing.TypeVar` are also instances of+# `typing_extensions.TypeVarTuple` on Python 3.11-3.14.+# (Possibly we're being a little too clever for our own good there.)+GOOD_TYPEVARTUPLE_REPR_EXPECTED = (+    type(typing_extensions.TypeVarTuple("Ts"))+    is typing_extensions.TypeVarTuple+) @@ -533,2 +555,10 @@ +    @skipUnless(TYPING_3_10_0, "PEP 604 has yet to be")+    def test_or(self):+        self.assertEqual(self.bottom_type | int, Union[self.bottom_type, int])+        self.assertEqual(int | self.bottom_type, Union[int, self.bottom_type])++        self.assertEqual(get_args(self.bottom_type | int), (self.bottom_type, int))+        self.assertEqual(get_args(int | self.bottom_type), (int, self.bottom_type))+ @@ -806,2 +836,21 @@         self.assertEqual(D.inited, 3)++    def test_existing_init_subclass_in_sibling_base(self):+        @deprecated("A will go away soon")+        class A:+            pass+        class B:+            def __init_subclass__(cls, x):+                super().__init_subclass__()+                cls.inited = x++        with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"):+            class C(A, B, x=42):+                pass+        self.assertEqual(C.inited, 42)++        with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"):+            class D(B, A, x=42):+                pass+        self.assertEqual(D.inited, 42) @@ -1731,7 +1780,5 @@             Optional[List[str]]     : Optional[List[str]],-            Optional[annotation]     : Optional[annotation],+            Optional[annotation]    : Optional[annotation],             Union[str, None, str]   : Optional[str],             Unpack[Tuple[int, None]]: Unpack[Tuple[int, None]],-            # Note: A starred *Ts will use typing.Unpack in 3.11+ see Issue #485-            Unpack[Ts]              : Unpack[Ts],         }@@ -1751,3 +1798,11 @@             Annotated["annotation", "nested"]  : Annotated[Union[int, None], "data", "nested"],+            # Note: A starred *Ts will use typing.Unpack in 3.11+ see Issue #485+            Unpack[Ts]                         : Unpack[Ts],         }+        # Note: A starred *Ts will use typing.Unpack in 3.11+ see Issue #485+        if TYPING_3_15_0:+            # The repr is typing.Unpack[~Ts], which cannot be evaluated.+            do_not_stringify_cases[Unpack[Ts]] = Unpack[Ts]+        else:+            cases[Unpack[Ts]] = Unpack[Ts]         if TYPING_3_10_0:  # cannot construct UnionTypes before 3.10@@ -2212,2 +2267,35 @@ +    def test_setattr(self):+        origin = collections.abc.Generator+        alias = typing_extensions.Generator+        original_name = alias._name++        def cleanup():+            for obj in origin, alias:+                for attr in 'foo', '__dunder__':+                    try:+                        delattr(obj, attr)+                    except Exception:+                        pass+            try:+                alias._name = original_name+            except Exception:+                pass++        self.addCleanup(cleanup)++        # Attribute assignment on generic alias sets attribute on origin+        alias.foo = 1+        self.assertEqual(alias.foo, 1)+        self.assertEqual(origin.foo, 1)+        # Except for dunders...+        alias.__dunder__ = 2+        self.assertEqual(alias.__dunder__, 2)+        self.assertRaises(AttributeError, lambda: origin.__dunder__)++        # ...and certain known attributes+        alias._name = "NewName"+        self.assertEqual(alias._name, "NewName")+        self.assertRaises(AttributeError, lambda: origin._name)+ @@ -2380,2 +2468,12 @@                 ...++    def test_module_with_incomplete_sys(self):+        def does_not_exist(*args):+            raise AttributeError+        with (+            patch("sys._getframemodulename", does_not_exist, create=True),+            patch("sys._getframe", does_not_exist, create=True),+        ):+            X = NewType("X", int)+            self.assertEqual(X.__module__, None) @@ -3801,3 +3899,9 @@ +        class CustomPathLikeProtocol(os.PathLike, Protocol):+            pass+         class CustomContextManager(typing.ContextManager, Protocol):+            pass++        class CustomAsyncIterator(typing.AsyncIterator, Protocol):             pass@@ -4440,4 +4544,8 @@                     )-                    base_anno = typing.ForwardRef("int", module="builtins") if base_future else int-                    child_anno = typing.ForwardRef("int", module="builtins") if child_future else int+                    if sys.version_info >= (3, 14):+                        base_anno = typing.ForwardRef("int", module="builtins", owner=base) if base_future else int+                        child_anno = typing.ForwardRef("int", module="builtins", owner=child) if child_future else int+                    else:+                        base_anno = typing.ForwardRef("int", module="builtins") if base_future else int+                        child_anno = typing.ForwardRef("int", module="builtins") if child_future else int                     self.assertEqual(base.__annotations__, {'base': base_anno})@@ -4569,2 +4677,43 @@                         pass++    def test_keys_inheritance_with_same_name(self):+        class NotTotal(TypedDict, total=False):+            a: int++        class Total(NotTotal):+            a: int++        self.assertEqual(NotTotal.__required_keys__, frozenset())+        self.assertEqual(NotTotal.__optional_keys__, frozenset(['a']))+        self.assertEqual(Total.__required_keys__, frozenset(['a']))+        self.assertEqual(Total.__optional_keys__, frozenset())++        class Base(TypedDict):+            a: NotRequired[int]+            b: Required[int]++        class Child(Base):+            a: Required[int]+            b: NotRequired[int]++        self.assertEqual(Base.__required_keys__, frozenset(['b']))+        self.assertEqual(Base.__optional_keys__, frozenset(['a']))+        self.assertEqual(Child.__required_keys__, frozenset(['a']))+        self.assertEqual(Child.__optional_keys__, frozenset(['b']))++    def test_multiple_inheritance_with_same_key(self):+        class Base1(TypedDict):+            a: NotRequired[int]++        class Base2(TypedDict):+            a: Required[str]++        class Child(Base1, Base2):+            pass++        # Last base wins+        self.assertEqual(Child.__annotations__, {'a': Required[str]})+        self.assertEqual(Child.__required_keys__, frozenset(['a']))+        self.assertEqual(Child.__optional_keys__, frozenset())+ @@ -5299,2 +5448,13 @@ +    @skipUnless(TYPING_3_10_0, "PEP 604 has yet to be")+    def test_or(self):+        class TD(TypedDict):+            a: int++        self.assertEqual(TD | int, Union[TD, int])+        self.assertEqual(int | TD, Union[int, TD])++        self.assertEqual(get_args(TD | int), (TD, int))+        self.assertEqual(get_args(int | TD), (int, TD))+ class AnnotatedTests(BaseTestCase):@@ -5519,2 +5679,15 @@             BA2+        )++    @skipUnless(TYPING_3_11_0, "TODO: evaluate nested forward refs in Python < 3.11")+    def test_get_type_hints_genericalias(self):+        def foobar(x: list['X']): ...+        X = Annotated[int, (1, 10)]+        self.assertEqual(+            get_type_hints(foobar, globals(), locals()),+            {'x': list[int]}+        )+        self.assertEqual(+            get_type_hints(foobar, globals(), locals(), include_extras=True),+            {'x': list[Annotated[int, (1, 10)]]}         )@@ -5975,2 +6148,7 @@ +    def test_subclass(self):+        with self.assertRaises(TypeError):+            class MyParamSpec(ParamSpec):+                pass+ @@ -6133,2 +6311,43 @@ +    def test_isinstance_results_unaffected_by_presence_of_tracing_function(self):+        # See https://github.com/python/typing_extensions/issues/661++        code = textwrap.dedent(+            """\+            import sys, typing++            def trace_call(*args):+                return trace_call
… 410 more lines (truncated)
pyproject.toml +3 lines
--- +++ @@ -8,3 +8,3 @@ name = "typing_extensions"-version = "4.15.0"+version = "4.16.0" description = "Backported and Experimental Type Hints for Python 3.9+"@@ -42,2 +42,3 @@     "Programming Language :: Python :: 3.14",+    "Programming Language :: Python :: 3.15",     "Topic :: Software Development",@@ -92,3 +93,2 @@     "UP035",-    "UP038",     "UP045",  # X | None instead of Optional[X]@@ -125,2 +125,3 @@ fail_under = 96+precision = 2 show_missing = true
src/typing_extensions.py +232 lines
--- +++ @@ -93,2 +93,3 @@     'Protocol',+    'sentinel',     'Sentinel',@@ -150,3 +151,2 @@     'no_type_check',-    'no_type_check_decorator', ]@@ -162,13 +162,117 @@ ++def _caller(depth=1, default='__main__'):+    try:+        return sys._getframemodulename(depth + 1) or default+    except AttributeError:  # For platforms without _getframemodulename()+        pass+    try:+        return sys._getframe(depth + 1).f_globals.get('__name__', default)+    except (AttributeError, ValueError):  # For platforms without _getframe()+        pass+    return None+++# Placeholder for sentinel methods, because sentinels can not have their own sentinels+_sentinel_placeholder = object()++if hasattr(builtins, "sentinel"):  # 3.15++    sentinel = builtins.sentinel+else:+    class sentinel:+        """Create a unique sentinel object.++        *name* should be the name of the variable to which the return value+        shall be assigned.+        """++        def __init__(+            self,+            __name: str = _sentinel_placeholder,+            __repr: typing.Optional[str] = _sentinel_placeholder,+            /,+            *,+            repr: typing.Optional[str] = None,+            name: str = _sentinel_placeholder,+        ) -> None:+            if name is not _sentinel_placeholder:+                warnings.warn(+                    "Passing 'name' as a keyword argument is deprecated; "+                    "pass it positionally instead.",+                    DeprecationWarning,+                    stacklevel=2,+                )+                __name = name+            if __name is _sentinel_placeholder:+                raise TypeError("First parameter 'name' is required")+            if __repr is not _sentinel_placeholder:+                warnings.warn(+                    "Passing 'repr' as a positional argument is deprecated; "+                    "pass it by keyword instead.",+                    DeprecationWarning,+                    stacklevel=2,+                )+                repr = __repr++            self._name = __name+            self._repr = repr if repr is not None else __name++            # For pickling as a singleton:+            self.__module__ = _caller()++        def __init_subclass__(cls):+            warnings.warn(+                "Subclassing sentinel is deprecated "+                "and will be disallowed in Python 3.15",+                DeprecationWarning,+                stacklevel=2,+            )+            super().__init_subclass__()++        def __setattr__(self, attr: str, value: object) -> None:+            if attr not in {"_name", "_repr", "__module__"}:+                warnings.warn(+                    f"Setting attribute {attr!r} on sentinel objects is deprecated "+                    "and will be disallowed in Python 3.15.",+                    DeprecationWarning,+                    stacklevel=2,+                )+            super().__setattr__(attr, value)++        @property+        def __name__(self) -> str:+            return self._name++        @__name__.setter+        def __name__(self, value: str) -> None:+            self._name = value++        def __repr__(self) -> str:+            return self._repr++        if sys.version_info < (3, 11):+            # The presence of this method convinces typing._type_check+            # that Sentinels are types.+            def __call__(self, *args, **kwargs):+                raise TypeError(f"{type(self).__name__!r} object is not callable")++        # Breakpoint: https://github.com/python/cpython/pull/21515+        if sys.version_info >= (3, 10):+            def __or__(self, other):+                return typing.Union[self, other]++            def __ror__(self, other):+                return typing.Union[other, self]++        def __reduce__(self) -> str:+            """Reduce this sentinel to a singleton."""+            return self.__name__  # Module is taken from the __module__ attribute++Sentinel = sentinel++_marker = sentinel("sentinel")++ # The functions below are modified copies of typing internal helpers. # They are needed by _ProtocolMeta and they provide support for PEP 646.---class _Sentinel:-    def __repr__(self):-        return "<sentinel>"---_marker = _Sentinel()- @@ -526,3 +630,5 @@     class _SpecialGenericAlias(typing._SpecialGenericAlias, _root=True):-        def __init__(self, origin, nparams, *, inst=True, name=None, defaults=()):+        def __init__(self, origin, nparams, *, defaults, inst=True, name=None):+            assert nparams > 0, "`nparams` must be a positive integer"+            assert defaults, "Must always specify a non-empty sequence for `defaults`"             super().__init__(origin, nparams, inst=inst, name=name)@@ -544,4 +650,3 @@             if (-                self._defaults-                and len(params) < self._nparams+                len(params) < self._nparams                 and len(params) + len(self._defaults) >= self._nparams@@ -552,8 +657,3 @@             if actual_len != self._nparams:-                if self._defaults:-                    expected = f"at least {self._nparams - len(self._defaults)}"-                else:-                    expected = str(self._nparams)-                if not self._nparams:-                    raise TypeError(f"{self} is not a generic class")+                expected = f"at least {self._nparams - len(self._defaults)}"                 raise TypeError(@@ -589,6 +689,9 @@         'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',-        'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer',+        'AsyncIterator', 'Hashable', 'Sized', 'Container', 'Collection',+        'Reversible', 'Buffer',     ],     'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],+    'io': ['Reader', 'Writer'],     'typing_extensions': ['Buffer'],+    'os': ['PathLike'], }@@ -614,18 +717,8 @@ -def _caller(depth=1, default='__main__'):-    try:-        return sys._getframemodulename(depth + 1) or default-    except AttributeError:  # For platforms without _getframemodulename()-        pass-    try:-        return sys._getframe(depth + 1).f_globals.get('__name__', default)-    except (AttributeError, ValueError):  # For platforms without _getframe()-        pass-    return None-- # `__match_args__` attribute was removed from protocol members in 3.13, # we want to backport this change to older Python versions.-# Breakpoint: https://github.com/python/cpython/pull/110683-if sys.version_info >= (3, 13):+# 3.14 additionally added `io.Reader`, `io.Writer` and `os.PathLike` to+# the list of allowed protocol allowlist.+# https://github.com/python/cpython/issues/127647+if sys.version_info >= (3, 14):     Protocol = typing.Protocol@@ -1040,6 +1133,6 @@ # Update this to something like >=3.13.0b1 if and when-# PEP 728 is implemented in CPython-_PEP_728_IMPLEMENTED = False--if _PEP_728_IMPLEMENTED:+# PEP 764 is implemented in CPython+_PEP_764_IMPLEMENTED = False++if _PEP_764_IMPLEMENTED:     # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"@@ -1053,3 +1146,4 @@     # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.-    # PEP 728 (still pending) makes more changes.+    # PEP 728 (Python 3.15+) adds the `extra_items` and `closed` keywords.+    # PEP 764 (still pending) allows the `TypedDict` special form to be subscripted.     TypedDict = typing.TypedDict@@ -1157,4 +1251,10 @@                     annotations.update(base_dict.get('__annotations__', {}))-                required_keys.update(base_dict.get('__required_keys__', ()))-                optional_keys.update(base_dict.get('__optional_keys__', ()))+                base_required = base_dict.get('__required_keys__', set())+                required_keys |= base_required+                optional_keys -= base_required++                base_optional = base_dict.get('__optional_keys__', set())+                required_keys -= base_optional+                optional_keys |= base_optional+                 readonly_keys.update(base_dict.get('__readonly_keys__', ()))@@ -1186,9 +1286,15 @@                 if Required in qualifiers:+                    is_required = True+                elif NotRequired in qualifiers:+                    is_required = False+                else:+                    is_required = total++                if is_required:                     required_keys.add(annotation_key)-                elif NotRequired in qualifiers:-                    optional_keys.add(annotation_key)-                elif total:-                    required_keys.add(annotation_key)+                    optional_keys.discard(annotation_key)                 else:                     optional_keys.add(annotation_key)+                    required_keys.discard(annotation_key)+                 if ReadOnly in qualifiers:@@ -1800,3 +1906,3 @@                                              contravariant=contravariant)-                paramspec.__infer_variance__ = infer_variance+                paramspec.__infer_variance__ = bool(infer_variance) @@ -1896,6 +2002,3 @@
… 238 more lines (truncated)

No packages match — nothing recent right now. Clear the filters to see the full watchlist.

alert feed
1mo ago · react-dom — BURST ACTIVE registry-verified
3 releases in 2m: 19.2.8, 19.1.9, 19.0.8
1mo ago · react — BURST ACTIVE registry-verified
3 releases in 2m: 19.2.8, 19.1.9, 19.0.8
1mo ago · eslint — BURST ACTIVE registry-verified
2 releases in 41m: 9.39.5, 10.7.0
1mo ago · @types/node — BURST ACTIVE registry-verified
4 releases in 0m: 26.1.1, 25.9.5, 24.13.3, 22.20.1
1mo ago · charset-normalizer — YANK ACTIVE registry-verified
3.4.8 marked yanked (still downloadable)
1mo ago · grpcio-status — YANK ACTIVE registry-verified
1.82.0 marked yanked (still downloadable)
1mo ago · prettier — BURST ACTIVE registry-verified
2 releases in 9m: 3.9.2, 3.9.3
1mo ago · pandas — YANK historic registry-verified
3.0.4 marked yanked (still downloadable)
2mo ago · @types/node — BURST ACTIVE registry-verified
2 releases in 0m: 26.0.0, 25.9.4
2mo ago · axios — BURST ACTIVE registry-verified
2 releases in 0m: 0.33.0, 1.18.0
2mo ago · @types/node — BURST ACTIVE registry-verified
4 releases in 0m: 25.9.3, 24.13.2, 22.19.21, 20.19.43
2mo ago · @types/node — BURST ACTIVE registry-verified
4 releases in 0m: 25.9.2, 24.13.1, 22.19.20, 20.19.42
2mo ago · @types/react — BURST ACTIVE registry-verified
2 releases in 0m: 19.2.17, 18.3.31
2mo ago · @types/react — BURST ACTIVE registry-verified
3 releases in 0m: 19.2.16, 18.3.30, 17.0.93
2mo ago · react-dom — BURST ACTIVE registry-verified
3 releases in 4m: 19.0.7, 19.1.8, 19.2.7
2mo ago · react — BURST ACTIVE registry-verified
3 releases in 4m: 19.0.7, 19.1.8, 19.2.7
2mo ago · @babel/core — BURST ACTIVE registry-verified
2 releases in 22m: 7.29.6, 7.29.7
3mo ago · @types/react — BURST ACTIVE registry-verified
5 releases in 0m: 19.2.15, 18.3.29, 17.0.92, 16.14.70, 15.7.37
3mo ago · @types/node — BURST ACTIVE registry-verified
3 releases in 0m: 24.12.4, 22.19.19, 20.19.41
3mo ago · @types/node — BURST ACTIVE registry-verified
4 releases in 0m: 25.6.2, 24.12.3, 22.19.18, 20.19.40
3mo ago · react-dom — BURST ACTIVE registry-verified
3 releases in 1m: 19.2.6, 19.1.7, 19.0.6
3mo ago · react — BURST ACTIVE registry-verified
3 releases in 1m: 19.2.6, 19.1.7, 19.0.6
4mo ago · axios — BURST ACTIVE registry-verified
2 releases in 4m: 1.15.1, 0.31.1
4mo ago · react-dom — BURST historic registry-verified
3 releases in 1m: 19.2.5, 19.1.6, 19.0.5
4mo ago · react — BURST historic registry-verified
3 releases in 1m: 19.2.5, 19.1.6, 19.0.5
4mo ago · @types/node — BURST historic registry-verified
4 releases in 0m: 25.5.2, 24.12.2, 22.19.17, 20.19.39
4mo ago · @types/node — BURST historic registry-verified
4 releases in 0m: 25.5.1, 24.12.1, 22.19.16, 20.19.38
4mo ago · ts-jest — BURST historic registry-verified
3 releases in 49m: 29.4.7, 29.4.8, 29.4.9
4mo ago · axios — DELETION historic registry-verified
0.30.4 published then removed
4mo ago · axios — DELETION historic registry-verified
1.14.1 published then removed
4mo ago · axios — BURST historic registry-verified
2 releases in 39m: 1.14.1, 0.30.4
4mo ago · pydantic-core — YANK historic registry-verified
2.44.0 marked yanked (still downloadable)
4mo ago · pydantic-core — YANK historic registry-verified
2.43.0 marked yanked (still downloadable)
5mo ago · @types/node — BURST historic registry-verified
4 releases in 1m: 25.3.5, 24.11.2, 22.19.15, 20.19.37
5mo ago · @types/node — BURST historic registry-verified
4 releases in 1m: 25.3.4, 24.11.1, 22.19.14, 20.19.36
5mo ago · @types/node — BURST historic registry-verified
4 releases in 1m: 25.3.2, 24.10.15, 22.19.13, 20.19.35
5mo ago · @types/node — BURST historic registry-verified
4 releases in 1m: 25.3.1, 24.10.14, 22.19.12, 20.19.34
6mo ago · rollup — BURST historic registry-verified
2 releases in 34m: 2.80.0, 3.30.0
6mo ago · grpcio-status — YANK historic registry-verified
1.78.1 marked yanked (still downloadable)
6mo ago · @types/node — BURST historic registry-verified
3 releases in 0m: 25.2.3, 24.10.13, 22.19.11