{ "version": 3, "sources": ["../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/util/Char.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/censor/BuiltinStrategies.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/util/Interval.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/matcher/MatchPayload.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/censor/TextCensor.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/matcher/BlacklistedTerm.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/dataset/DataSet.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/pattern/Nodes.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/pattern/Util.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/TransformerSet.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/util/CharacterIterator.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/matcher/IntervalCollection.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/matcher/regexp/RegExpMatcher.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/matcher/Matcher.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/pattern/ParserError.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/pattern/Parser.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/pattern/Pattern.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/Transformers.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/collapse-duplicates/transformer.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/collapse-duplicates/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/remap-characters/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/resolve-confusables/confusables.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/resolve-confusables/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/resolve-leetspeak/dictionary.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/resolve-leetspeak/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/to-ascii-lowercase/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/preset/english.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/transformer/skip-non-alphabetic/index.js", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/index.js", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/_assert.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/crypto.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/utils.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/_sha2.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/sha256.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/abstract/utils.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/abstract/modular.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/abstract/curve.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/abstract/weierstrass.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.2/node_modules/@noble/hashes/src/hmac.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/_shortw_utils.ts", "../../../node_modules/.pnpm/@noble+curves@1.2.0/node_modules/@noble/curves/src/secp256k1.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.1/node_modules/@noble/hashes/src/crypto.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.1/node_modules/@noble/hashes/src/utils.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.1/node_modules/@noble/hashes/src/_assert.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.1/node_modules/@noble/hashes/src/_sha2.ts", "../../../node_modules/.pnpm/@noble+hashes@1.3.1/node_modules/@noble/hashes/src/sha256.ts", "../../../node_modules/.pnpm/nostr-tools@2.10.4_typescript@5.7.2/node_modules/nostr-tools/lib/esm/pool.js", "../../../src/ts/entry/secret-live-project.tsx", "../../../node_modules/.pnpm/emittery@1.0.3/node_modules/emittery/maps.js", "../../../node_modules/.pnpm/emittery@1.0.3/node_modules/emittery/index.js", "../../../node_modules/.pnpm/@getalby+sdk@3.8.2_typescript@5.7.2/node_modules/@getalby/sdk/dist/index.modern.js", "../../../src/ts/entry/live.phantompowermusic.io.tsx", "../../../node_modules/.pnpm/obscenity@0.4.1/node_modules/obscenity/dist/index.mjs", "../../../node_modules/.pnpm/canvas-confetti@1.9.3/node_modules/canvas-confetti/dist/confetti.module.mjs"], "sourcesContent": ["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getAndAssertSingleCodePoint = exports.invertCaseOfAlphabeticChar = exports.isUpperCase = exports.isLowerCase = exports.isAlphabetic = exports.isDigit = exports.isWordChar = exports.convertSurrogatePairToCodePoint = exports.isLowSurrogate = exports.isHighSurrogate = void 0;\nfunction isHighSurrogate(char) {\n return 55296 /* CharacterCode.HighSurrogateStart */ <= char && char <= 56319 /* CharacterCode.HighSurrogateEnd */;\n}\nexports.isHighSurrogate = isHighSurrogate;\nfunction isLowSurrogate(char) {\n return 56320 /* CharacterCode.LowSurrogateStart */ <= char && char <= 57343 /* CharacterCode.LowSurrogateEnd */;\n}\nexports.isLowSurrogate = isLowSurrogate;\n// See https://unicodebook.readthedocs.io/unicode_encodings.html#utf-16-surrogate-pairs.\nfunction convertSurrogatePairToCodePoint(highSurrogate, lowSurrogate) {\n return ((highSurrogate - 55296 /* CharacterCode.HighSurrogateStart */) * 0x400 +\n lowSurrogate -\n 56320 /* CharacterCode.LowSurrogateStart */ +\n 0x10000);\n}\nexports.convertSurrogatePairToCodePoint = convertSurrogatePairToCodePoint;\nfunction isWordChar(char) {\n return isDigit(char) || isAlphabetic(char);\n}\nexports.isWordChar = isWordChar;\nfunction isDigit(char) {\n return 48 /* CharacterCode.Zero */ <= char && char <= 57 /* CharacterCode.Nine */;\n}\nexports.isDigit = isDigit;\nfunction isAlphabetic(char) {\n return isLowerCase(char) || isUpperCase(char);\n}\nexports.isAlphabetic = isAlphabetic;\nfunction isLowerCase(char) {\n return 97 /* CharacterCode.LowerA */ <= char && char <= 122 /* CharacterCode.LowerZ */;\n}\nexports.isLowerCase = isLowerCase;\nfunction isUpperCase(char) {\n return 65 /* CharacterCode.UpperA */ <= char && char <= 90 /* CharacterCode.UpperZ */;\n}\nexports.isUpperCase = isUpperCase;\n// Input must be a lower-case or upper-case ASCII alphabet character.\nfunction invertCaseOfAlphabeticChar(char) {\n return char ^ 0x20;\n}\nexports.invertCaseOfAlphabeticChar = invertCaseOfAlphabeticChar;\n// Asserts that the string is comprised of one and only one code point,\n// then returns said code point.\nfunction getAndAssertSingleCodePoint(str) {\n if ([...str].length !== 1)\n throw new RangeError(`Expected the input string to be one code point in length.`);\n return str.codePointAt(0);\n}\nexports.getAndAssertSingleCodePoint = getAndAssertSingleCodePoint;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.randomCharFromSetCensorStrategy = exports.fixedCharCensorStrategy = exports.fixedPhraseCensorStrategy = exports.grawlixCensorStrategy = exports.asteriskCensorStrategy = exports.keepEndCensorStrategy = exports.keepStartCensorStrategy = void 0;\nconst Char_1 = require(\"../util/Char\");\n/**\n * A text censoring strategy that extends another strategy, adding the first\n * character matched at the start of the generated string.\n *\n * @example\n * ```typescript\n * const strategy = keepStartCensorStrategy(grawlixCensorStrategy());\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: 'f$@* you'\n * ```\n * @example\n * ```typescript\n * // Since keepEndCensorStrategy() returns another text censoring strategy, you can use it\n * // as the base strategy to pass to keepStartCensorStrategy().\n * const strategy = keepStartCensorStrategy(keepEndCensorStrategy(asteriskCensorStrategy()));\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: 'f**k you'\n * ```\n * @param baseStrategy - Strategy to extend. It will be used to produce the end of\n * the generated string.\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction keepStartCensorStrategy(baseStrategy) {\n return (ctx) => {\n if (ctx.overlapsAtStart)\n return baseStrategy(ctx);\n const firstChar = String.fromCodePoint(ctx.input.codePointAt(ctx.startIndex));\n return firstChar + baseStrategy({ ...ctx, matchLength: ctx.matchLength - 1 });\n };\n}\nexports.keepStartCensorStrategy = keepStartCensorStrategy;\n/**\n * A text censoring strategy that extends another strategy, adding the last\n * character matched at the end of the generated string.\n *\n * @example\n * ```typescript\n * const strategy = keepEndCensorStrategy(asteriskCensorStrategy());\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: '***k you'\n * ```\n * @param baseStrategy - Strategy to extend. It will be used to produce the start\n * of the generated string.\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction keepEndCensorStrategy(baseStrategy) {\n return (ctx) => {\n if (ctx.overlapsAtEnd)\n return baseStrategy(ctx);\n const lastChar = String.fromCodePoint(ctx.input.codePointAt(ctx.endIndex));\n return baseStrategy({ ...ctx, matchLength: ctx.matchLength - 1 }) + lastChar;\n };\n}\nexports.keepEndCensorStrategy = keepEndCensorStrategy;\n/**\n * A text censoring strategy that generates strings made up of asterisks (`*`).\n *\n * @example\n * ```typescript\n * const strategy = asteriskCensorStrategy();\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: '**** you'\n * ```\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction asteriskCensorStrategy() {\n return fixedCharCensorStrategy('*');\n}\nexports.asteriskCensorStrategy = asteriskCensorStrategy;\n/**\n * A text censoring strategy that generates\n * [grawlix](https://www.merriam-webster.com/words-at-play/grawlix-symbols-swearing-comic-strips),\n * i.e. strings that contain the characters `%`, `@`, `$`, `&`, and `*`.\n *\n * @example\n * ```typescript\n * const strategy = grawlixCensorStrategy();\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: '%@&* you'\n * ```\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction grawlixCensorStrategy() {\n return randomCharFromSetCensorStrategy('%@$&*');\n}\nexports.grawlixCensorStrategy = grawlixCensorStrategy;\n/**\n * A text censoring strategy that returns a fixed string.\n *\n * @example\n * ```typescript\n * // The replacement phrase '' effectively removes all matched regions\n * // from the string.\n * const strategy = fixedPhraseCensorStrategy('');\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: ' you'\n * ```\n * @example\n * ```typescript\n * const strategy = fixedPhraseCensorStrategy('fudge');\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: 'fudge you'\n * ```\n * @param phrase - Replacement phrase to use.\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction fixedPhraseCensorStrategy(phrase) {\n return () => phrase;\n}\nexports.fixedPhraseCensorStrategy = fixedPhraseCensorStrategy;\n/**\n * A text censoring strategy that generates replacement strings that are made up\n * of the character given, repeated as many times as needed.\n *\n * @example\n * ```typescript\n * const strategy = fixedCharCensorStrategy('*');\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you'\n * // After: '**** you'.\n * ```\n * @param char - String that represents the code point which should be used when\n * generating the replacement string. Must be exactly one code point in length.\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction fixedCharCensorStrategy(char) {\n // Make sure the input character is one code point in length.\n (0, Char_1.getAndAssertSingleCodePoint)(char);\n return (ctx) => char.repeat(ctx.matchLength);\n}\nexports.fixedCharCensorStrategy = fixedCharCensorStrategy;\n/**\n * A text censoring strategy that generates replacement strings made up of\n * random characters from the set of characters provided.\n *\n * @example\n * ```typescript\n * const strategy = randomCharFromSetCensorStrategy('$#!');\n * const censor = new TextCensor().setStrategy(strategy);\n * // Before: 'fuck you!'\n * // After: '!##$ you!'\n * ```\n * @param charset - Set of characters from which the replacement string should\n * be constructed. Must not be empty.\n * @returns A [[TextCensorStrategy]] for use with the [[TextCensor]].\n */\nfunction randomCharFromSetCensorStrategy(charset) {\n const chars = [...charset];\n if (chars.length === 0)\n throw new Error('The character set passed must not be empty.');\n return (ctx) => {\n let censored = '';\n for (let i = 0; i < ctx.matchLength; i++)\n censored += chars[Math.floor(Math.random() * chars.length)];\n return censored;\n };\n}\nexports.randomCharFromSetCensorStrategy = randomCharFromSetCensorStrategy;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.compareIntervals = void 0;\nfunction compareIntervals(lowerBound0, upperBound0, lowerBound1, upperBound1) {\n if (lowerBound0 < lowerBound1)\n return -1;\n if (lowerBound1 < lowerBound0)\n return 1;\n if (upperBound0 < upperBound1)\n return -1;\n if (upperBound1 < upperBound0)\n return 1;\n return 0;\n}\nexports.compareIntervals = compareIntervals;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.compareMatchByPositionAndId = void 0;\nconst Interval_1 = require(\"../util/Interval\");\n/**\n * Compares two match payloads.\n *\n * If the first match payload's start index is less than the second's, `-1` is\n * returned;\n * If the second match payload's start index is less than the first's, `1` is\n * returned;\n * If the first match payload's end index is less than the second's, `-1` is\n * returned;\n * If the second match payload's end index is less than the first's, `1` is\n * returned;\n * If the first match payload's term ID is less than the second's, `-1` is\n * returned;\n * If the first match payload's term ID is equal to the second's, `0` is\n * returned;\n * Otherwise, `1` is returned.\n *\n * @param a - First match payload.\n * @param b - Second match payload.\n * @returns The result of the comparison: -1 if the first should sort lower than\n * the second, 0 if they are the same, and 1 if the second should sort lower\n * than the first.\n */\nfunction compareMatchByPositionAndId(a, b) {\n const result = (0, Interval_1.compareIntervals)(a.startIndex, a.endIndex, b.startIndex, b.endIndex);\n if (result !== 0)\n return result;\n return a.termId === b.termId ? 0 : a.termId < b.termId ? -1 : 1;\n}\nexports.compareMatchByPositionAndId = compareMatchByPositionAndId;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TextCensor = void 0;\nconst MatchPayload_1 = require(\"../matcher/MatchPayload\");\nconst BuiltinStrategies_1 = require(\"./BuiltinStrategies\");\n/**\n * Censors regions of text matched by a [[Matcher]], supporting flexible\n * [[TextCensorStrategy | censoring strategies]].\n */\nclass TextCensor {\n constructor() {\n this.strategy = (0, BuiltinStrategies_1.grawlixCensorStrategy)();\n }\n /**\n * Sets the censoring strategy, which is responsible for generating\n * replacement text for regions of the text that should be censored.\n *\n * The default censoring strategy is the [[grawlixCensorStrategy]],\n * generating text like `$%@*`. There are several other built-in strategies\n * available:\n * - [[keepStartCensorStrategy]] - extends another strategy and keeps the\n * first character matched, e.g. `f***`.\n * - [[keepEndCensorStrategy]] - extends another strategy and keeps the last\n * character matched, e.g. `***k`.\n * - [[asteriskCensorStrategy]] - replaces the text with asterisks, e.g.\n * `****`.\n * - [[grawlixCensorStrategy]] - the default strategy, discussed earlier.\n *\n * Note that since censoring strategies are just functions (see the\n * documentation for [[TextCensorStrategy]]), it is relatively simple to\n * create your own.\n *\n * To ease creation of common censoring strategies, we provide a number of\n * utility functions:\n * - [[fixedPhraseCensorStrategy]] - generates a fixed phrase, e.g. `fudge`.\n * - [[fixedCharCensorStrategy]] - generates replacement strings constructed\n * from the character given, repeated as many times as needed.\n * - [[randomCharFromSetCensorStrategy]] - generates replacement strings\n * made up of random characters from the set of characters provided.\n *\n * @param strategy - Text censoring strategy to use.\n */\n setStrategy(strategy) {\n this.strategy = strategy;\n return this;\n }\n /**\n * Applies the censoring strategy to the text, returning the censored text.\n *\n * **Overlapping regions**\n *\n * Overlapping regions are an annoying edge case to deal with when censoring\n * text. There is no single best way to handle them, but the implementation\n * of this method guarantees that overlapping regions will always be\n * replaced, following the rules below:\n *\n * - Replacement text for matched regions will be generated in the order\n * specified by [[compareMatchByPositionAndId]];\n * - When generating replacements for regions that overlap at the start with\n * some other region, the start index of the censor context passed to the\n * censoring strategy will be the end index of the first region, plus one.\n *\n * @param input - Input text.\n * @param matches - A list of matches.\n * @returns The censored text.\n */\n applyTo(input, matches) {\n if (matches.length === 0)\n return input;\n const sorted = [...matches].sort(MatchPayload_1.compareMatchByPositionAndId);\n let censored = '';\n let lastIndex = 0; // end index of last match, plus one\n for (let i = 0; i < sorted.length; i++) {\n const match = sorted[i];\n if (lastIndex > match.endIndex)\n continue; // completely contained in the previous span\n const overlapsAtStart = match.startIndex < lastIndex;\n // Add the chunk of text between the end of the last match and the\n // start of the current match.\n if (!overlapsAtStart)\n censored += input.slice(lastIndex, match.startIndex);\n const actualStartIndex = Math.max(lastIndex, match.startIndex);\n const overlapsAtEnd = i < sorted.length - 1 && // not the last match\n match.endIndex >= sorted[i + 1].startIndex && // end index of this match and start index of next one overlap\n match.endIndex < sorted[i + 1].endIndex; // doesn't completely contain next match\n censored += this.strategy({ ...match, startIndex: actualStartIndex, input, overlapsAtStart, overlapsAtEnd });\n lastIndex = match.endIndex + 1;\n }\n censored += input.slice(lastIndex);\n return censored;\n }\n}\nexports.TextCensor = TextCensor;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.assignIncrementingIds = void 0;\n/**\n * Assigns incrementing IDs to the patterns provided, starting with 0. It is\n * useful if you have a list of patterns to match against but don't care about\n * identifying which pattern matched.\n *\n * @example\n * ```typescript\n * const matcher = new RegExpMatcher({\n * ...,\n * blacklistedTerms: assignIncrementingIds([\n * pattern`f?uck`,\n * pattern`|shit|`,\n * ]),\n * });\n * ```\n * @param patterns - List of parsed patterns.\n * @returns A list of blacklisted terms with valid IDs which can then be passed\n * to the [[RegExpMatcher]].\n */\nfunction assignIncrementingIds(patterns) {\n let currentId = 0;\n return patterns.map((pattern) => ({ id: currentId++, pattern }));\n}\nexports.assignIncrementingIds = assignIncrementingIds;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PhraseBuilder = exports.DataSet = void 0;\nconst BlacklistedTerm_1 = require(\"../matcher/BlacklistedTerm\");\n/**\n * Holds phrases (groups of patterns and whitelisted terms), optionally\n * associating metadata with them.\n *\n * @typeParam MetadataType - Metadata type for phrases. Note that the metadata\n * type is implicitly nullable.\n */\nclass DataSet {\n constructor() {\n this.containers = [];\n this.patternCount = 0;\n this.patternIdToPhraseContainer = new Map(); // pattern ID => index of its container\n }\n /**\n * Adds all the phrases from the dataset provided to this one.\n *\n * @example\n * ```typescript\n * const customDataset = new DataSet().addAll(englishDataset);\n * ```\n * @param other - Other dataset.\n */\n addAll(other) {\n for (const container of other.containers)\n this.registerContainer(container);\n return this;\n }\n /**\n * Removes phrases that match the predicate given.\n *\n * @example\n * ```typescript\n * const customDataset = new DataSet<{ originalWord: string }>()\n * \t.addAll(englishDataset)\n * \t.removePhrasesIf((phrase) => phrase.metadata.originalWord === 'fuck');\n * ```\n * @param predicate - A predicate that determines whether or not a phrase should be removed.\n * Return `true` to remove, `false` to keep.\n */\n removePhrasesIf(predicate) {\n // Clear the internal state, then gradually rebuild it by adding the\n // containers that should be kept.\n this.patternCount = 0;\n this.patternIdToPhraseContainer.clear();\n const containers = this.containers.splice(0);\n for (const container of containers) {\n const remove = predicate(container);\n if (!remove)\n this.registerContainer(container);\n }\n return this;\n }\n /**\n * Adds a phrase to this dataset.\n *\n * @example\n * ```typescript\n * const data = new DataSet<{ originalWord: string }>()\n * \t.addPhrase((phrase) => phrase.setMetadata({ originalWord: 'fuck' })\n * \t\t.addPattern(pattern`fuck`)\n * \t\t.addPattern(pattern`f[?]ck`)\n * \t\t.addWhitelistedTerm('Afck'))\n * \t.build();\n * ```\n * @param fn - A function that takes a [[PhraseBuilder]], adds\n * patterns/whitelisted terms/metadata to it, and returns it.\n */\n addPhrase(fn) {\n const container = fn(new PhraseBuilder()).build();\n this.registerContainer(container);\n return this;\n }\n /**\n * Retrieves the phrase metadata associated with a pattern and returns a\n * copy of the match payload with said metadata attached to it.\n *\n * @example\n * ```typescript\n * const matches = matcher.getAllMatches(input);\n * const matchesWithPhraseMetadata = matches.map((match) => dataset.getPayloadWithPhraseMetadata(match));\n * // Now we can access the 'phraseMetadata' property:\n * const phraseMetadata = matchesWithPhraseMetadata[0].phraseMetadata;\n * ```\n * @param payload - Original match payload.\n */\n getPayloadWithPhraseMetadata(payload) {\n const offset = this.patternIdToPhraseContainer.get(payload.termId);\n if (offset === undefined) {\n throw new Error(`The pattern with ID ${payload.termId} does not exist in this dataset.`);\n }\n return {\n ...payload,\n phraseMetadata: this.containers[offset].metadata,\n };\n }\n /**\n * Returns the dataset in a format suitable for usage with the [[RegExpMatcher]].\n *\n * @example\n * ```typescript\n * // With the RegExpMatcher:\n * const matcher = new RegExpMatcher({\n * \t...dataset.build(),\n * \t// additional options here\n * });\n * ```\n */\n build() {\n return {\n blacklistedTerms: (0, BlacklistedTerm_1.assignIncrementingIds)(this.containers.flatMap((p) => p.patterns)),\n whitelistedTerms: this.containers.flatMap((p) => p.whitelistedTerms),\n };\n }\n registerContainer(container) {\n const offset = this.containers.push(container) - 1;\n for (let i = 0, phraseId = this.patternCount; i < container.patterns.length; i++, phraseId++) {\n this.patternIdToPhraseContainer.set(phraseId, offset);\n this.patternCount++;\n }\n }\n}\nexports.DataSet = DataSet;\n/**\n * Builder for phrases.\n */\nclass PhraseBuilder {\n constructor() {\n this.patterns = [];\n this.whitelistedTerms = [];\n }\n /**\n * Associates a pattern with this phrase.\n *\n * @param pattern - Pattern to add.\n */\n addPattern(pattern) {\n this.patterns.push(pattern);\n return this;\n }\n /**\n * Associates a whitelisted pattern with this phrase.\n *\n * @param term - Whitelisted term to add.\n */\n addWhitelistedTerm(term) {\n this.whitelistedTerms.push(term);\n return this;\n }\n /**\n * Associates some metadata with this phrase.\n *\n * @param metadata - Metadata to use.\n */\n setMetadata(metadata) {\n this.metadata = metadata;\n return this;\n }\n /**\n * Builds the phrase, returning a [[PhraseContainer]] for use with the\n * [[DataSet]].\n */\n build() {\n return {\n patterns: this.patterns,\n whitelistedTerms: this.whitelistedTerms,\n metadata: this.metadata,\n };\n }\n}\nexports.PhraseBuilder = PhraseBuilder;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SyntaxKind = void 0;\n/**\n * An enumeration of the kinds of nodes there are.\n */\nvar SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"Optional\"] = 0] = \"Optional\";\n SyntaxKind[SyntaxKind[\"Wildcard\"] = 1] = \"Wildcard\";\n SyntaxKind[SyntaxKind[\"Literal\"] = 2] = \"Literal\";\n SyntaxKind[SyntaxKind[\"BoundaryAssertion\"] = 3] = \"BoundaryAssertion\";\n})(SyntaxKind || (exports.SyntaxKind = SyntaxKind = {}));\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getRegExpStringForNode = exports.compilePatternToRegExp = exports.potentiallyMatchesEmptyString = void 0;\nconst Nodes_1 = require(\"./Nodes\");\nfunction potentiallyMatchesEmptyString(pattern) {\n return pattern.nodes.every((node) => node.kind === Nodes_1.SyntaxKind.Optional);\n}\nexports.potentiallyMatchesEmptyString = potentiallyMatchesEmptyString;\nfunction compilePatternToRegExp(pattern) {\n let regExpStr = '';\n if (pattern.requireWordBoundaryAtStart)\n regExpStr += '\\\\b';\n for (const node of pattern.nodes)\n regExpStr += getRegExpStringForNode(node);\n if (pattern.requireWordBoundaryAtEnd)\n regExpStr += `\\\\b`;\n return new RegExp(regExpStr, 'gs');\n}\nexports.compilePatternToRegExp = compilePatternToRegExp;\nconst regExpSpecialChars = ['[', '.', '*', '+', '?', '^', '$', '{', '}', '(', ')', '|', '[', '\\\\', ']'].map((str) => str.charCodeAt(0));\nfunction getRegExpStringForNode(node) {\n switch (node.kind) {\n case Nodes_1.SyntaxKind.Literal: {\n let str = '';\n for (const char of node.chars) {\n if (regExpSpecialChars.includes(char))\n str += '\\\\';\n str += String.fromCodePoint(char);\n }\n return str;\n }\n case Nodes_1.SyntaxKind.Optional:\n return `(?:${getRegExpStringForNode(node.childNode)})?`;\n case Nodes_1.SyntaxKind.Wildcard:\n return `.`;\n }\n}\nexports.getRegExpStringForNode = getRegExpStringForNode;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TransformerSet = void 0;\nclass TransformerSet {\n constructor(transformers) {\n this.transformers = transformers;\n this.statefulTransformers = Array.from({ length: this.transformers.length });\n for (let i = 0; i < this.transformers.length; i++) {\n const transformer = this.transformers[i];\n if (transformer.type === 1 /* TransformerType.Stateful */) {\n this.statefulTransformers[i] = transformer.factory();\n }\n }\n }\n applyTo(char) {\n let transformed = char;\n for (let i = 0; i < this.transformers.length && transformed !== undefined; i++) {\n const transformer = this.transformers[i];\n if (transformer.type === 0 /* TransformerType.Simple */)\n transformed = transformer.transform(transformed);\n else\n transformed = this.statefulTransformers[i].transform(transformed);\n }\n return transformed;\n }\n resetAll() {\n for (let i = 0; i < this.transformers.length; i++) {\n if (this.transformers[i].type === 1 /* TransformerType.Stateful */) {\n this.statefulTransformers[i].reset();\n }\n }\n }\n}\nexports.TransformerSet = TransformerSet;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CharacterIterator = void 0;\nconst Char_1 = require(\"./Char\");\nclass CharacterIterator {\n constructor(input) {\n this.lastPosition = -1;\n this.currentPosition = 0;\n this._lastWidth = 0;\n this._input = input ?? '';\n }\n get input() {\n return this._input;\n }\n setInput(input) {\n this._input = input;\n this.reset();\n return this;\n }\n reset() {\n this.lastPosition = -1;\n this.currentPosition = 0;\n this._lastWidth = 0;\n }\n next() {\n if (this.done)\n return { done: true, value: undefined };\n this.lastPosition = this.currentPosition;\n const char = this._input.charCodeAt(this.currentPosition++);\n this._lastWidth = 1;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.done || !(0, Char_1.isHighSurrogate)(char))\n return { done: false, value: char };\n // Do we have a surrogate pair?\n const next = this._input.charCodeAt(this.currentPosition);\n if ((0, Char_1.isLowSurrogate)(next)) {\n this._lastWidth++;\n this.currentPosition++;\n return { done: false, value: (0, Char_1.convertSurrogatePairToCodePoint)(char, next) };\n }\n return { done: false, value: char };\n }\n // Position of the iterator; equals the start index of the last character consumed.\n // -1 if no characters were consumed yet.\n get position() {\n return this.lastPosition;\n }\n // Width of the last character consumed; 2 if it was a surrogate pair and 1 otherwise.\n // 0 if no characters were consumed yet.\n get lastWidth() {\n return this._lastWidth;\n }\n get done() {\n return this.currentPosition >= this._input.length;\n }\n [Symbol.iterator]() {\n return this;\n }\n}\nexports.CharacterIterator = CharacterIterator;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.IntervalCollection = void 0;\nclass IntervalCollection {\n constructor() {\n this.dirty = false;\n this.intervals = [];\n }\n insert(lowerBound, upperBound) {\n this.intervals.push([lowerBound, upperBound]);\n this.dirty = true;\n }\n query(lowerBound, upperBound) {\n if (this.intervals.length === 0)\n return false;\n if (this.dirty) {\n this.dirty = false;\n // Sort by lower bound.\n this.intervals.sort(\n /* istanbul ignore next: not possible to write a robust test for this */\n (a, b) => (a[0] < b[0] ? -1 : b[0] < a[0] ? 1 : 0));\n }\n for (const interval of this.intervals) {\n // Since the intervals are sorted by lower bound, if we see an\n // interval with a lower bound greater than the target, we can skip\n // checking all the ones after it as it's impossible that they fully\n // contain the target interval.\n if (interval[0] > lowerBound)\n break;\n if (interval[0] <= lowerBound && upperBound <= interval[1])\n return true;\n }\n return false;\n }\n values() {\n return this.intervals.values();\n }\n [Symbol.iterator]() {\n return this.values();\n }\n}\nexports.IntervalCollection = IntervalCollection;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.RegExpMatcher = void 0;\nconst Char_1 = require(\"../../util/Char\");\nconst Util_1 = require(\"../../pattern/Util\");\nconst TransformerSet_1 = require(\"../../transformer/TransformerSet\");\nconst CharacterIterator_1 = require(\"../../util/CharacterIterator\");\nconst IntervalCollection_1 = require(\"../IntervalCollection\");\nconst MatchPayload_1 = require(\"../MatchPayload\");\n/**\n * An implementation of the [[Matcher]] interface using regular expressions and\n * string searching methods.\n */\nclass RegExpMatcher {\n /**\n * Creates a new [[RegExpMatcher]] with the options given.\n *\n * @example\n * ```typescript\n * // Use the options provided by the English preset.\n * const matcher = new RegExpMatcher({\n * \t...englishDataset.build(),\n * \t...englishRecommendedTransformers,\n * });\n * ```\n * @example\n * ```typescript\n * // Simple matcher that only has blacklisted patterns.\n * const matcher = new RegExpMatcher({\n * blacklistedTerms: assignIncrementingIds([\n * pattern`fuck`,\n * pattern`f?uck`, // wildcards (?)\n * pattern`bitch`,\n * pattern`b[i]tch` // optionals ([i] matches either \"i\" or \"\")\n * ]),\n * });\n *\n * // Check whether some string matches any of the patterns.\n * const doesMatch = matcher.hasMatch('fuck you bitch');\n * ```\n * @example\n * ```typescript\n * // A more advanced example, with transformers and whitelisted terms.\n * const matcher = new RegExpMatcher({\n * blacklistedTerms: [\n * { id: 1, pattern: pattern`penis` },\n * { id: 2, pattern: pattern`fuck` },\n * ],\n * whitelistedTerms: ['pen is'],\n * blacklistMatcherTransformers: [\n * resolveConfusablesTransformer(), // '\uD83C\uDD70' => 'a'\n * resolveLeetSpeakTransformer(), // '$' => 's'\n * foldAsciiCharCaseTransformer(), // case insensitive matching\n * skipNonAlphabeticTransformer(), // 'f.u...c.k' => 'fuck'\n * collapseDuplicatesTransformer(), // 'aaaa' => 'a'\n * ],\n * });\n *\n * // Output all matches.\n * console.log(matcher.getAllMatches('fu.....uuuuCK the pen is mightier than the sword!'));\n * ```\n * @param options - Options to use.\n */\n constructor({ blacklistedTerms, whitelistedTerms = [], blacklistMatcherTransformers = [], whitelistMatcherTransformers = [], }) {\n this.blacklistedTerms = this.compileTerms(blacklistedTerms);\n this.validateWhitelistedTerms(whitelistedTerms);\n this.whitelistedTerms = whitelistedTerms;\n this.blacklistMatcherTransformers = new TransformerSet_1.TransformerSet(blacklistMatcherTransformers);\n this.whitelistMatcherTransformers = new TransformerSet_1.TransformerSet(whitelistMatcherTransformers);\n }\n getAllMatches(input, sorted = false) {\n const whitelistedIntervals = this.getWhitelistedIntervals(input);\n const [transformedToOrigIndex, transformed] = this.applyTransformers(input, this.blacklistMatcherTransformers);\n const matches = [];\n for (const blacklistedTerm of this.blacklistedTerms) {\n for (const match of transformed.matchAll(blacklistedTerm.regExp)) {\n const origStartIndex = transformedToOrigIndex[match.index];\n let origEndIndex = transformedToOrigIndex[match.index + match[0].length - 1];\n // End index is (unfortunately) inclusive, so adjust as necessary.\n if (origEndIndex < input.length - 1 && // not the last character\n (0, Char_1.isHighSurrogate)(input.charCodeAt(origEndIndex)) && // character is a high surrogate\n (0, Char_1.isLowSurrogate)(input.charCodeAt(origEndIndex + 1)) // next character is a low surrogate\n ) {\n origEndIndex++;\n }\n if (!whitelistedIntervals.query(origStartIndex, origEndIndex)) {\n matches.push({\n termId: blacklistedTerm.id,\n startIndex: origStartIndex,\n endIndex: origEndIndex,\n matchLength: [...match[0]].length,\n });\n }\n }\n }\n if (sorted)\n matches.sort(MatchPayload_1.compareMatchByPositionAndId);\n return matches;\n }\n hasMatch(input) {\n const whitelistedIntervals = this.getWhitelistedIntervals(input);\n const [transformedToOrigIndex, transformed] = this.applyTransformers(input, this.blacklistMatcherTransformers);\n for (const blacklistedTerm of this.blacklistedTerms) {\n for (const match of transformed.matchAll(blacklistedTerm.regExp)) {\n const origStartIndex = transformedToOrigIndex[match.index];\n let origEndIndex = transformedToOrigIndex[match.index + match[0].length - 1];\n // End index is (unfortunately) inclusive, so adjust as necessary.\n if (origEndIndex < input.length - 1 && // not the last character\n (0, Char_1.isHighSurrogate)(input.charCodeAt(origEndIndex)) && // character is a high surrogate\n (0, Char_1.isLowSurrogate)(input.charCodeAt(origEndIndex + 1)) // next character is a low surrogate\n ) {\n origEndIndex++;\n }\n if (!whitelistedIntervals.query(origStartIndex, origEndIndex))\n return true;\n }\n }\n return false;\n }\n getWhitelistedIntervals(input) {\n const matches = new IntervalCollection_1.IntervalCollection();\n const [transformedToOrigIndex, transformed] = this.applyTransformers(input, this.whitelistMatcherTransformers);\n for (const whitelistedTerm of this.whitelistedTerms) {\n let lastEnd = 0;\n for (let startIndex = transformed.indexOf(whitelistedTerm, lastEnd); startIndex !== -1; startIndex = transformed.indexOf(whitelistedTerm, lastEnd)) {\n let origEndIndex = transformedToOrigIndex[startIndex + whitelistedTerm.length - 1];\n // End index is (unfortunately) inclusive, so adjust as necessary.\n if (origEndIndex < input.length - 1 && // not the last character\n (0, Char_1.isHighSurrogate)(input.charCodeAt(origEndIndex)) && // character is a high surrogate\n (0, Char_1.isLowSurrogate)(input.charCodeAt(origEndIndex + 1)) // next character is a low surrogate\n ) {\n origEndIndex++;\n }\n matches.insert(transformedToOrigIndex[startIndex], origEndIndex);\n lastEnd = startIndex + whitelistedTerm.length;\n }\n }\n return matches;\n }\n applyTransformers(input, transformers) {\n const transformedToOrigIndex = [];\n let transformed = '';\n const iter = new CharacterIterator_1.CharacterIterator(input);\n for (const char of iter) {\n const transformedChar = transformers.applyTo(char);\n if (transformedChar !== undefined) {\n transformed += String.fromCodePoint(transformedChar);\n while (transformedToOrigIndex.length < transformed.length)\n transformedToOrigIndex.push(iter.position);\n }\n }\n transformers.resetAll();\n return [transformedToOrigIndex, transformed];\n }\n compileTerms(terms) {\n const compiled = [];\n const seenIds = new Set();\n for (const term of terms) {\n if (seenIds.has(term.id))\n throw new Error(`Duplicate blacklisted term ID ${term.id}.`);\n if ((0, Util_1.potentiallyMatchesEmptyString)(term.pattern)) {\n throw new Error(`Pattern with ID ${term.id} potentially matches empty string; this is unsupported.`);\n }\n compiled.push({\n id: term.id,\n regExp: (0, Util_1.compilePatternToRegExp)(term.pattern),\n });\n seenIds.add(term.id);\n }\n return compiled;\n }\n validateWhitelistedTerms(whitelist) {\n if (whitelist.some((term) => term.length === 0)) {\n throw new Error('Whitelisted term set contains empty string; this is unsupported.');\n }\n }\n}\nexports.RegExpMatcher = RegExpMatcher;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ParserError = void 0;\n/**\n * Custom error thrown by the parser when syntactical errors are detected.\n */\nclass ParserError extends Error {\n constructor(message, line, column) {\n super(`${line}:${column}: ${message}`);\n this.name = 'ParserError';\n this.line = line;\n this.column = column;\n }\n}\nexports.ParserError = ParserError;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Parser = void 0;\nconst Char_1 = require(\"../util/Char\");\nconst CharacterIterator_1 = require(\"../util/CharacterIterator\");\nconst Nodes_1 = require(\"./Nodes\");\nconst ParserError_1 = require(\"./ParserError\");\nconst supportsEscaping = [\n 92 /* CharacterCode.Backslash */,\n 91 /* CharacterCode.LeftSquareBracket */,\n 93 /* CharacterCode.RightSquareBracket */,\n 63 /* CharacterCode.QuestionMark */,\n 124 /* CharacterCode.VerticalBar */,\n];\nconst supportsEscapingList = supportsEscaping.map((char) => `'${String.fromCodePoint(char)}'`).join(', ');\nconst eof = -1;\nclass Parser {\n constructor() {\n this.input = '';\n this.line = 1;\n this.column = 1;\n this.position = 0;\n this.lastColumn = 1;\n this.lastWidth = 0;\n }\n parse(input) {\n this.setInput(input);\n const nodes = [];\n const firstNode = this.nextNode();\n const requireWordBoundaryAtStart = firstNode?.kind === Nodes_1.SyntaxKind.BoundaryAssertion;\n if (firstNode && !requireWordBoundaryAtStart)\n nodes.push(firstNode);\n let requireWordBoundaryAtEnd = false;\n while (!this.done) {\n const pos = this.mark();\n const node = this.nextNode();\n if (node.kind !== Nodes_1.SyntaxKind.BoundaryAssertion) {\n nodes.push(node);\n continue;\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!this.done) {\n this.reportError('Boundary assertions are not supported in this position; they are only allowed at the start / end of the pattern.', pos);\n }\n requireWordBoundaryAtEnd = true;\n }\n return { requireWordBoundaryAtStart, requireWordBoundaryAtEnd, nodes };\n }\n setInput(input) {\n this.input = input;\n this.line = 1;\n this.column = 1;\n this.position = 0;\n this.lastColumn = 1;\n this.lastWidth = 0;\n return this;\n }\n nextNode() {\n switch (this.peek()) {\n case eof:\n return undefined;\n case 91 /* CharacterCode.LeftSquareBracket */:\n return this.parseOptional();\n case 93 /* CharacterCode.RightSquareBracket */:\n this.reportError(`Unexpected ']' with no corresponding '['.`);\n // eslint-disable-next-line no-fallthrough\n case 63 /* CharacterCode.QuestionMark */:\n return this.parseWildcard();\n case 124 /* CharacterCode.VerticalBar */:\n return this.parseBoundaryAssertion();\n default:\n return this.parseLiteral();\n }\n }\n get done() {\n return this.position >= this.input.length;\n }\n // Optional ::= '[' Wildcard | Text ']'\n parseOptional() {\n const preOpenBracketPos = this.mark();\n this.next(); // '['\n const postOpenBracketPos = this.mark();\n if (this.done)\n this.reportError(\"Unexpected unclosed '['.\", preOpenBracketPos);\n if (this.accept('['))\n this.reportError('Unexpected nested optional node.', postOpenBracketPos);\n const childNode = this.nextNode();\n if (childNode.kind === Nodes_1.SyntaxKind.BoundaryAssertion) {\n this.reportError('Boundary assertions are not supported in this position; they are only allowed at the start / end of the pattern.', postOpenBracketPos);\n }\n if (!this.accept(']'))\n this.reportError(\"Unexpected unclosed '['.\");\n return { kind: Nodes_1.SyntaxKind.Optional, childNode: childNode };\n }\n // Wildcard ::= '?'\n parseWildcard() {\n this.next(); // '?'\n return { kind: Nodes_1.SyntaxKind.Wildcard };\n }\n // BoundaryAssertion ::= '|'\n parseBoundaryAssertion() {\n this.next(); // '|'\n return { kind: Nodes_1.SyntaxKind.BoundaryAssertion };\n }\n // Literal ::= (NON_SPECIAL | '\\' SUPPORTS_ESCAPING)+\n // NON_SPECIAL ::= _any character other than '\\', '?', '[', ']', or '|'_\n // SUPPORTS_ESCAPING ::= '\\' | '[' | ']' | '?' | '|'\n parseLiteral() {\n const chars = [];\n while (!this.done) {\n if (this.accept('[]?|')) {\n this.backup();\n break;\n }\n const next = this.next();\n if (next === 92 /* CharacterCode.Backslash */) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.done) {\n this.backup();\n this.reportError('Unexpected trailing backslash.');\n }\n // Can we escape the next character?\n const escaped = this.next();\n if (!supportsEscaping.includes(escaped)) {\n const repr = String.fromCodePoint(escaped);\n this.backup();\n this.reportError(`Cannot escape character '${repr}'; the only characters that can be escaped are the following: ${supportsEscapingList}.`);\n }\n chars.push(escaped);\n }\n else {\n chars.push(next);\n }\n }\n return { kind: Nodes_1.SyntaxKind.Literal, chars };\n }\n reportError(message, { line = this.line, column = this.column } = {}) {\n throw new ParserError_1.ParserError(message, line, column);\n }\n // Marks the current position.\n mark() {\n return { line: this.line, column: this.column };\n }\n // Accepts any code point in the charset provided. Iff accepted, the character is consumed.\n accept(charset) {\n const next = this.next();\n const iter = new CharacterIterator_1.CharacterIterator(charset);\n for (const char of iter) {\n if (char === next)\n return true;\n }\n this.backup();\n return false;\n }\n // Reads one code point from the input, without consuming it.\n peek() {\n const next = this.next();\n this.backup();\n return next;\n }\n // Consumes one code point from the input.\n next() {\n if (this.done)\n return eof;\n const char = this.input.charCodeAt(this.position++);\n this.lastWidth = 1;\n if (char === 10 /* CharacterCode.Newline */) {\n this.lastColumn = this.column;\n this.column = 1;\n this.line++;\n return char;\n }\n this.lastColumn = this.column++;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!(0, Char_1.isHighSurrogate)(char) || this.done)\n return char;\n // Do we have a surrogate pair?\n const next = this.input.charCodeAt(this.position);\n if ((0, Char_1.isLowSurrogate)(next)) {\n this.position++;\n this.lastWidth++;\n return (0, Char_1.convertSurrogatePairToCodePoint)(char, next);\n }\n return char;\n }\n // Steps back one character; can only be called once per call to next().\n backup() {\n this.position -= this.lastWidth;\n this.column = this.lastColumn;\n // Adjust line count if needed.\n if (this.lastWidth === 1 && this.input.charCodeAt(this.position) === 10 /* CharacterCode.Newline */) {\n this.line--;\n }\n }\n}\nexports.Parser = Parser;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.parseRawPattern = exports.pattern = void 0;\nconst Parser_1 = require(\"./Parser\");\nconst parser = new Parser_1.Parser();\n/**\n * Parses a pattern, which matches a set of strings; see the `Syntax` section\n * for details. This function is intended to be called as a [template\n * tag](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates).\n *\n * **Syntax**\n *\n * Generally speaking, in patterns, characters are interpreted literally. That\n * is, they match exactly what they are: `a` matches an `a`, `b` matches a `b`,\n * `;` matches a `;`, and so on.\n *\n * However, there are several constructs that have special meaning:\n *\n * - `[expr]` matches either the empty string or `expr` (an **optional\n * expression**). `expr` may be a sequence of literal characters or a wildcard\n * (see below).\n * - `?` matches any character (a **wildcard**).\n * - A `|` at the start or end of the pattern asserts position at a word\n * boundary (a **word boundary assertion**). If `|` is at the start, it\n * ensures that the match either starts at the start of the string or a non-\n * word character preceding it; if it is at the end, it ensures that the match\n * either ends at the end of the string or a non-word character follows it.\n *\n * A word character is an lower-case or upper-case ASCII alphabet character or\n * an ASCII digit.\n * - In a literal, a backslash may be used to **escape** one of the\n * meta-characters mentioned above so that it does match literally: `\\\\[`\n * matches `[`, and does not mark the start of an optional expression.\n *\n * **Note about escapes**\n *\n * As this function operates on raw strings, double-escaping backslashes is\n * not necessary:\n *\n * ```typescript\n * // Use this:\n * const parsed = pattern`hello \\[`;\n * // Don't use this:\n * const parsed = pattern`hello \\\\[`;\n * ```\n *\n * **Examples**\n *\n * - `baz` matches `baz` exactly.\n *\n * - `b\\[ar` matches `b[ar` exactly.\n *\n * - `d?ude` matches `d`, then any character, then `ude`. All of the following\n * strings are matched by this pattern:\n * - `dyude`\n * - `d;ude`\n * - `d!ude`\n *\n * - `h[?]ello` matches either `h`, any character, then `ello` or the literal\n * string `hello`. The set of strings it matches is equal to the union of the\n * set of strings that the two patterns `hello` and `h?ello` match. All of the\n * following strings are matched by this pattern:\n * - `hello`\n * - `h!ello`\n * - `h;ello`\n *\n * - `|foobar|` asserts position at a word boundary, matches the literal string\n * `foobar`, and asserts position at a word boundary:\n * - `foobar` matches, as the start and end of string count as word\n * boundaries;\n * - `yofoobar` does _not_ match, as `f` is immediately preceded by a word\n * character;\n * - `hello foobar bye` matches, as `f` is immediately preceded by a non-word\n * character, and `r` is immediately followed by a non-word character.\n *\n * **Grammar**\n *\n * ```\n * Pattern ::= '['? Atom* ']'?\n * Atom ::= Literal | Wildcard | Optional\n * Optional ::= '[' Literal | Wildcard ']'\n * Literal ::= (NON_SPECIAL | '\\' SUPPORTS_ESCAPING)+\n *\n * NON_SPECIAL ::= _any character other than '\\', '?', '[', ']', or '|'_\n * SUPPORTS_ESCAPING ::= '\\' | '[' | ']' | '?' | '|'\n * ```\n *\n * @example\n * ```typescript\n * const parsed = pattern`hello?`; // match \"hello\", then any character\n * ```\n * @example\n * ```typescript\n * const parsed = pattern`w[o]rld`; // match \"wrld\" or \"world\"\n * ```\n * @example\n * ```typescript\n * const parsed = pattern`my initials are \\[??\\]`; // match \"my initials are [\", then any two characters, then a \"]\"\n * ```\n * @returns The parsed pattern, which can then be used with the\n * [[RegExpMatcher]].\n * @throws [[ParserError]] if a syntactical error was detected while parsing the\n * pattern.\n * @see [[parseRawPattern]] if you want to parse a string into a pattern without\n * using a template tag.\n */\nfunction pattern(strings, ...expressions) {\n let result = strings.raw[0];\n for (const [i, expression] of expressions.entries()) {\n result += expression;\n result += strings.raw[i + 1];\n }\n return parser.parse(result);\n}\nexports.pattern = pattern;\n/**\n * Parses a string as a pattern directly.\n *\n * **Note**\n *\n * It is recommended to use the [[pattern | pattern template tag]] instead of\n * this function for literal patterns (i.e. ones without dynamic content).\n *\n * @param pattern - The string to parse.\n * @throws [[ParserError]] if a syntactical error was detected while parsing the\n * pattern.\n * @returns The parsed pattern, which can then be used with the\n * [[RegExpMatcher]].\n */\nfunction parseRawPattern(pattern) {\n return parser.parse(pattern);\n}\nexports.parseRawPattern = parseRawPattern;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.createStatefulTransformer = exports.createSimpleTransformer = void 0;\n/**\n * Creates a container holding the transformer function provided. Simple\n * transformers are suitable for stateless transformations, e.g., a\n * transformation that maps certain characters to others. For transformations\n * that need to keep around state, see `createStatefulTransformer`.\n *\n * @example\n * ```typescript\n * function lowercaseToUppercase(char) {\n * return isLowercase(char) ? char - 32 : char;\n * }\n *\n * const transformer = createSimpleTransformer(lowercaseToUppercase);\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @example\n * ```typescript\n * function ignoreAllNonDigitChars(char) {\n * return isDigit(char) ? char : undefined;\n * }\n *\n * const transformer = createSimpleTransformer(ignoreAllNonDigitChars);\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @param transformer - Function that applies the transformation. It should\n * accept one argument, the input character, and return the transformed\n * character. A return value of `undefined` indicates that the character should\n * be ignored.\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction createSimpleTransformer(transformer) {\n return { type: 0 /* TransformerType.Simple */, transform: transformer };\n}\nexports.createSimpleTransformer = createSimpleTransformer;\n/**\n * Creates a container holding the stateful transformer. Stateful transformers\n * are objects which satisfy the `StatefulTransformer` interface. They are\n * suitable for transformations that require keeping around some state regarding\n * the characters previously transformed in the text.\n *\n * @example\n * ```typescript\n * class IgnoreDuplicateCharactersTransformer implements StatefulTransformer {\n * private lastChar = -1;\n *\n * public transform(char: number) {\n * if (char === this.lastChar) return undefined;\n * this.lastChar = char;\n * return char;\n * }\n *\n * public reset() {\n * this.lastChar = -1;\n * }\n * }\n *\n * const transformer = createStatefulTransformer(() => new IgnoreDuplicateCharactersTransformer());\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @param factory A function that returns an instance of the stateful\n * transformer.\n * @returns A container holding the stateful transformer, which can then be\n * passed to the [[RegExpMatcher]].\n */\nfunction createStatefulTransformer(factory) {\n return { type: 1 /* TransformerType.Stateful */, factory };\n}\nexports.createStatefulTransformer = createStatefulTransformer;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CollapseDuplicatesTransformer = void 0;\nclass CollapseDuplicatesTransformer {\n constructor({ defaultThreshold, customThresholds }) {\n this.remaining = -1;\n this.lastChar = -1;\n this.defaultThreshold = defaultThreshold;\n this.customThresholds = customThresholds;\n }\n transform(char) {\n if (char === this.lastChar) {\n return this.remaining-- > 0 ? char : undefined;\n }\n const threshold = this.customThresholds.get(char) ?? this.defaultThreshold;\n this.remaining = threshold - 1;\n this.lastChar = char;\n return threshold > 0 ? char : undefined;\n }\n reset() {\n this.remaining = -1;\n this.lastChar = -1;\n }\n}\nexports.CollapseDuplicatesTransformer = CollapseDuplicatesTransformer;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.collapseDuplicatesTransformer = void 0;\nconst Char_1 = require(\"../../util/Char\");\nconst Transformers_1 = require(\"../Transformers\");\nconst transformer_1 = require(\"./transformer\");\n/**\n * Creates a transformer that collapses duplicate characters. This is useful for\n * detecting variants of patterns in which a character is repeated to bypass\n * detection.\n *\n * As an example, the pattern `hi` does not match `hhiii` by default, as the\n * frequency of the characters does not match. With this transformer, `hhiii`\n * would become `hi`, and would therefore match the pattern.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied after all other\n * transformers. Using it before other transformers may have the effect of not\n * catching duplicates of certain characters that were originally different but\n * became the same after a series of transformations.\n *\n * **Warning**\n *\n * This transformer should be used with caution, as while it can make certain\n * patterns match text that wouldn't have been matched before, it can also go\n * the other way. For example, the pattern `hello` clearly matches `hello`, but\n * with this transformer, by default, `hello` would become `helo` which does\n * _not_ match. In this cases, the `customThresholds` option can be used to\n * allow two `l`s in a row, making it leave `hello` unchanged.\n *\n * @example\n * ```typescript\n * // Collapse runs of the same character.\n * const transformer = collapseDuplicatesTransformer();\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @example\n * ```typescript\n * // Collapse runs of characters other than 'a'.\n * const transformer = collapseDuplicatesTransformer({ customThresholds: new Map([['a', Infinity]]) });\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @param options - Options for the transformer.\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction collapseDuplicatesTransformer({ defaultThreshold = 1, customThresholds = new Map(), } = {}) {\n const map = createCharacterToThresholdMap(customThresholds);\n return (0, Transformers_1.createStatefulTransformer)(() => new transformer_1.CollapseDuplicatesTransformer({ defaultThreshold, customThresholds: map }));\n}\nexports.collapseDuplicatesTransformer = collapseDuplicatesTransformer;\nfunction createCharacterToThresholdMap(customThresholds) {\n const map = new Map();\n for (const [str, threshold] of customThresholds) {\n if (threshold < 0)\n throw new RangeError('Expected all thresholds to be non-negative.');\n const char = (0, Char_1.getAndAssertSingleCodePoint)(str);\n map.set(char, threshold);\n }\n return map;\n}\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.remapCharactersTransformer = void 0;\nconst Char_1 = require(\"../../util/Char\");\nconst CharacterIterator_1 = require(\"../../util/CharacterIterator\");\nconst Transformers_1 = require(\"../Transformers\");\n/**\n * Maps certain characters to other characters, leaving other characters\n * unchanged.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied near the start of the\n * transformer chain.\n *\n * @example\n * ```typescript\n * // Transform 'a' to 'b'.\n * const transformer = remapCharactersTransformer({ 'b': 'a' });\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @example\n * ```typescript\n * // Transform '\uD83C\uDD71\uFE0F' to 'b', and use a map instead of an object as the argument.\n * const transformer = remapCharactersTransformer(new Map([['b', '\uD83C\uDD71\uFE0F']]));\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @example\n * ```typescript\n * // Transform '\uD83C\uDDF4' and '0' to 'o'.\n * const transformer = remapCharactersTransformer({ o: '\uD83C\uDDF40' });\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @param mapping - A map/object mapping certain characters to others.\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n * @see [[resolveConfusablesTransformer| Transformer that handles confusable Unicode characters]]\n * @see [[resolveLeetSpeakTransformer | Transformer that handles leet-speak]]\n */\nfunction remapCharactersTransformer(mapping) {\n const map = createOneToOneMap(mapping);\n return (0, Transformers_1.createSimpleTransformer)((c) => map.get(c) ?? c);\n}\nexports.remapCharactersTransformer = remapCharactersTransformer;\nfunction createOneToOneMap(mapping) {\n const map = new Map();\n const iterable = mapping instanceof Map ? mapping.entries() : Object.entries(mapping);\n for (const [original, equivalents] of iterable) {\n const originalChar = (0, Char_1.getAndAssertSingleCodePoint)(original);\n const iter = new CharacterIterator_1.CharacterIterator(equivalents);\n for (const equivalent of iter)\n map.set(equivalent, originalChar);\n }\n return map;\n}\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.confusables = void 0;\n/**\n * Maps confusable Unicode characters to their normalized equivalents.\n *\n * @copyright\n * The data here is taken from the\n * [confusables](https://github.com/gc/confusables) library.\n *\n * ```text\n * # The MIT License (MIT)\n *\n * Copyright \u00A9 2019 https://github.com/gc/\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \u201CSoftware\u201D), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \u201CAS IS\u201D, WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n * ```\n */\nexports.confusables = new Map([\n [' ', ' '],\n ['0', '\u24FF'],\n ['1', '\u24F5\u278A\u2474\u00B9\uD835\uDFCF\uD835\uDFD9\uFF11\uD835\uDFF7\uD835\uDFE3\u2488\uD835\uDFED1\u2780\u2081\u2460\u2776\u2960'],\n ['2', '\u24F6\u2489\u2475\u278B\u01BB\u00B2\u14BF\uD835\uDFDA\uFF12\uD835\uDFEE\uD835\uDFE4\u14BE\uD835\uDFF8\u01A7\uD835\uDFD0\u2461\u1D24\u2082\u2781\u2777\u161D\u01A8'],\n ['3', '\u00B3\u2CCC\uA7AB\uD835\uDFD1\u2128\uD835\uDFDB\uD835\uDFEF\uD835\uDFE5\uA76A\u278C\u0417\u021C\u24F7\u04E0\u01B7\uFF13\uD835\uDFF9\u2476\u248A\u0292\u0293\u01EF\u01EE\u01BA\uD835\uDD74\u1DBE\u0437\u19A1\u2782\u2462\u2083\u1D9A\u1D23\u1D1F\u2778\u0498\u0499\u04EC\u04E1\u04ED\u04DF\u04DE'],\n ['4', '\u278D\u04B6\u13CE\uD835\uDFDC\u04B7\u24F8\u04B8\u04B9\u04F4\u04F5\u1DA3\uFF14\u0447\u3129\u2074\u2783\u2084\u2463\u2779\u04CB\u2477\u248B'],\n ['5', '\uD835\uDFF1\u24F9\u278E\u01BC\uD835\uDFD3\uD835\uDFFB\uD835\uDFDD\uD835\uDFE7\uFF15\u2784\u2085\u2464\u2075\u277A\u01BD\u2478\u248C'],\n ['6', '\u2CD2\u13EE\uD835\uDFDE\uD835\uDFE8\uD835\uDFD4\u278F\u24FA\u03EC\u03ED\u2076\u0431\uFF16\u19C8\u2465\u2785\u2086\u277B\u2479\u248D'],\n ['7', '\u24FB\uD801\uDCD2\u2790\uFF17\u2077\u2466\u2087\u277C\u2786\u247A\u248E'],\n ['8', '\uD800\uDF1A\u2791\u24FC\uFF18\uD835\uDFE0\uD835\uDFEA\u09EA\u2078\u2088\uD835\uDFF4\u2787\u2467\u277D\uD835\uDFFE\uD835\uDFD6\u247B\u248F'],\n ['9', '\uA76E\u2CCA\u24FD\u2792\u0A67\u09ED\u0B68\uFF19\uD835\uDFEB\uD835\uDFFF\uD835\uDFD7\u2079\u2089\u0533\u2788\u2468\u277E\u247C\u2490'],\n ['A', '\uD83C\uDD30\u13AF\uD800\uDEA0\uD835\uDD6C\uD835\uDF1C\uD835\uDC34\uA4EE\u13AA\uD835\uDEA8\uAB7A\uD835\uDF56\uD83C\uDD50\u212B\u2200\uD83C\uDDE6\u20B3\uD83C\uDD70\uD835\uDC9C\uD835\uDE08\uD835\uDC00\uD835\uDD38\u0434\u01FA\u15C5\u24B6\uFF21\u0391\u1F8B\u15E9\u0102\u00C3\u00C5\u01CD\u0200\u0202\u0100\u023A\u0104\u028C\u039B\u03BB\u019B\u1D00\u1D2C\u0414\u0410\u120D\u00C4\u2090\u1571\u00AA\u01DE\u04D2\u0386\u1EA0\u1EA2\u1EA6\u1EA8\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1FB8\u1FB9\u1FBA\u1FBB\u1FBC\u1F88\u1F89\u1F8A\u1F8C\u1F8D\u1F8E\u1F8F\u1F08\u1F09\u1F0A\u1F0B\u1F0C\u1F0D\u1F0E\u1F0F\u1E00\u0226\u01E0\u04D0\u00C0\u00C1\u00C2\u1EA4\u1EAA\uD835\uDEE2\uD835\uDCD0\uD835\uDE70\uD835\uDE3C'],\n ['a', '\u2202\u237A\u24D0\u0571\u01DF\u1D43\u1D8F\u249C\u0430\u0252\uFF41\u03B1\u0203\u0201\u0E04\u01CE\u10DB\u00E4\u0251\u0101\u0250\u0105\u1F84\u1E9A\u1EA1\u1EA3\u01E1\u1EA7\u1EB5\u1E01\u0227\u04D1\u04D3\u00E3\u00E5\u03AC\u1F70\u1F71\u0103\u1EA9\u1EB1\u1EB3\u1EB7\u1F80\u1F81\u1F82\u1F83\u1F85\u1F86\u1FB0\u1FB1\u1FB2\u1FB3\u1FB4\u1D90\u1FB6\u1FB7\u1F00\u1F01\u1F02\u1F03\u1F04\u1F05\u1F06\u1F07\u1F87\u1EAD\u1EAF\u00E0\u00E1\u00E2\u1EA5\u1EAB\u01FB\u2C65\uD835\uDC1A\uD835\uDC4E\uD835\uDC82\uD835\uDCB6\uD835\uDCEA\uD835\uDD1E\uD835\uDD52\uD835\uDD86\uD835\uDDBA\uD835\uDDEE\uD835\uDE22\uD835\uDE56\uD835\uDE8A\uD835\uDEC2\uD835\uDEFC\uD835\uDF36\uD835\uDF70\uD835\uDFAA\u2376'],\n ['B', '\uD800\uDF01\uD835\uDC69\uD835\uDD6D\uD83C\uDD31\uD800\uDEA1\uD835\uDDA1\uD835\uDE3D\uA4D0\uD835\uDDD5\uD835\uDE09\uD835\uDF1D\uD800\uDE82\uD835\uDEA9\uD835\uDC01\uD835\uDEE3\uD835\uDF57\uD835\uDC35\uD835\uDE71\uD835\uDD39\u13F4\u13FC\uD835\uDF91\uA7B4\uD835\uDD05\uD83C\uDD51\u0E3F\uD835\uDCD1\u15FF\u15FE\u15FD\uD83C\uDD71\u24B7\uFF22\u0432\u03D0\u15F7\u0181\u4E43\u00DF\u10EA\u10E9\u0E56\u03B2\u026E\u0411\u0545\u0E52\u1656\u0299\u1D2E\u1D47\u130C\u1E04\u212C\u0392\u0412\u1E9E\u1E02\u1E06\u0243\u0D26\u15F9\u15F8\u1D5D\u165E\u165F\u165D\u16D2\u1657\u1658\u1D03\uD83C\uDDE7'],\n ['b', '\u13CF\uD835\uDC1B\uD835\uDE23\uD835\uDCB7\uD835\uDD1F\uD835\uDCEB\uD835\uDD87\uD835\uDDBB\uD835\uDC4F\uD835\uDE57\uD835\uDD53\uD835\uDC83\uD835\uDDEF\uD835\uDE8B\u266D\u1473\u1488\uFF42\u159A\u1579\u157A\u24D1\u1E03\u1E05\u048D\u044A\u1E07\u0183\u0253\u0185\u15AF\u0184\u042C\u1472\u00FE\u0182\u249D\u042A\u1D80\u147F\u1480\u1482\u1481\u147E\u044C\u0180\u048C\u0462\u0463\u150E'],\n ['C', '\u13DF\u2CA4\uD83C\uDD32\uA4DA\uD800\uDEA2\uD800\uDF02\uD83C\uDD72\uD801\uDC15\uD83C\uDD52\u263E\u010C\u00C7\u24B8\uFF23\u2183\u0187\u1455\u3108\u00A2\u096E\u21BB\u0108\u03FE\u0547\u023B\u1645\u1D9C\u249E\u0106\u0480\u010A\u00A9\u091F\u0186\u2102\u212D\u03F9\u0421\u531A\u1E08\u04AA\u0297\u1456\u1461\u1462\u1463\u1464\u1465\u216D\uD835\uDC02\uD835\uDC36\uD835\uDC6A\uD835\uDC9E\uD835\uDCD2\uD835\uDD6E\uD835\uDDA2\uD835\uDDD6\uD835\uDE0A\uD835\uDE3E\u150D'],\n ['c', '\u2CA5\uD801\uDC3D\uABAF\u0109\uFF43\u24D2\u0107\u010D\u010B\u00E7\u0481\u0188\u1E09\u023C\u2184\u0441\u122D\u1D04\u03F2\u04AB\uA49D\u03C2\u027D\u03DB\uD835\uDE72\u1466\u19DA\uD835\uDC1C\uD835\uDC50\uD835\uDC84\uD835\uDCB8\uD835\uDCEC\uD835\uDD20\uD835\uDD54\uD835\uDD88\uD835\uDDBC\uD835\uDDF0\uD835\uDE24\uD835\uDE58\uD835\uDE8C\u20B5\uD83C\uDDE8\u1974\u14BC\u217D'],\n ['D', '\u13A0\uD83C\uDD33\uD835\uDD21\uD835\uDD89\uD835\uDD3B\uD835\uDDD7\uD835\uDE0B\uD835\uDE73\uD835\uDC37\uD835\uDCD3\uD835\uDC03\uD835\uDC6B\uD835\uDD6F\uD835\uDDA3\uD835\uDD07\uD835\uDE3F\uAB70\u2145\uD835\uDC9F\uA4D3\uD83C\uDD73\uD83C\uDD53\u24B9\uFF24\u0189\u15EA\u018A\u00D0\u053A\u1D05\u1D30\u2181\u1E0A\u0110\u00DE\u216E\u15DE\u146F\u010E\u1E0C\u1E10\u1E12\u1E0E\u15EB\u15EC\u15DF\u15E0\u1D9B\u1D06\uD83C\uDDE9'],\n ['d', '\u13E7\uA4D2\uD835\uDCED\u1D6D\u20AB\u0503\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u1D48\u249F\u0501\u217E\u1D81\u0500\u147A\u147B\u147C\u147D\u1484\u1470\u1471\u1D91\uD835\uDD55\uD835\uDDBD\uD835\uDC51\uD835\uDE25\uD835\uDC85\uD835\uDE59\uD835\uDC1D\uD835\uDDF1\uD835\uDE8D\u2146\uD835\uDCB9\u02A0\u056A'],\n ['E', '\uAB7C\uD83C\uDD34\uD835\uDE40\uD835\uDD3C\uD800\uDE86\uD835\uDEAC\uA4F0\uD835\uDF5A\uD835\uDF94\uD835\uDCD4\uD835\uDC6C\uD835\uDDD8\uD83C\uDD74\uD83C\uDD54\u24BA\u0388\uFF25\u018E\u1F1D\u156E\u0190\u30E2\u0404\u1D07\u1D31\u1D49\u00C9\u4E47\u0401\u0246\uA085\u20AC\u00C8\u2130\u0395\u0415\u2D39\u13AC\u0112\u0114\u0116\u0118\u011A\u00CA\u00CB\u0510\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u1E14\u1E16\u1EBA\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u1E18\u1E1A\u1F18\u1F19\u1F1A\u1F1B\u1F1C\u1FC8\u1FC9\u04D6\u1F72\u1F73\u0400\u03F5\uD83C\uDDEA'],\n ['e', '\uD835\uDC52\uD835\uDCEE\uD835\uDD56\uD835\uDD8A\uD835\uDE26\uD835\uDDF2\uD835\uDE8E\uD835\uDE5A\uD835\uDC86\uD835\uDD22\uD835\uDDBE\uD835\uDC1E\u04BE\u04BF\u24D4\uFF45\u24A0\u00E8\u19C9\u00E9\u1D92\u00EA\u0258\u1F14\u1EC1\u1EBF\u1EC5\u0AEF\u01DD\u0454\u03B5\u0113\u04BD\u025B\u1EC3\u1EBD\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u0247\u2091\u0119\u1E1D\u1E19\u1E1B\u212E\u0435\u0511\u0450\u04D7\u1971\u0451\u1F10\u1F11\u1F12\u1F13\u1F15\u212F'],\n ['F', '\uD83C\uDD35\uD800\uDE87\uD835\uDD09\uD835\uDE0D\uD800\uDEA5\uA4DD\uA798\uD83C\uDD75\uD83C\uDD55\uD835\uDCD5\u24BB\uFF26\u0493\u0492\u15B4\u0191\u0532\u03DD\u127B\u1E1E\u2131\u03DC\u20A3\uD83C\uDDEB\u2132'],\n ['f', '\uD835\uDC1F\uD835\uDD8B\u24D5\uFF46\u0192\u1E1F\u0283\u0562\u1DA0\u24A1\u017F\uA2B0\u0284\u2231\u1D82\uD835\uDE27'],\n ['G', '\uA4D6\u13F3\uD83C\uDD36\u13C0\u13FB\uD835\uDD3E\uD835\uDCD6\uD835\uDC6E\uD835\uDD72\uAB90\uD835\uDCA2\uD835\uDE42\uD835\uDDA6\uD835\uDE76\uD835\uDD0A\uD835\uDC3A\uD835\uDC06\uD83C\uDD76\uD83C\uDD56\u24BC\uFF27\u0262\u0193\u029B\u0122\u161C\u1D33\u01F4\u0120\u050C\u011C\u1E20\u011E\u01E6\u01E4\u050D\u20B2\uD83C\uDDEC\u2141'],\n ['g', '\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u0581\u0AED\u01E5\u0260\uFEED\uFEEE\u1D4D\u24A2\u210A\u0261\u19C1\uD835\uDC20\uD835\uDC54\uD835\uDC88\uD835\uDCF0\uD835\uDD24\uD835\uDD58\uD835\uDD8C\uD835\uDDC0\uD835\uDDF4\uD835\uDE28\uD835\uDE5C\uD835\uDE90'],\n ['H', '\uD83C\uDD37\uD835\uDF22\uA4E7\uD835\uDE0F\uD835\uDC3B\uD835\uDF5C\uD835\uDDA7\uD800\uDECF\uD835\uDDDB\uAB8B\u210D\u13BB\u210C\u2C8E\uD835\uDC6F\uD835\uDF96\uD83C\uDD77\uD83C\uDD57\u12DE\u01F6\u050B\u24BD\uFF28\u0124\u16BA\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u04A2\u04A3\u04A4\u1FCA\u1FCB\u1FCC\u1F28\u1F29\u1F2A\u1F2B\u1F2D\u1F2E\u1F2F\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D\u1F9E\u1F9F\u04C9\u04C8\u04A5\u0389\u043D\u5344\u2653\uD835\uDCD7\u210B\u041D\uD835\uDC07\uD835\uDE43\uD835\uDE77\u029C\uD835\uDEE8\u0397\uD835\uDEAE\u157C\u04C7\u1D34\u1D78\uD83C\uDDED'],\n ['h', '\u04BA\u24A3\u0452\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u0570\u04BB\u12A8\u12A9\u12AA\u12AB\u0266\u210E\uD835\uDC21\uD835\uDC89\uD835\uDCBD\uD835\uDCF1\uD835\uDD25\uD835\uDD59\uD835\uDD8D\uD835\uDDC1\uD835\uDDF5\uD835\uDE29\uD835\uDE5D\uD835\uDE91\u056B\u02B0\u144B\u15C1\u0267\u3093\u0265'],\n ['I', '\uD83C\uDD38\u0407\uA024\u13C6\uD83C\uDD78\uD83C\uDD58\u0625\uFE87\u0673\u0623\uFE83\u0672\u0675\u24BE\uFF29\u17F8\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197\u30A7\u30A8\u1FD8\u1FD9\u1FDA\u1FDB\u1F38\u1F39\u1F3A\u1F3B\u1F3C\u1F3D\u1F3E\u2160\u03AA\u038A\u026A\u1DA6\u144A\u1963\uD835\uDEEA\uD835\uDC08\uD835\uDE44\uD835\uDE78\uD835\uDCF5\uD835\uDE61\uD835\uDC3C\u1D35\uD835\uDEB0\uD835\uDC70\uD83C\uDDEE'],\n ['i', '\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u1E2D\u1FD0\u1FD1\u1FD2\u1FD3\u1FD6\u1FD7\u1F30\u1F31\u1F32\u2170\u217C\u2223\u2D4F\uFFE8\u05C0\u0627\u0661\u06F1\u07CA\u16C1\u1F33\u1F34\u1F35\u0268\u0456\u1F76\u1F77\u1D96\uD835\uDD26\uD835\uDE92\uD835\uDF78\uD835\uDDC2\uD835\uDC22\uD835\uDD5A\uD835\uDD8E\uD835\uDDF6\uD835\uDE2A\uD835\uDE5E\u03AF\u2071\u1D62\uD835\uDCF2\u24A4'],\n ['J', '\uD83C\uDD39\uD83C\uDD79\uD83C\uDD59\u24BF\uFF2A\u0408\u029D\u148D\u05E0\uFF8C\u0134\u0286\u0E27\u0644\u0575\u0296\u1D0A\u1D36\uFEDD\u130B\u0248\u2C7C\u0542\u0E45\u10B1\u012F\u13AB\u0237\u4E3F\u2110\u2111\u1498\u1499\u149A\u149B\u14B4\u14B5\u148E\u148F\uD83C\uDDEF'],\n ['j', '\u24D9\uFF4A\u03F3\u02B2\u24A5\u0249\u0135\u01F0\u0458\u06B6\u1DA8\uD835\uDCBF\uD835\uDE2B\uD835\uDDF7\uD835\uDC57\uD835\uDE5F\uD835\uDD27\uD835\uDC8B\uD835\uDDC3\uD835\uDCF3\uD835\uDD5B\uD835\uDE93\uD835\uDD8F\uD835\uDC23'],\n ['K', '\uD835\uDDDE\uD83C\uDD3A\uD835\uDF25\uD835\uDE12\uA4D7\uD835\uDE46\uD835\uDD42\u2C94\uD835\uDD0E\uD835\uDEEB\u13E6\uD835\uDF99\uD835\uDCA6\uD83C\uDD7A\uD83C\uDD5A\u20AD\u24C0\uFF2B\u0138\u1E30\u045C\u0198\u043A\u04A0\u03BA\u049B\u049F\u04C4\u029E\u049A\u041A\u04A1\u1D0B\u1D37\u1D4F\u24A6\u16D5\u040C\u1315\u1E32\u039A\u212A\u049C\u049D\u049E\u0136\u1E34\u01E8\u2C69\u03D7\u04C3\uD83C\uDDF0'],\n ['k', '\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\u1D84\uD835\uDC24\uD835\uDE2C\uD835\uDDC4\uD835\uDD5C\uD835\uDF05\uD835\uDF18\uD835\uDF3F\uD835\uDF52\uD835\uDF79\uD835\uDF8C\uD835\uDFB3\uD835\uDE60\uD835\uDE94\uD835\uDC58\uD835\uDC8C\u03F0\uD835\uDECB\uD835\uDEDE\uD835\uDFC6\uD835\uDDF8\uD835\uDCF4\uD835\uDCC0'],\n ['L', '\uD83C\uDD3B\uD801\uDC1B\u2CD0\uD835\uDC73\uD835\uDE7B\uD801\uDC43\uD835\uDCDB\u2CD1\uABAE\u13DE\uA4E1\uD83C\uDD7B\uD83C\uDD5B\uFE88\u2514\u24C1\u0582\uFF2C\u013F\u14AA\u4E5A\u0546\u029F\uA4F6\u03B9\u053C\u1D38\u02E1\u0139\u1228\u1E36\u2097\u0393\u056C\u013B\u1102\u216C\u2112\u2C62\u1967\u1968\u14BB\u14B6\u14B7\u1DAB\uFE8E\u14BA\u14B9\u14B8\u14AB\u23B3\u3125\u0141\u2C60\uFE84\u023D\uD83C\uDDF1'],\n ['l', '\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u04C0\u2113\u1E3D\u1E3B\u0142\uFF9A\u026D\u019A\u026B\u2C61|\u0196\u24A7\u0285\u01C0\u05D5\u05DF\u0399\u0406\uFF5C\u1DA9\u04CF\uD835\uDCD8\uD835\uDD40\uD835\uDDA8\uD835\uDDDC\uD835\uDE10\uD835\uDC25\uD835\uDC59\uD835\uDC8D\uD835\uDCC1\uD835\uDD29\uD835\uDD5D\uD835\uDD91\uD835\uDDC5\uD835\uDDF9\uD835\uDE2D\uD835\uDE95\uD835\uDF24\uD835\uDF5E\u0131\uD835\uDEA4\u0269\u1FBE\uD835\uDECA\uD835\uDF04\uD835\uDF3E\uD835\uDFB2'],\n ['M', '\uD83C\uDD3C\uD800\uDF11\uD800\uDEB0\uA4DF\u2C98\u13B7\uD83C\uDD7C\uD83C\uDD5C\u24C2\uFF2D\u043C\u1E42\u0D71\u15F0\u5DDE\u163B\u10DD\u0E53\u264F\u028D\u164F\u1D0D\u1D39\u1D50\u24A8\u1E3E\u041C\u1E40\u0BF1\u216F\u2133\u039C\u03FA\u16D6\u04CD\u04CE\uD835\uDC0C\uD835\uDC40\uD835\uDC74\uD835\uDCDC\uD835\uDD10\uD835\uDD44\uD835\uDD78\uD835\uDDAC\uD835\uDDE0\uD835\uDE14\uD835\uDE48\uD835\uDE7C\uD835\uDEB3\uD835\uDEED\uD835\uDF27\uD835\uDF61\uD835\uDF9B\uD83C\uDDF2'],\n ['m', '\u20A5\u1D6F\uD835\uDD92\uD835\uDC26\uD835\uDDC6\uD835\uDD2A\uD835\uDD5E\uD835\uDCC2\u24DC\uFF4D\u0D28\u1662\u0D69\u1E3F\u1E41\u217F\u03FB\u1E43\u1320\u0271\u17F3\u1D86\uD835\uDE62\uD835\uDCF6\uD835\uDE96\uD835\uDC5A\uD835\uDDFA\u19D5\u19D7'],\n ['N', '\uD83C\uDD3D\u2115\uA4E0\uD835\uDEEE\uD835\uDF62\uD835\uDE7D\uD835\uDEB4\uD835\uDC75\uD835\uDC41\u2C9A\uD835\uDC0D\uD835\uDCA9\uD835\uDF9C\uD835\uDDE1\uD835\uDE15\uD835\uDF28\uD835\uDCDD\uD835\uDDAD\uD83C\uDD7D\u20A6\uD83C\uDD5D\u0419\u040D\u24C3\u048B\u17F7\uFF2E\u1D0E\u0274\u019D\u144E\u51E0\u0438\u0548\u057C\u0418\u05D4\u041B\u03C0\u1D3A\u1DB0\u0143\u5200\u12AD\u1E44\u207F\u00D1\u041F\u039D\u1D28\u0578\u03D6\u01F8\u0147\u1E46\u0145\u1E4A\u1E48\u0E17\u014A\u04E2\u04E3\u04E4\u04E5\u045B\u045D\u0439\u1962\u048A\u1D3B\uD83C\uDDF3'],\n ['n', '\u05D7\uD835\uDC8F\uD835\uDCF7\uD835\uDE63\uD835\uDC5B\uD835\uDD93\uD835\uDD2B\uD835\uDDC7\uD835\uDE97\uD835\uDDFB\u1952\u24DD\u03AE\uFF4E\u01F9\u1D12\u0144\u00F1\u1F97\u03B7\u1E45\u0148\u1E47\u0272\u0146\u1E4B\u1E49\u0572\u0E96\u054C\u019E\u014B\u24A9\u0E20\u0E01\u0273\u043F\u0149\u043B\u0509\u0220\u1F20\u1F21\u1FC3\u0564\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1FC4\u1FC6\u1FC7\u1FC2\u1F22\u1F23\u1F24\u1F25\u1F26\u1F27\u1F74\u1F75\u1260\u1261\u1262\u1263\u1264\u1265\u1266\u0235\uD835\uDEC8\uD835\uDF02\uD835\uDF3C\uD835\uDF76\uD835\uDFB0\uD835\uDD5F\uD835\uDE2F\uD835\uDC27\uD835\uDCC3\u1D87\u1D70\u1965\u2229'],\n [\n 'O',\n '\uA132\uD83C\uDD3E\uD800\uDE92\uD835\uDFEC\uA4F3\u2C9E\uD801\uDC04\uD800\uDEAB\uD801\uDCC2\uD835\uDF9E\uD83C\uDD5E\u2365\u25EF\u2D41\u2296\uFF10\u229D\uD835\uDF64\u0472\u03F4\uD835\uDEB6\uD835\uDF2A\u047A\u04E6\u04E8\u04EA\u038C\u0298\uD835\uDC0E\u01D1\u00D2\u014E\u00D3\u00D4\u00D5\u020C\u020E\u31FF\u274D\u24C4\uFF2F\u1F4B\u30ED\u2764\u0AE6\u2295\u00D8\u0424\u053E\u0398\u01A0\u1D3C\u1D52\u24AA\u0150\u00D6\u2092\u00A4\u25CA\u03A6\u3007\u039F\u041E\u0555\u0B20\u0D20\u0BE6\u05E1\u1ED2\u1ED0\u1ED6\u1ED4\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u022E\u0230\u022A\u1ECE\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u01FE\u019F\u2D54\u07C0\u17F0\u235C\u2394\u2395\u29B0\u29B1\u29B2\u29B3\u29B4\u29B5\u29B6\u29B7\u29B8\u29B9\u29BA\u29BB\u29BC\u29BD\u29BE\u29BF\u29C0\u29C1\u29C2\u29C3\u1F48\u1F49\u1F4A\u1F4C\u1F4D',\n ],\n [\n 'o',\n '\uD835\uDE98\uD835\uDED0\uD835\uDDC8\uD835\uDFBC\u101D\u2C9F\uD835\uDE64\u1040\uD801\uDC2C\uD835\uDD2C\uD801\uDCEA\uD835\uDCF8\uD83C\uDDF4\u2364\u25CB\u03D9\uD83C\uDD7E\uD835\uDCAA\uD835\uDDAE\uD835\uDFE2\uD835\uDFF6\uD835\uDE7E\uD835\uDE30\uD835\uDDFC\uD835\uDD60\uD835\uDF0A\uD835\uDC28\uD835\uDF7E\uD835\uDFB8\u1424\u24DE\u0473\u19D0\u1972\u00F0\uFF4F\u0C20\u199E\u0553\u00F2\u04E9\u04E7\u00F3\u00BA\u014D\u00F4\u01D2\u020F\u014F\u1ED3\u1ED1\u020D\u1ED7\u1ED5\u00F5\u03C3\u1E4D\u022D\u1E4F\u1F44\u1E51\u1E53\u022F\u022B\u0E4F\u1D0F\u0151\u00F6\u047B\u043E\u12D0\u01ED\u0231\u09E6\u0B66\u0665\u0C66\u0CE6\u0D66\u0E50\u0ED0\u03BF\u0585\u1D11\u0966\u0A66\u1ECF\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u00F8\u01FF\u0275\u056E\u1F40\u1F41\u03CC\u1F78\u1F79\u1F42\u1F43\u1F45',\n ],\n ['P', '\uD83C\uDD3F\uA4D1\uD835\uDEB8\uD835\uDE7F\uD835\uDFA0\uD835\uDE4B\uABB2\u2CA2\uD835\uDCAB\uD835\uDF66\uD835\uDC43\uD835\uDC77\uD835\uDDE3\uD835\uDC0F\uD800\uDE95\uD835\uDF2C\uD835\uDE17\uD835\uDCDF\uD835\uDDAF\uD835\uDEF2\u13E2\uD83C\uDD5F\u048E\uD83C\uDD7F\u24C5\uFF30\u01A4\u146D\u5C38\u1E56\u0580\u03C6\u0584\u1D18\u1D3E\u1D56\u24AB\u1E54\uFF71\u05E7\u0420\u12E8\u1D29\u2C63\u2119\u03A1\u1FEC\u1478\u1476\u1477\u1479\u146C\u146E\uD83C\uDDF5\u20B1'],\n ['p', '\u048F\u2117\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\u1FE5\u03C1\u0440\u01BF\u01F7\u1FE4\u2374\uD835\uDCF9\uD835\uDCC5\uD835\uDC29\uD835\uDC5D\uD835\uDC91\uD835\uDD2D\uD835\uDD61\uD835\uDD95\uD835\uDDC9\uD835\uDDFD\uD835\uDE31\uD835\uDE65\uD835\uDE99\uD835\uDED2\uD835\uDF46\uD835\uDFBA\uD835\uDF0C\uD835\uDF80'],\n ['Q', '\uD83C\uDD40\uD83C\uDD80\uD83C\uDD60\u24C6\uFF31\u211A\u2D55\u051A\uD835\uDC10\uD835\uDC44\uD835\uDC78\uD835\uDCAC\uD835\uDCE0\uD835\uDE80\uD835\uDE18\uD835\uDE4C\uD835\uDDB0\uD835\uDD7C\uD835\uDD14\uD835\uDDE4\uD83C\uDDF6'],\n ['q', '\u24E0\uFF51\u0563\u24AC\u06F9\u0566\u146B\u024B\u024A\u051B\uD835\uDDCA\uD835\uDC5E\uD835\uDE32\uD835\uDD62\uD835\uDE9A\uD835\uDC92\uD835\uDD96\uD835\uDC2A\uD835\uDD2E\uD835\uDCFA\uD835\uDE66'],\n ['R', '\u211E\u211F\uAB71\u13D2\uD801\uDCB4\uABA2\u13A1\uA4E3\uD83C\uDD81\uD83C\uDD61\u24C7\uFF32\u1D19\u0212\u0280\u1587\u044F\u5C3A\u0154\u042F\u0AB0\u01A6\u1D3F\u12EA\u1E5A\u024C\u0281\u211B\u211C\u211D\u1E58\u0158\u0210\u1E5C\u0156\u1E5E\u2C64\uD835\uDC11\uD835\uDC45\uD835\uDC79\uD835\uDCE1\uD835\uDD7D\uD835\uDDB1\uD835\uDDE5\uD835\uDE19\uD835\uDE4D\uD835\uDE81\u16B1\uD83C\uDDF7\u1D1A'],\n ['r', '\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u0433\u0550\u027E\u196C\u1E5F\u024D\u02B3\u24AD\u027C\u0453\u1D26\u1D89\uD835\uDC2B\uD835\uDC5F\uD835\uDC93\uD835\uDCC7\uD835\uDCFB\uD835\uDD2F\uD835\uDD63\uD835\uDD97\uD835\uDDCB\uD835\uDDFF\uD835\uDE33\uD835\uDE67\u1D72\u0491\u1D63'],\n ['S', '\uD83C\uDD42\uA1D9\uD835\uDCE2\uD835\uDDE6\u13DA\uD835\uDCAE\u13D5\uD835\uDE82\uD835\uDC12\uA4E2\uD835\uDDB2\uD835\uDD16\uD835\uDE4E\uD800\uDE96\uD835\uDD7E\uD801\uDC20\uD835\uDE1A\uD835\uDD4A\uD835\uDC46\uD835\uDC7A\uD83C\uDD82\uD83C\uDD62\u24C8\uFF33\u1E68\u015E\u0586\u054F\u0218\u02E2\u24AE\u0405\u1E60\u0160\u015A\u1E64\u015C\u1E66\u1E62\u0D1F\u1515\u1516\u1522\u1521\u1523\u1524'],\n ['s', '\u24E2\uA731\uD801\uDC48\uABAA\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u0282\u1E63\u1E69\u0455\u015F\u0219\u023F\u1D8A\u0C15\uD835\uDC2C\uD835\uDC60\uD835\uDC94\uD835\uDCC8\uD835\uDCFC\uD835\uDD30\uD835\uDD64\uD835\uDD98\uD835\uDDCC\uD835\uDE00\uD835\uDE34\uD835\uDE68\uD835\uDE9C\u078E\uD83C\uDDF8'],\n ['T', '\uD83C\uDD43\uD83C\uDD83\uD800\uDF15\uD835\uDEBB\uD835\uDEF5\uD835\uDD4B\uD835\uDD7F\uD835\uDC7B\uD800\uDEB1\uD800\uDE97\uD835\uDDB3\uD835\uDE4F\uD83D\uDF68\uD835\uDF69\uD835\uDFA3\uD835\uDE83\uD835\uDE1B\uD835\uDC47\uA4D4\u27D9\uD835\uDC13\u2CA6\uD835\uDDE7\u22A4\uD835\uDD17\u13A2\uAB72\uD835\uDCAF\uD83C\uDD63\u23C7\u23C9\u24C9\uFF34\u0442\u04AC\u04AD\u01AC\u30A4\u0166\u0535\u03C4\u1D1B\u1D40\uFF72\u1355\u03EE\u0164\u22A5\u01AE\u03A4\u0422\u4E0B\u1E6A\u1E6C\u021A\u0162\u1E70\u1E6E\u4E05\u4E01\u142A\uD835\uDED5\uD835\uDF0F\uD835\uDF49\uD835\uDF83\uD835\uDFBD\uD835\uDCE3\u3112\uD83C\uDDF9\u1325'],\n ['t', '\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0236\u0A6E\u0567\u0287\u2020\u0163\u1E71\u1E6F\u01AD\u0167\u1D57\u24AF\u0288\u0565\u01AB\uD835\uDC2D\uD835\uDC61\uD835\uDC95\uD835\uDCC9\uD835\uDCFD\uD835\uDD31\uD835\uDD65\uD835\uDD99\uD835\uDDCD\uD835\uDE01\uD835\uDE35\uD835\uDE69\uD835\uDE9D\u30CA'],\n ['U', '\uD83C\uDD44\uA4F4\uD801\uDCCE\uA4A4\uD83C\uDD84\uD83C\uDD64\u0168\u016C\u016E\u1457\u1458\u01D3\u01D5\u01D7\u01D9\u24CA\uFF35\u0216\u144C\u51F5\u01B1\u0574\u0531\uA4F5\u0426\u016A\u0544\u01B2\u1640\u1D41\u1D58\u24B0\u0170\u0AAA\u00DC\u054D\u00D9\u00DA\u00DB\u1E78\u1E7A\u01DB\u1EE6\u0214\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244\u1969\u1467\u222A\u162E\u22C3\uD835\uDC14\uD835\uDC48\uD835\uDC7C\uD835\uDCB0\uD835\uDCE4\uD835\uDD18\uD835\uDD4C\uD835\uDD80\uD835\uDDB4\uD835\uDDE8\uD835\uDE1C\uD835\uDE50\uD835\uDE84\uD83C\uDDFA'],\n ['u', '\u1F7A\u1F7B\u24E4\uFF55\u00F9\u0169\u016B\u1EEB\u1E77\u1E79\u016D\u01D6\u1EEF\u1959\u01DA\u01DC\u1F57\u03C5\u03B0\u0E19\u057D\u028A\u01D8\u01D4\u00FA\u016F\u1D1C\u0171\u0173\u0E22\u00FB\u1E7B\u0446\u1201\u00FC\u1D7E\u1D64\u00B5\u028B\u1EE7\u0215\u0217\u01B0\u1EE9\u1EED\u1EF1\u1EE5\u1E73\u1E75\u0289\u1FE0\u1FE1\u1FE2\u1FE3\u1FE6\u1FE7\u1F50\u1F51\u03CB\u03CD\u1F52\u1F53\u1F54\u1F55\u1F56\u1954\uD835\uDC2E\uD835\uDC62\uD835\uDC96\uD835\uDCCA\uD835\uDCFE\uD835\uDD32\uD835\uDD66\uD835\uDD9A\uD835\uDDCE\u1D99'],\n ['V', '\uD83C\uDD45\uA4E6\uD835\uDC7D\uD835\uDDB5\uD835\uDE1D\u13D9\uD835\uDE85\uD835\uDE51\uD835\uDC15\uD83C\uDD85\uD83C\uDD65\u24CB\uFF36\u142F\u0474\u1D5B\u24B1\u06F7\u1E7E\u2174\u2164\u1E7C\u0667\u2D38\u0476\u143A\u143B\uD83C\uDDFB\uD835\uDCE5'],\n ['v', '\u1200\u24E5\uFF56\uD835\uDF10\uD835\uDF4A\u1E7D\u1E7F\u0C6E\u0E07\u0475\u05E2\u1D20\u03BD\u05D8\u1D65\u0477\u17F4\u1601\uD835\uDE6B\uD835\uDE9F\uD835\uDECE\uD835\uDF08\uD835\uDF42\uD835\uDF7C\uD835\uDFB6\uD835\uDE37\uD835\uDE03\uD835\uDCFF'],\n ['W', '\uD83C\uDD46\u13D4\u13B3\uD835\uDC7E\uA4EA\uD835\uDCB2\uD835\uDE1E\uD83C\uDD86\u24CC\uD83C\uDD66\uFF57\uFF37\u1E82\u1FA7\u15EF\u1955\u5C71\u0460\u0E9F\u0C1A\u0561\u0429\u0428\u03CE\u0449\u0E2C\u0448\u164E\u1D42\u02B7\u24B2\u0E1D\u1220\u1E84\u051C\u1E80\u0174\u1E86\u1E88\u0D27\u163A\u047F\u1661\u019C\u20A9\uD83C\uDDFC'],\n ['w', '\u1E81\uAB83\u1E83\u24E6\u2375\u0175\u1E87\u1E85\u1E98\u1E89\u2C73\u1F7C\u1F60\u1F61\u1F62\u1F63\u03C9\u1F64\u1F65\u1F66\u1F67\u1FF2\u1FF3\u1FF4\u1FF6\u1FF7\u2C72\u0461\u051D\u1D21\u1F7D\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u026F\uD835\uDF55\uD835\uDFC9\uD835\uDF8F'],\n ['X', '\uD83D\uDFA8\uD83D\uDFA9\uD83D\uDFAA\uD83C\uDD47\uD83D\uDFAB\uD83D\uDFAC\uD800\uDF17\u2CAC\uA4EB\uD835\uDD83\uD835\uDFA6\uD835\uDE1F\uD800\uDE90\uD835\uDEBE\uD835\uDF6C\uD835\uDF32\uA7B3\uD800\uDF22\uD835\uDDB7\uD835\uDC4B\uD835\uDD4F\uD835\uDD1B\uD800\uDEB4\uD835\uDDEB\uD83C\uDD87\uD83C\uDD67\u274C\u24CD\uD835\uDCE7\uFF38\u1E8A\u166D\u03C7\u3128\uD835\uDCB3\u04FE\u10EF\u04FC\u04B3\u0416\u03A7\u04B2\u1D61\u02E3\u24B3\u05D0\u1238\u1E8C\uA2BC\u2169\u0425\u2573\u166E\u1541\u157D\u2179\u16B7\u2D5D\uD835\uDE53\uD835\uDE87\u4E42\uD835\uDC17\uD83C\uDDFD'],\n ['x', '\u24E7\uFF58\u0445\u1E8B\u00D7\u2093\u292B\u292C\u2A2F\u1E8D\u1D8D\uD835\uDE6D\u04FD\uD835\uDE39\uD835\uDC31\uD835\uDEA1\u2A30\uFF92\uD835\uDD01'],\n ['Y', '\u2CA8\uD835\uDE88\uD835\uDC4C\uD835\uDDEC\uD835\uDC18\uA4EC\uD835\uDC80\uD835\uDF30\uD800\uDEB2\uD83C\uDD88\uD83C\uDD68\u24CE\uFF39\u1F5B\u01B3\u311A\u028F\u2144\u03D4\uFFE5\u00A5\u054E\u03D3\u03B3\u05E5\u04F2\u0427\u040E\u1203\u0178\u024E\u03E4\u03A5\u03D2\u04AE\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u1EF6\u1EF4\u1FE8\u1FE9\u1FEA\u1FEB\u1F59\u1F5D\u1F5F\u03AB\u038E\u04EE\u04F0\u04B0\u04B1\uD835\uDD50\uD83C\uDDFE'],\n ['y', '\uD83C\uDD48\u13BD\u13A9\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u0443\u10E7\u1E99\u1EF5\u01B4\u024F\u1D5E\u0263\u02B8\u1D8C\u04AF\u24B4\u04F3\u04F1\u04EF\u045E\u0423\u028E'],\n ['Z', '\uD83C\uDD49\uA4DC\uD835\uDDED\uD835\uDC19\u2621\u13C3\uD835\uDE21\uD83C\uDD89\uD83C\uDD69\u24CF\uFF3A\u1E94\u01B5\u4E59\u1E90\u0224\u1DBB\u24B5\u0179\u2124\u0396\u017B\u017D\u1E92\u2C6B\uD83C\uDDFF'],\n ['z', '\uAB93\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u1D22\u130A\u0290\u2C6C\u1D8E\u0291\u1646'],\n]);\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.resolveConfusablesTransformer = void 0;\nconst remap_characters_1 = require(\"../remap-characters\");\nconst confusables_1 = require(\"./confusables\");\n/**\n * Creates a transformer that maps confusable Unicode characters to their\n * normalized equivalent. For example, `\u24F5`, `\u278A`, and `\u2474` become `1` when using\n * this transformer.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied near the start of the\n * transformer chain.\n *\n * @example\n * ```typescript\n * const transformer = resolveConfusablesTransformer();\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction resolveConfusablesTransformer() {\n return (0, remap_characters_1.remapCharactersTransformer)(confusables_1.confusables);\n}\nexports.resolveConfusablesTransformer = resolveConfusablesTransformer;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.dictionary = void 0;\nexports.dictionary = new Map([\n ['a', '@4'],\n ['c', '('],\n ['e', '3'],\n ['i', '1|'],\n ['o', '0'],\n ['s', '$'],\n]);\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.resolveLeetSpeakTransformer = void 0;\nconst remap_characters_1 = require(\"../remap-characters\");\nconst dictionary_1 = require(\"./dictionary\");\n/**\n * Creates a transformer that maps leet-speak characters to their normalized\n * equivalent. For example, `$` becomes `s` when using this transformer.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied near the start of the\n * transformer chain, but after similar transformers that map characters to\n * other characters, such as the [[resolveConfusablesTransformer | transformer\n * that resolves confusable Unicode characters]].\n *\n * @example\n * ```typescript\n * const transformer = resolveLeetSpeakTransformer();\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction resolveLeetSpeakTransformer() {\n return (0, remap_characters_1.remapCharactersTransformer)(dictionary_1.dictionary);\n}\nexports.resolveLeetSpeakTransformer = resolveLeetSpeakTransformer;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.toAsciiLowerCaseTransformer = void 0;\nconst Char_1 = require(\"../../util/Char\");\nconst Transformers_1 = require(\"../Transformers\");\n/**\n * Creates a transformer that changes all ASCII alphabet characters to\n * lower-case, leaving other characters unchanged.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied near the end of the\n * transformer chain. Using it before other transformers may have the effect of\n * making its changes useless as transformers applied after produce characters\n * of varying cases.\n *\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction toAsciiLowerCaseTransformer() {\n return (0, Transformers_1.createSimpleTransformer)((c) => ((0, Char_1.isUpperCase)(c) ? (0, Char_1.invertCaseOfAlphabeticChar)(c) : c));\n}\nexports.toAsciiLowerCaseTransformer = toAsciiLowerCaseTransformer;\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.englishDataset = exports.englishRecommendedTransformers = exports.englishRecommendedWhitelistMatcherTransformers = exports.englishRecommendedBlacklistMatcherTransformers = void 0;\nconst DataSet_1 = require(\"../dataset/DataSet\");\nconst Pattern_1 = require(\"../pattern/Pattern\");\nconst collapse_duplicates_1 = require(\"../transformer/collapse-duplicates\");\nconst resolve_confusables_1 = require(\"../transformer/resolve-confusables\");\nconst resolve_leetspeak_1 = require(\"../transformer/resolve-leetspeak\");\nconst to_ascii_lowercase_1 = require(\"../transformer/to-ascii-lowercase\");\n/**\n * A set of transformers to be used when matching blacklisted patterns with the\n * [[englishDataset | english word dataset]].\n */\nexports.englishRecommendedBlacklistMatcherTransformers = [\n (0, resolve_confusables_1.resolveConfusablesTransformer)(),\n (0, resolve_leetspeak_1.resolveLeetSpeakTransformer)(),\n (0, to_ascii_lowercase_1.toAsciiLowerCaseTransformer)(),\n // See #23 and #46.\n // skipNonAlphabeticTransformer(),\n (0, collapse_duplicates_1.collapseDuplicatesTransformer)({\n defaultThreshold: 1,\n customThresholds: new Map([\n ['b', 2],\n ['e', 2],\n ['o', 2],\n ['l', 2],\n ['s', 2],\n ['g', 2], // ni_gg_er\n ]),\n }),\n];\n/**\n * A set of transformers to be used when matching whitelisted terms with the\n * [[englishDataset | english word dataset]].\n */\nexports.englishRecommendedWhitelistMatcherTransformers = [\n (0, to_ascii_lowercase_1.toAsciiLowerCaseTransformer)(),\n (0, collapse_duplicates_1.collapseDuplicatesTransformer)({\n defaultThreshold: Number.POSITIVE_INFINITY,\n customThresholds: new Map([[' ', 1]]), // collapse spaces\n }),\n];\n/**\n * Recommended transformers to be used with the [[englishDataset | english word\n * dataset]] and the [[RegExpMatcher]].\n */\nexports.englishRecommendedTransformers = {\n blacklistMatcherTransformers: exports.englishRecommendedBlacklistMatcherTransformers,\n whitelistMatcherTransformers: exports.englishRecommendedWhitelistMatcherTransformers,\n};\n/**\n * A dataset of profane English words.\n *\n * @example\n * ```typescript\n * const matcher = new RegExpMatcher({\n * \t...englishDataset.build(),\n * \t...englishRecommendedTransformers,\n * });\n * ```\n * @example\n * ```typescript\n * // Extending the data-set by adding a new word and removing an existing one.\n * const myDataset = new DataSet()\n * \t.addAll(englishDataset)\n * \t.removePhrasesIf((phrase) => phrase.metadata.originalWord === 'vagina')\n * \t.addPhrase((phrase) => phrase.addPattern(pattern`|balls|`));\n * ```\n * @copyright\n * The words are taken from the [cuss](https://github.com/words/cuss) project,\n * with some modifications.\n *\n * ```text\n * (The MIT License)\n *\n * Copyright (c) 2016 Titus Wormer \n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * 'Software'), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n * ```\n */\nexports.englishDataset = new DataSet_1.DataSet()\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'abo' }).addPattern((0, Pattern_1.pattern) `|ab[b]o[s]|`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'abeed' }).addPattern((0, Pattern_1.pattern) `ab[b]eed`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'africoon' }).addPattern((0, Pattern_1.pattern) `africoon`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'anal' })\n .addPattern((0, Pattern_1.pattern) `|anal`)\n .addWhitelistedTerm('analabos')\n .addWhitelistedTerm('analagous')\n .addWhitelistedTerm('analav')\n .addWhitelistedTerm('analy')\n .addWhitelistedTerm('analog')\n .addWhitelistedTerm('an al')\n .addPattern((0, Pattern_1.pattern) `danal`)\n .addPattern((0, Pattern_1.pattern) `eanal`)\n .addPattern((0, Pattern_1.pattern) `fanal`)\n .addWhitelistedTerm('fan al')\n .addPattern((0, Pattern_1.pattern) `ganal`)\n .addWhitelistedTerm('gan al')\n .addPattern((0, Pattern_1.pattern) `ianal`)\n .addWhitelistedTerm('ian al')\n .addPattern((0, Pattern_1.pattern) `janal`)\n .addWhitelistedTerm('trojan al')\n .addPattern((0, Pattern_1.pattern) `kanal`)\n .addPattern((0, Pattern_1.pattern) `lanal`)\n .addWhitelistedTerm('lan al')\n .addPattern((0, Pattern_1.pattern) `lanal`)\n .addWhitelistedTerm('lan al')\n .addPattern((0, Pattern_1.pattern) `oanal|`)\n .addPattern((0, Pattern_1.pattern) `panal`)\n .addWhitelistedTerm('pan al')\n .addPattern((0, Pattern_1.pattern) `qanal`)\n .addPattern((0, Pattern_1.pattern) `ranal`)\n .addPattern((0, Pattern_1.pattern) `sanal`)\n .addPattern((0, Pattern_1.pattern) `tanal`)\n .addWhitelistedTerm('tan al')\n .addPattern((0, Pattern_1.pattern) `uanal`)\n .addWhitelistedTerm('uan al')\n .addPattern((0, Pattern_1.pattern) `vanal`)\n .addWhitelistedTerm('van al')\n .addPattern((0, Pattern_1.pattern) `wanal`)\n .addPattern((0, Pattern_1.pattern) `xanal`)\n .addWhitelistedTerm('texan al')\n .addPattern((0, Pattern_1.pattern) `yanal`)\n .addPattern((0, Pattern_1.pattern) `zanal`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'anus' })\n .addPattern((0, Pattern_1.pattern) `anus`)\n .addWhitelistedTerm('an us')\n .addWhitelistedTerm('tetanus')\n .addWhitelistedTerm('uranus')\n .addWhitelistedTerm('janus')\n .addWhitelistedTerm('manus'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'arabush' }).addPattern((0, Pattern_1.pattern) `arab[b]ush`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'arse' })\n .addPattern((0, Pattern_1.pattern) `|ars[s]e`)\n .addWhitelistedTerm('arsen'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'ass' })\n .addPattern((0, Pattern_1.pattern) `|ass`)\n .addWhitelistedTerm('assa')\n .addWhitelistedTerm('assem')\n .addWhitelistedTerm('assen')\n .addWhitelistedTerm('asser')\n .addWhitelistedTerm('asset')\n .addWhitelistedTerm('assev')\n .addWhitelistedTerm('assi')\n .addWhitelistedTerm('assoc')\n .addWhitelistedTerm('assoi')\n .addWhitelistedTerm('assu'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'bastard' }).addPattern((0, Pattern_1.pattern) `bas[s]tard`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'bestiality' }).addPattern((0, Pattern_1.pattern) `be[e][a]s[s]tial`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'bitch' })\n .addPattern((0, Pattern_1.pattern) `bitch`)\n .addPattern((0, Pattern_1.pattern) `bich|`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'blowjob' }).addPattern((0, Pattern_1.pattern) `b[b]l[l][o]wj[o]b`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'bollocks' }).addPattern((0, Pattern_1.pattern) `bol[l]ock`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'boob' }).addPattern((0, Pattern_1.pattern) `boob`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'boonga' })\n .addPattern((0, Pattern_1.pattern) `boonga`)\n .addWhitelistedTerm('baboon ga'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'buttplug' }).addPattern((0, Pattern_1.pattern) `buttplug`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'chingchong' }).addPattern((0, Pattern_1.pattern) `chingchong`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'chink' })\n .addPattern((0, Pattern_1.pattern) `chink`)\n .addWhitelistedTerm('chin k'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'cock' })\n .addPattern((0, Pattern_1.pattern) `|cock|`)\n .addPattern((0, Pattern_1.pattern) `|cocks`)\n .addPattern((0, Pattern_1.pattern) `|cockp`)\n .addPattern((0, Pattern_1.pattern) `|cocke[e]|`)\n .addWhitelistedTerm('cockney'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'cuck' })\n .addPattern((0, Pattern_1.pattern) `cuck`)\n .addWhitelistedTerm('cuckoo'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'cum' })\n .addPattern((0, Pattern_1.pattern) `|cum`)\n .addWhitelistedTerm('cumu')\n .addWhitelistedTerm('cumb'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'cunt' })\n .addPattern((0, Pattern_1.pattern) `|cunt`)\n .addPattern((0, Pattern_1.pattern) `cunt|`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'deepthroat' })\n .addPattern((0, Pattern_1.pattern) `deepthro[o]at`)\n .addPattern((0, Pattern_1.pattern) `deepthro[o]t`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'dick' })\n .addPattern((0, Pattern_1.pattern) `|dck|`)\n .addPattern((0, Pattern_1.pattern) `dick`)\n .addWhitelistedTerm('benedick')\n .addWhitelistedTerm('dickens'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'dildo' }).addPattern((0, Pattern_1.pattern) `dildo`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'doggystyle' }).addPattern((0, Pattern_1.pattern) `d[o]g[g]ys[s]t[y]l[l]`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'double penetration' }).addPattern((0, Pattern_1.pattern) `double penetra`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'dyke' })\n .addPattern((0, Pattern_1.pattern) `dyke`)\n .addWhitelistedTerm('van dyke'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'ejaculate' })\n .addPattern((0, Pattern_1.pattern) `e[e]jacul`)\n .addPattern((0, Pattern_1.pattern) `e[e]jakul`)\n .addPattern((0, Pattern_1.pattern) `e[e]acul[l]ate`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'fag' })\n .addPattern((0, Pattern_1.pattern) `|fag`)\n .addPattern((0, Pattern_1.pattern) `fggot`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'felch' }).addPattern((0, Pattern_1.pattern) `fe[e]l[l]ch`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'fellatio' }).addPattern((0, Pattern_1.pattern) `f[e][e]llat`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'finger bang' }).addPattern((0, Pattern_1.pattern) `fingerbang`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'fisting' }).addPattern((0, Pattern_1.pattern) `fistin`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'fuck' })\n .addPattern((0, Pattern_1.pattern) `f[?]ck`)\n .addPattern((0, Pattern_1.pattern) `|fk`)\n .addPattern((0, Pattern_1.pattern) `|fu|`)\n .addPattern((0, Pattern_1.pattern) `|fuk`)\n .addWhitelistedTerm('fickle')\n .addWhitelistedTerm('kung-fu')\n .addWhitelistedTerm('kung fu'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'gangbang' }).addPattern((0, Pattern_1.pattern) `g[?]ngbang`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'handjob' }).addPattern((0, Pattern_1.pattern) `h[?]ndjob`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'hentai' }).addPattern((0, Pattern_1.pattern) `h[e][e]ntai`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'hooker' }).addPattern((0, Pattern_1.pattern) `hooker`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'incest' }).addPattern((0, Pattern_1.pattern) `incest`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'jerk off' }).addPattern((0, Pattern_1.pattern) `jerkoff`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'jizz' }).addPattern((0, Pattern_1.pattern) `jizz`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'kike' }).addPattern((0, Pattern_1.pattern) `kike`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'lubejob' }).addPattern((0, Pattern_1.pattern) `lubejob`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'masturbate' })\n .addPattern((0, Pattern_1.pattern) `m[?]sturbate`)\n .addPattern((0, Pattern_1.pattern) `masterbate`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'negro' })\n .addPattern((0, Pattern_1.pattern) `negro`)\n .addWhitelistedTerm('montenegro')\n .addWhitelistedTerm('negron')\n .addWhitelistedTerm('stoneground')\n .addWhitelistedTerm('winegrow'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'nigger' })\n .addPattern((0, Pattern_1.pattern) `n[i]gger`)\n .addPattern((0, Pattern_1.pattern) `n[i]gga`)\n .addPattern((0, Pattern_1.pattern) `|nig|`)\n .addPattern((0, Pattern_1.pattern) `|nigs|`)\n .addWhitelistedTerm('snigger'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'orgasm' })\n .addPattern((0, Pattern_1.pattern) `[or]gasm`)\n .addWhitelistedTerm('gasma'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'orgy' })\n .addPattern((0, Pattern_1.pattern) `orgy`)\n .addPattern((0, Pattern_1.pattern) `orgies`)\n .addWhitelistedTerm('porgy'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'penis' })\n .addPattern((0, Pattern_1.pattern) `pe[e]nis`)\n .addPattern((0, Pattern_1.pattern) `|pnis`)\n .addWhitelistedTerm('pen is'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'piss' }).addPattern((0, Pattern_1.pattern) `|piss`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'porn' })\n .addPattern((0, Pattern_1.pattern) `|prn|`)\n .addPattern((0, Pattern_1.pattern) `porn`)\n .addWhitelistedTerm('p orna'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'prick' }).addPattern((0, Pattern_1.pattern) `|prick[s]|`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'pussy' }).addPattern((0, Pattern_1.pattern) `p[u]ssy`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'rape' })\n .addPattern((0, Pattern_1.pattern) `|rape`)\n .addPattern((0, Pattern_1.pattern) `|rapis[s]t`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'retard' }).addPattern((0, Pattern_1.pattern) `retard`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'scat' }).addPattern((0, Pattern_1.pattern) `|s[s]cat|`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'semen' }).addPattern((0, Pattern_1.pattern) `|s[s]e[e]me[e]n`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'sex' })\n .addPattern((0, Pattern_1.pattern) `|s[s]e[e]x|`)\n .addPattern((0, Pattern_1.pattern) `|s[s]e[e]xy|`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'shit' })\n .addPattern((0, Pattern_1.pattern) `shit`)\n .addWhitelistedTerm('s hit')\n .addWhitelistedTerm('sh it')\n .addWhitelistedTerm('shi t')\n .addWhitelistedTerm('shitake')\n .addWhitelistedTerm('mishit'))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'slut' }).addPattern((0, Pattern_1.pattern) `s[s]lut`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'spastic' }).addPattern((0, Pattern_1.pattern) `|spastic`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'tit' })\n .addPattern((0, Pattern_1.pattern) `|tit|`)\n .addPattern((0, Pattern_1.pattern) `|tits|`)\n .addPattern((0, Pattern_1.pattern) `|titt`)\n .addPattern((0, Pattern_1.pattern) `|tiddies`)\n .addPattern((0, Pattern_1.pattern) `|tities`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'tranny' }).addPattern((0, Pattern_1.pattern) `tranny`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'turd' })\n .addPattern((0, Pattern_1.pattern) `|turd`)\n .addWhitelistedTerm('turducken'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'twat' })\n .addPattern((0, Pattern_1.pattern) `|twat`)\n .addWhitelistedTerm('twattle'))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'vagina' })\n .addPattern((0, Pattern_1.pattern) `vagina`)\n .addPattern((0, Pattern_1.pattern) `|v[?]gina`))\n .addPhrase((phrase) => phrase.setMetadata({ originalWord: 'wank' }).addPattern((0, Pattern_1.pattern) `|wank`))\n .addPhrase((phrase) => phrase\n .setMetadata({ originalWord: 'whore' })\n .addPattern((0, Pattern_1.pattern) `|wh[o]re|`)\n .addPattern((0, Pattern_1.pattern) `|who[o]res[s]|`)\n .addWhitelistedTerm(\"who're\"));\n", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.skipNonAlphabeticTransformer = void 0;\nconst Char_1 = require(\"../../util/Char\");\nconst Transformers_1 = require(\"../Transformers\");\n/**\n * Creates a transformer that skips non-alphabetic characters (`a`-`z`,\n * `A`-`Z`). This is useful when matching text on patterns that are solely\n * comprised of alphabetic characters (the pattern `hello` does not match\n * `h.e.l.l.o` by default, but does with this transformer).\n *\n * **Warning**\n *\n * This transformation is not part of the default set of transformations, as\n * there are some known rough edges with false negatives; see\n * [#23](https://github.com/jo3-l/obscenity/issues/23) and\n * [#46](https://github.com/jo3-l/obscenity/issues/46) on the GitHub issue\n * tracker.\n *\n * **Application order**\n *\n * It is recommended that this transformer be applied near the end of the\n * transformer chain, if at all.\n *\n * @example\n * ```typescript\n * const transformer = skipNonAlphabeticTransformer();\n * const matcher = new RegExpMatcher({ ..., blacklistMatcherTransformers: [transformer] });\n * ```\n * @returns A container holding the transformer, which can then be passed to the\n * [[RegExpMatcher]].\n */\nfunction skipNonAlphabeticTransformer() {\n return (0, Transformers_1.createSimpleTransformer)((c) => ((0, Char_1.isAlphabetic)(c) ? c : undefined));\n}\nexports.skipNonAlphabeticTransformer = skipNonAlphabeticTransformer;\n", "\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./censor/BuiltinStrategies\"), exports);\n__exportStar(require(\"./censor/TextCensor\"), exports);\n__exportStar(require(\"./dataset/DataSet\"), exports);\n__exportStar(require(\"./matcher/regexp/RegExpMatcher\"), exports);\n__exportStar(require(\"./matcher/BlacklistedTerm\"), exports);\n__exportStar(require(\"./matcher/MatchPayload\"), exports);\n__exportStar(require(\"./matcher/Matcher\"), exports);\n__exportStar(require(\"./pattern/Nodes\"), exports);\n__exportStar(require(\"./pattern/ParserError\"), exports);\n__exportStar(require(\"./pattern/Pattern\"), exports);\n__exportStar(require(\"./preset/english\"), exports);\n__exportStar(require(\"./transformer/collapse-duplicates\"), exports);\n__exportStar(require(\"./transformer/remap-characters\"), exports);\n__exportStar(require(\"./transformer/resolve-confusables\"), exports);\n__exportStar(require(\"./transformer/resolve-leetspeak\"), exports);\n__exportStar(require(\"./transformer/skip-non-alphabetic\"), exports);\n__exportStar(require(\"./transformer/to-ascii-lowercase\"), exports);\n", "function number(n: number) {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error(`Wrong positive integer: ${n}`);\n}\n\nfunction bool(b: boolean) {\n if (typeof b !== 'boolean') throw new Error(`Expected boolean, not ${b}`);\n}\n\nfunction bytes(b: Uint8Array | undefined, ...lengths: number[]) {\n if (!(b instanceof Uint8Array)) throw new Error('Expected Uint8Array');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);\n}\n\ntype Hash = {\n (data: Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\nfunction hash(hash: Hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('Hash should be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\n\nfunction exists(instance: any, checkFinished = true) {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\nfunction output(out: any, instance: any) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\n\nexport { number, bool, bytes, hash, exists, output };\n\nconst assert = { number, bool, bytes, hash, exists, output };\nexport default assert;\n", "// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// See utils.ts for details.\ndeclare const globalThis: Record | undefined;\nexport const crypto =\n typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\n", "/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated, we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\nconst u8a = (a: any): a is Uint8Array => a instanceof Uint8Array;\n// Cast array to different type\nexport const u8 = (arr: TypedArray) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u32 = (arr: TypedArray) =>\n new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n\n// Cast array to view\nexport const createView = (arr: TypedArray) =>\n new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n\n// The rotate right (circular right shift) operation for uint32\nexport const rotr = (word: number, shift: number) => (word << (32 - shift)) | (word >>> shift);\n\n// big-endian hardware is rare. Just in case someone still decides to run hashes:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE) throw new Error('Non little-endian hardware is not supported');\n\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n if (!u8a(bytes)) throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2) throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => {};\n\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters: number, tick: number, cb: (i: number) => void) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\nexport type Input = Uint8Array | string;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n if (!u8a(data)) throw new Error(`expected Uint8Array, got ${typeof data}`);\n return data;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a)) throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n\n// For runtime check if class implements interface\nexport abstract class Hash> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF> = Hash & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\nconst toStr = {}.toString;\ntype EmptyObj = {};\nexport function checkOpts(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && toStr.call(opts) !== '[object Object]')\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\nexport type CHash = ReturnType;\n\nexport function wrapConstructor>(hashCons: () => Hash) {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function wrapConstructorWithOpts, T extends Object>(\n hashCons: (opts?: T) => Hash\n) {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\nexport function wrapXOFConstructorWithOpts, T extends Object>(\n hashCons: (opts?: T) => HashXOF\n) {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\n/**\n * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.\n */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n", "import { exists, output } from './_assert.js';\nimport { Hash, createView, Input, toBytes } from './utils.js';\n\n// Polyfill for Safari 14\nfunction setBigUint64(view: DataView, byteOffset: number, value: bigint, isLE: boolean): void {\n if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n\n// Base SHA2 class (RFC 6234)\nexport abstract class SHA2> extends Hash {\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(\n readonly blockLen: number,\n public outputLen: number,\n readonly padOffset: number,\n readonly isLE: boolean\n ) {\n super();\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: Input): this {\n exists(this);\n const { view, buffer, blockLen } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input, cast it to view and process\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: Uint8Array) {\n exists(this);\n output(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n this.buffer.subarray(pos).fill(0);\n // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n // So we just write lowest 64 bits of that value.\n setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen should be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest() {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.length = length;\n to.pos = pos;\n to.finished = finished;\n to.destroyed = destroyed;\n if (length % blockLen) to.buffer.set(buffer);\n return to;\n }\n}\n", "import { SHA2 } from './_sha2.js';\nimport { rotr, wrapConstructor } from './utils.js';\n\n// SHA2-256 need to try 2^128 hashes to execute birthday attack.\n// BTC network is doing 2^67 hashes/sec as per early 2023.\n\n// Choice: a ? b : c\nconst Chi = (a: number, b: number, c: number) => (a & b) ^ (~a & c);\n// Majority function, true if any two inpust is true\nconst Maj = (a: number, b: number, c: number) => (a & b) ^ (a & c) ^ (b & c);\n\n// Round constants:\n// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n// prettier-ignore\nconst IV = /* @__PURE__ */new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n]);\n\n// Temporary buffer, not used to store anything between runs\n// Named this way because it matches specification.\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\nclass SHA256 extends SHA2 {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n A = IV[0] | 0;\n B = IV[1] | 0;\n C = IV[2] | 0;\n D = IV[3] | 0;\n E = IV[4] | 0;\n F = IV[5] | 0;\n G = IV[6] | 0;\n H = IV[7] | 0;\n\n constructor() {\n super(64, 32, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean() {\n SHA256_W.fill(0);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n this.buffer.fill(0);\n }\n}\n// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf\nclass SHA224 extends SHA256 {\n A = 0xc1059ed8 | 0;\n B = 0x367cd507 | 0;\n C = 0x3070dd17 | 0;\n D = 0xf70e5939 | 0;\n E = 0xffc00b31 | 0;\n F = 0x68581511 | 0;\n G = 0x64f98fa7 | 0;\n H = 0xbefa4fa4 | 0;\n constructor() {\n super();\n this.outputLen = 28;\n }\n}\n\n/**\n * SHA2-256 hash function\n * @param message - data that would be hashed\n */\nexport const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());\nexport const sha224 = /* @__PURE__ */ wrapConstructor(() => new SHA224());\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// 100 lines of code in the file are duplicated from noble-hashes (utils).\n// This is OK: `abstract` directory does not use noble-hashes.\n// User may opt-in into using different hashing library. This way, noble-hashes\n// won't be included into their bundle.\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst u8a = (a: any): a is Uint8Array => a instanceof Uint8Array;\nexport type Hex = Uint8Array | string; // hex strings are accepted for simplicity\nexport type PrivKey = Hex | bigint; // bigints are accepted to ease learning curve\nexport type CHash = {\n (message: Uint8Array | string): Uint8Array;\n blockLen: number;\n outputLen: number;\n create(opts?: { dkLen?: number }): any; // For shake\n};\nexport type FHash = (message: Uint8Array | string) => Uint8Array;\n\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n if (!u8a(bytes)) throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\nexport function numberToHexUnpadded(num: number | bigint): string {\n const hex = num.toString(16);\n return hex.length & 1 ? `0${hex}` : hex;\n}\n\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n // Big Endian\n return BigInt(hex === '' ? '0' : `0x${hex}`);\n}\n\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2) throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes: Uint8Array): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\nexport function bytesToNumberLE(bytes: Uint8Array): bigint {\n if (!u8a(bytes)) throw new Error('Uint8Array expected');\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\n\nexport function numberToBytesBE(n: number | bigint, len: number): Uint8Array {\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\nexport function numberToBytesLE(n: number | bigint, len: number): Uint8Array {\n return numberToBytesBE(n, len).reverse();\n}\n// Unpadded, rarely used\nexport function numberToVarBytesBE(n: number | bigint): Uint8Array {\n return hexToBytes(numberToHexUnpadded(n));\n}\n\n/**\n * Takes hex string or Uint8Array, converts to Uint8Array.\n * Validates output length.\n * Will throw error for other types.\n * @param title descriptive title for an error e.g. 'private key'\n * @param hex hex string or Uint8Array\n * @param expectedLength optional, will compare to result array's length\n * @returns\n */\nexport function ensureBytes(title: string, hex: Hex, expectedLength?: number): Uint8Array {\n let res: Uint8Array;\n if (typeof hex === 'string') {\n try {\n res = hexToBytes(hex);\n } catch (e) {\n throw new Error(`${title} must be valid hex string, got \"${hex}\". Cause: ${e}`);\n }\n } else if (u8a(hex)) {\n // Uint8Array.from() instead of hash.slice() because node.js Buffer\n // is instance of Uint8Array, and its slice() creates **mutable** copy\n res = Uint8Array.from(hex);\n } else {\n throw new Error(`${title} must be hex string or Uint8Array`);\n }\n const len = res.length;\n if (typeof expectedLength === 'number' && len !== expectedLength)\n throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);\n return res;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a)) throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n\nexport function equalBytes(b1: Uint8Array, b2: Uint8Array) {\n // We don't care about timing attacks here\n if (b1.length !== b2.length) return false;\n for (let i = 0; i < b1.length; i++) if (b1[i] !== b2[i]) return false;\n return true;\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n// Bit operations\n\n/**\n * Calculates amount of bits in a bigint.\n * Same as `n.toString(2).length`\n */\nexport function bitLen(n: bigint) {\n let len;\n for (len = 0; n > _0n; n >>= _1n, len += 1);\n return len;\n}\n\n/**\n * Gets single bit at position.\n * NOTE: first bit position is 0 (same as arrays)\n * Same as `!!+Array.from(n.toString(2)).reverse()[pos]`\n */\nexport function bitGet(n: bigint, pos: number) {\n return (n >> BigInt(pos)) & _1n;\n}\n\n/**\n * Sets single bit at position.\n */\nexport const bitSet = (n: bigint, pos: number, value: boolean) => {\n return n | ((value ? _1n : _0n) << BigInt(pos));\n};\n\n/**\n * Calculate mask for N bits. Not using ** operator with bigints because of old engines.\n * Same as BigInt(`0b${Array(i).fill('1').join('')}`)\n */\nexport const bitMask = (n: number) => (_2n << BigInt(n - 1)) - _1n;\n\n// DRBG\n\nconst u8n = (data?: any) => new Uint8Array(data); // creates Uint8Array\nconst u8fr = (arr: any) => Uint8Array.from(arr); // another shortcut\ntype Pred = (v: Uint8Array) => T | undefined;\n/**\n * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n * @returns function that will call DRBG until 2nd arg returns something meaningful\n * @example\n * const drbg = createHmacDRBG(32, 32, hmac);\n * drbg(seed, bytesToKey); // bytesToKey must return Key or undefined\n */\nexport function createHmacDrbg(\n hashLen: number,\n qByteLen: number,\n hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array\n): (seed: Uint8Array, predicate: Pred) => T {\n if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number');\n if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number');\n if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function');\n // Step B, Step C: set hashLen to 8*ceil(hlen/8)\n let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => {\n v.fill(1);\n k.fill(0);\n i = 0;\n };\n const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)\n const reseed = (seed = u8n()) => {\n // HMAC-DRBG reseed() function. Steps D-G\n k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0) return;\n k = h(u8fr([0x01]), seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n // HMAC-DRBG generate() function\n if (i++ >= 1000) throw new Error('drbg: tried 1000 values');\n let len = 0;\n const out: Uint8Array[] = [];\n while (len < qByteLen) {\n v = h();\n const sl = v.slice();\n out.push(sl);\n len += v.length;\n }\n return concatBytes(...out);\n };\n const genUntil = (seed: Uint8Array, pred: Pred): T => {\n reset();\n reseed(seed); // Steps D-G\n let res: T | undefined = undefined; // Step H: grind until k is in [1..n-1]\n while (!(res = pred(gen()))) reseed();\n reset();\n return res;\n };\n return genUntil;\n}\n\n// Validating curves and fields\n\nconst validatorFns = {\n bigint: (val: any) => typeof val === 'bigint',\n function: (val: any) => typeof val === 'function',\n boolean: (val: any) => typeof val === 'boolean',\n string: (val: any) => typeof val === 'string',\n stringOrUint8Array: (val: any) => typeof val === 'string' || val instanceof Uint8Array,\n isSafeInteger: (val: any) => Number.isSafeInteger(val),\n array: (val: any) => Array.isArray(val),\n field: (val: any, object: any) => (object as any).Fp.isValid(val),\n hash: (val: any) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),\n} as const;\ntype Validator = keyof typeof validatorFns;\ntype ValMap> = { [K in keyof T]?: Validator };\n// type Record = { [P in K]: T; }\n\nexport function validateObject>(\n object: T,\n validators: ValMap,\n optValidators: ValMap = {}\n) {\n const checkField = (fieldName: keyof T, type: Validator, isOptional: boolean) => {\n const checkVal = validatorFns[type];\n if (typeof checkVal !== 'function')\n throw new Error(`Invalid validator \"${type}\", expected function`);\n\n const val = object[fieldName as keyof typeof object];\n if (isOptional && val === undefined) return;\n if (!checkVal(val, object)) {\n throw new Error(\n `Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`\n );\n }\n };\n for (const [fieldName, type] of Object.entries(validators)) checkField(fieldName, type!, false);\n for (const [fieldName, type] of Object.entries(optValidators)) checkField(fieldName, type!, true);\n return object;\n}\n// validate type tests\n// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };\n// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!\n// // Should fail type-check\n// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });\n// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });\n// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });\n// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Utilities for modular arithmetics and finite fields\nimport {\n bitMask,\n numberToBytesBE,\n numberToBytesLE,\n bytesToNumberBE,\n bytesToNumberLE,\n ensureBytes,\n validateObject,\n} from './utils.js';\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);\n// prettier-ignore\nconst _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);\n// prettier-ignore\nconst _9n = BigInt(9), _16n = BigInt(16);\n\n// Calculates a modulo b\nexport function mod(a: bigint, b: bigint): bigint {\n const result = a % b;\n return result >= _0n ? result : b + result;\n}\n/**\n * Efficiently raise num to power and do modular division.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n * @example\n * pow(2n, 6n, 11n) // 64n % 11n == 9n\n */\n// TODO: use field version && remove\nexport function pow(num: bigint, power: bigint, modulo: bigint): bigint {\n if (modulo <= _0n || power < _0n) throw new Error('Expected power/modulo > 0');\n if (modulo === _1n) return _0n;\n let res = _1n;\n while (power > _0n) {\n if (power & _1n) res = (res * num) % modulo;\n num = (num * num) % modulo;\n power >>= _1n;\n }\n return res;\n}\n\n// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)\nexport function pow2(x: bigint, power: bigint, modulo: bigint): bigint {\n let res = x;\n while (power-- > _0n) {\n res *= res;\n res %= modulo;\n }\n return res;\n}\n\n// Inverses number over modulo\nexport function invert(number: bigint, modulo: bigint): bigint {\n if (number === _0n || modulo <= _0n) {\n throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);\n }\n // Euclidean GCD https://brilliant.org/wiki/extended-euclidean-algorithm/\n // Fermat's little theorem \"CT-like\" version inv(n) = n^(m-2) mod m is 30x slower.\n let a = mod(number, modulo);\n let b = modulo;\n // prettier-ignore\n let x = _0n, y = _1n, u = _1n, v = _0n;\n while (a !== _0n) {\n // JIT applies optimization if those two lines follow each other\n const q = b / a;\n const r = b % a;\n const m = x - u * q;\n const n = y - v * q;\n // prettier-ignore\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n const gcd = b;\n if (gcd !== _1n) throw new Error('invert: does not exist');\n return mod(x, modulo);\n}\n\n/**\n * Tonelli-Shanks square root search algorithm.\n * 1. https://eprint.iacr.org/2012/685.pdf (page 12)\n * 2. Square Roots from 1; 24, 51, 10 to Dan Shanks\n * Will start an infinite loop if field order P is not prime.\n * @param P field order\n * @returns function that takes field Fp (created from P) and number n\n */\nexport function tonelliShanks(P: bigint) {\n // Legendre constant: used to calculate Legendre symbol (a | p),\n // which denotes the value of a^((p-1)/2) (mod p).\n // (a | p) \u2261 1 if a is a square (mod p)\n // (a | p) \u2261 -1 if a is not a square (mod p)\n // (a | p) \u2261 0 if a \u2261 0 (mod p)\n const legendreC = (P - _1n) / _2n;\n\n let Q: bigint, S: number, Z: bigint;\n // Step 1: By factoring out powers of 2 from p - 1,\n // find q and s such that p - 1 = q*(2^s) with q odd\n for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++);\n\n // Step 2: Select a non-square z such that (z | p) \u2261 -1 and set c \u2261 zq\n for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++);\n\n // Fast-path\n if (S === 1) {\n const p1div4 = (P + _1n) / _4n;\n return function tonelliFast(Fp: IField, n: T) {\n const root = Fp.pow(n, p1div4);\n if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');\n return root;\n };\n }\n\n // Slow-path\n const Q1div2 = (Q + _1n) / _2n;\n return function tonelliSlow(Fp: IField, n: T): T {\n // Step 0: Check that n is indeed a square: (n | p) should not be \u2261 -1\n if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE)) throw new Error('Cannot find square root');\n let r = S;\n // TODO: will fail at Fp2/etc\n let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b\n let x = Fp.pow(n, Q1div2); // first guess at the square root\n let b = Fp.pow(n, Q); // first guess at the fudge factor\n\n while (!Fp.eql(b, Fp.ONE)) {\n if (Fp.eql(b, Fp.ZERO)) return Fp.ZERO; // https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm (4. If t = 0, return r = 0)\n // Find m such b^(2^m)==1\n let m = 1;\n for (let t2 = Fp.sqr(b); m < r; m++) {\n if (Fp.eql(t2, Fp.ONE)) break;\n t2 = Fp.sqr(t2); // t2 *= t2\n }\n // NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift, otherwise there will be overflow\n const ge = Fp.pow(g, _1n << BigInt(r - m - 1)); // ge = 2^(r-m-1)\n g = Fp.sqr(ge); // g = ge * ge\n x = Fp.mul(x, ge); // x *= ge\n b = Fp.mul(b, g); // b *= g\n r = m;\n }\n return x;\n };\n}\n\nexport function FpSqrt(P: bigint) {\n // NOTE: different algorithms can give different roots, it is up to user to decide which one they want.\n // For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).\n\n // P \u2261 3 (mod 4)\n // \u221An = n^((P+1)/4)\n if (P % _4n === _3n) {\n // Not all roots possible!\n // const ORDER =\n // 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;\n // const NUM = 72057594037927816n;\n const p1div4 = (P + _1n) / _4n;\n return function sqrt3mod4(Fp: IField, n: T) {\n const root = Fp.pow(n, p1div4);\n // Throw if root**2 != n\n if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');\n return root;\n };\n }\n\n // Atkin algorithm for q \u2261 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)\n if (P % _8n === _5n) {\n const c1 = (P - _5n) / _8n;\n return function sqrt5mod8(Fp: IField, n: T) {\n const n2 = Fp.mul(n, _2n);\n const v = Fp.pow(n2, c1);\n const nv = Fp.mul(n, v);\n const i = Fp.mul(Fp.mul(nv, _2n), v);\n const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));\n if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');\n return root;\n };\n }\n\n // P \u2261 9 (mod 16)\n if (P % _16n === _9n) {\n // NOTE: tonelli is too slow for bls-Fp2 calculations even on start\n // Means we cannot use sqrt for constants at all!\n //\n // const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F\n // const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F\n // const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F\n // const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic\n // sqrt = (x) => {\n // let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4\n // let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1\n // const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1\n // let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1\n // const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x\n // const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x\n // tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x\n // tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x\n // const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x\n // return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2\n // }\n }\n\n // Other cases: Tonelli-Shanks algorithm\n return tonelliShanks(P);\n}\n\n// Little-endian check for first LE bit (last BE bit);\nexport const isNegativeLE = (num: bigint, modulo: bigint) => (mod(num, modulo) & _1n) === _1n;\n\n// Field is not always over prime: for example, Fp2 has ORDER(q)=p^m\nexport interface IField {\n ORDER: bigint;\n BYTES: number;\n BITS: number;\n MASK: bigint;\n ZERO: T;\n ONE: T;\n // 1-arg\n create: (num: T) => T;\n isValid: (num: T) => boolean;\n is0: (num: T) => boolean;\n neg(num: T): T;\n inv(num: T): T;\n sqrt(num: T): T;\n sqr(num: T): T;\n // 2-args\n eql(lhs: T, rhs: T): boolean;\n add(lhs: T, rhs: T): T;\n sub(lhs: T, rhs: T): T;\n mul(lhs: T, rhs: T | bigint): T;\n pow(lhs: T, power: bigint): T;\n div(lhs: T, rhs: T | bigint): T;\n // N for NonNormalized (for now)\n addN(lhs: T, rhs: T): T;\n subN(lhs: T, rhs: T): T;\n mulN(lhs: T, rhs: T | bigint): T;\n sqrN(num: T): T;\n\n // Optional\n // Should be same as sgn0 function in\n // [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#section-4.1).\n // NOTE: sgn0 is 'negative in LE', which is same as odd. And negative in LE is kinda strange definition anyway.\n isOdd?(num: T): boolean; // Odd instead of even since we have it for Fp2\n // legendre?(num: T): T;\n pow(lhs: T, power: bigint): T;\n invertBatch: (lst: T[]) => T[];\n toBytes(num: T): Uint8Array;\n fromBytes(bytes: Uint8Array): T;\n // If c is False, CMOV returns a, otherwise it returns b.\n cmov(a: T, b: T, c: boolean): T;\n}\n// prettier-ignore\nconst FIELD_FIELDS = [\n 'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',\n 'eql', 'add', 'sub', 'mul', 'pow', 'div',\n 'addN', 'subN', 'mulN', 'sqrN'\n] as const;\nexport function validateField(field: IField) {\n const initial = {\n ORDER: 'bigint',\n MASK: 'bigint',\n BYTES: 'isSafeInteger',\n BITS: 'isSafeInteger',\n } as Record;\n const opts = FIELD_FIELDS.reduce((map, val: string) => {\n map[val] = 'function';\n return map;\n }, initial);\n return validateObject(field, opts);\n}\n\n// Generic field functions\n\n/**\n * Same as `pow` but for Fp: non-constant-time.\n * Unsafe in some contexts: uses ladder, so can expose bigint bits.\n */\nexport function FpPow(f: IField, num: T, power: bigint): T {\n // Should have same speed as pow for bigints\n // TODO: benchmark!\n if (power < _0n) throw new Error('Expected power > 0');\n if (power === _0n) return f.ONE;\n if (power === _1n) return num;\n let p = f.ONE;\n let d = num;\n while (power > _0n) {\n if (power & _1n) p = f.mul(p, d);\n d = f.sqr(d);\n power >>= _1n;\n }\n return p;\n}\n\n/**\n * Efficiently invert an array of Field elements.\n * `inv(0)` will return `undefined` here: make sure to throw an error.\n */\nexport function FpInvertBatch(f: IField, nums: T[]): T[] {\n const tmp = new Array(nums.length);\n // Walk from first to last, multiply them by each other MOD p\n const lastMultiplied = nums.reduce((acc, num, i) => {\n if (f.is0(num)) return acc;\n tmp[i] = acc;\n return f.mul(acc, num);\n }, f.ONE);\n // Invert last element\n const inverted = f.inv(lastMultiplied);\n // Walk from last to first, multiply them by inverted each other MOD p\n nums.reduceRight((acc, num, i) => {\n if (f.is0(num)) return acc;\n tmp[i] = f.mul(acc, tmp[i]);\n return f.mul(acc, num);\n }, inverted);\n return tmp;\n}\n\nexport function FpDiv(f: IField, lhs: T, rhs: T | bigint): T {\n return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.inv(rhs));\n}\n\n// This function returns True whenever the value x is a square in the field F.\nexport function FpIsSquare(f: IField) {\n const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic\n return (x: T): boolean => {\n const p = f.pow(x, legendreConst);\n return f.eql(p, f.ZERO) || f.eql(p, f.ONE);\n };\n}\n\n// CURVE.n lengths\nexport function nLength(n: bigint, nBitLength?: number) {\n // Bit size, byte size of CURVE.n\n const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;\n const nByteLength = Math.ceil(_nBitLength / 8);\n return { nBitLength: _nBitLength, nByteLength };\n}\n\ntype FpField = IField & Required, 'isOdd'>>;\n/**\n * Initializes a finite field over prime. **Non-primes are not supported.**\n * Do not init in loop: slow. Very fragile: always run a benchmark on a change.\n * Major performance optimizations:\n * * a) denormalized operations like mulN instead of mul\n * * b) same object shape: never add or remove keys\n * * c) Object.freeze\n * @param ORDER prime positive bigint\n * @param bitLen how many bits the field consumes\n * @param isLE (def: false) if encoding / decoding should be in little-endian\n * @param redef optional faster redefinitions of sqrt and other methods\n */\nexport function Field(\n ORDER: bigint,\n bitLen?: number,\n isLE = false,\n redef: Partial> = {}\n): Readonly {\n if (ORDER <= _0n) throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);\n const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);\n if (BYTES > 2048) throw new Error('Field lengths over 2048 bytes are not supported');\n const sqrtP = FpSqrt(ORDER);\n const f: Readonly = Object.freeze({\n ORDER,\n BITS,\n BYTES,\n MASK: bitMask(BITS),\n ZERO: _0n,\n ONE: _1n,\n create: (num) => mod(num, ORDER),\n isValid: (num) => {\n if (typeof num !== 'bigint')\n throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);\n return _0n <= num && num < ORDER; // 0 is valid element, but it's not invertible\n },\n is0: (num) => num === _0n,\n isOdd: (num) => (num & _1n) === _1n,\n neg: (num) => mod(-num, ORDER),\n eql: (lhs, rhs) => lhs === rhs,\n\n sqr: (num) => mod(num * num, ORDER),\n add: (lhs, rhs) => mod(lhs + rhs, ORDER),\n sub: (lhs, rhs) => mod(lhs - rhs, ORDER),\n mul: (lhs, rhs) => mod(lhs * rhs, ORDER),\n pow: (num, power) => FpPow(f, num, power),\n div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),\n\n // Same as above, but doesn't normalize\n sqrN: (num) => num * num,\n addN: (lhs, rhs) => lhs + rhs,\n subN: (lhs, rhs) => lhs - rhs,\n mulN: (lhs, rhs) => lhs * rhs,\n\n inv: (num) => invert(num, ORDER),\n sqrt: redef.sqrt || ((n) => sqrtP(f, n)),\n invertBatch: (lst) => FpInvertBatch(f, lst),\n // TODO: do we really need constant cmov?\n // We don't have const-time bigints anyway, so probably will be not very useful\n cmov: (a, b, c) => (c ? b : a),\n toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),\n fromBytes: (bytes) => {\n if (bytes.length !== BYTES)\n throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);\n return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);\n },\n } as FpField);\n return Object.freeze(f);\n}\n\nexport function FpSqrtOdd(Fp: IField, elm: T) {\n if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);\n const root = Fp.sqrt(elm);\n return Fp.isOdd(root) ? root : Fp.neg(root);\n}\n\nexport function FpSqrtEven(Fp: IField, elm: T) {\n if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);\n const root = Fp.sqrt(elm);\n return Fp.isOdd(root) ? Fp.neg(root) : root;\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Same as mapKeyToField, but accepts less bytes (40 instead of 48 for 32-byte field).\n * Which makes it slightly more biased, less secure.\n * @deprecated use mapKeyToField instead\n */\nexport function hashToPrivateScalar(\n hash: string | Uint8Array,\n groupOrder: bigint,\n isLE = false\n): bigint {\n hash = ensureBytes('privateHash', hash);\n const hashLen = hash.length;\n const minLen = nLength(groupOrder).nByteLength + 8;\n if (minLen < 24 || hashLen < minLen || hashLen > 1024)\n throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);\n const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);\n return mod(num, groupOrder - _1n) + _1n;\n}\n\n/**\n * Returns total number of bytes consumed by the field element.\n * For example, 32 bytes for usual 256-bit weierstrass curve.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of field\n */\nexport function getFieldBytesLength(fieldOrder: bigint): number {\n if (typeof fieldOrder !== 'bigint') throw new Error('field order must be bigint');\n const bitLength = fieldOrder.toString(2).length;\n return Math.ceil(bitLength / 8);\n}\n\n/**\n * Returns minimal amount of bytes that can be safely reduced\n * by field order.\n * Should be 2^-128 for 128-bit curve such as P256.\n * @param fieldOrder number of field elements, usually CURVE.n\n * @returns byte length of target hash\n */\nexport function getMinHashLength(fieldOrder: bigint): number {\n const length = getFieldBytesLength(fieldOrder);\n return length + Math.ceil(length / 2);\n}\n\n/**\n * \"Constant-time\" private key generation utility.\n * Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF\n * and convert them into private scalar, with the modulo bias being negligible.\n * Needs at least 48 bytes of input for 32-byte private key.\n * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/\n * FIPS 186-5, A.2 https://csrc.nist.gov/publications/detail/fips/186/5/final\n * RFC 9380, https://www.rfc-editor.org/rfc/rfc9380#section-5\n * @param hash hash output from SHA3 or a similar function\n * @param groupOrder size of subgroup - (e.g. secp256k1.CURVE.n)\n * @param isLE interpret hash bytes as LE num\n * @returns valid private scalar\n */\nexport function mapHashToField(key: Uint8Array, fieldOrder: bigint, isLE = false): Uint8Array {\n const len = key.length;\n const fieldLen = getFieldBytesLength(fieldOrder);\n const minLen = getMinHashLength(fieldOrder);\n // No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.\n if (len < 16 || len < minLen || len > 1024)\n throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);\n const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE(key);\n // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0\n const reduced = mod(num, fieldOrder - _1n) + _1n;\n return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);\n}\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Abelian group utilities\nimport { IField, validateField, nLength } from './modular.js';\nimport { validateObject } from './utils.js';\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\n\nexport type AffinePoint = {\n x: T;\n y: T;\n} & { z?: never; t?: never };\n\nexport interface Group> {\n double(): T;\n negate(): T;\n add(other: T): T;\n subtract(other: T): T;\n equals(other: T): boolean;\n multiply(scalar: bigint): T;\n}\n\nexport type GroupConstructor = {\n BASE: T;\n ZERO: T;\n};\nexport type Mapper = (i: T[]) => T[];\n\n// Elliptic curve multiplication of Point by scalar. Fragile.\n// Scalars should always be less than curve order: this should be checked inside of a curve itself.\n// Creates precomputation tables for fast multiplication:\n// - private scalar is split by fixed size windows of W bits\n// - every window point is collected from window's table & added to accumulator\n// - since windows are different, same point inside tables won't be accessed more than once per calc\n// - each multiplication is 'Math.ceil(CURVE_ORDER / \uD835\uDC4A) + 1' point additions (fixed for any scalar)\n// - +1 window is neccessary for wNAF\n// - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication\n// TODO: Research returning 2d JS array of windows, instead of a single window. This would allow\n// windows to be in different memory locations\nexport function wNAF>(c: GroupConstructor, bits: number) {\n const constTimeNegate = (condition: boolean, item: T): T => {\n const neg = item.negate();\n return condition ? neg : item;\n };\n const opts = (W: number) => {\n const windows = Math.ceil(bits / W) + 1; // +1, because\n const windowSize = 2 ** (W - 1); // -1 because we skip zero\n return { windows, windowSize };\n };\n return {\n constTimeNegate,\n // non-const time multiplication ladder\n unsafeLadder(elm: T, n: bigint) {\n let p = c.ZERO;\n let d: T = elm;\n while (n > _0n) {\n if (n & _1n) p = p.add(d);\n d = d.double();\n n >>= _1n;\n }\n return p;\n },\n\n /**\n * Creates a wNAF precomputation window. Used for caching.\n * Default window size is set by `utils.precompute()` and is equal to 8.\n * Number of precomputed points depends on the curve size:\n * 2^(\uD835\uDC4A\u22121) * (Math.ceil(\uD835\uDC5B / \uD835\uDC4A) + 1), where:\n * - \uD835\uDC4A is the window size\n * - \uD835\uDC5B is the bitlength of the curve order.\n * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.\n * @returns precomputed point tables flattened to a single array\n */\n precomputeWindow(elm: T, W: number): Group[] {\n const { windows, windowSize } = opts(W);\n const points: T[] = [];\n let p: T = elm;\n let base = p;\n for (let window = 0; window < windows; window++) {\n base = p;\n points.push(base);\n // =1, because we skip zero\n for (let i = 1; i < windowSize; i++) {\n base = base.add(p);\n points.push(base);\n }\n p = base.double();\n }\n return points;\n },\n\n /**\n * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.\n * @param W window size\n * @param precomputes precomputed tables\n * @param n scalar (we don't check here, but should be less than curve order)\n * @returns real and fake (for const-time) points\n */\n wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T } {\n // TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise\n // But need to carefully remove other checks before wNAF. ORDER == bits here\n const { windows, windowSize } = opts(W);\n\n let p = c.ZERO;\n let f = c.BASE;\n\n const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.\n const maxNumber = 2 ** W;\n const shiftBy = BigInt(W);\n\n for (let window = 0; window < windows; window++) {\n const offset = window * windowSize;\n // Extract W bits.\n let wbits = Number(n & mask);\n\n // Shift number by W bits.\n n >>= shiftBy;\n\n // If the bits are bigger than max size, we'll split those.\n // +224 => 256 - 32\n if (wbits > windowSize) {\n wbits -= maxNumber;\n n += _1n;\n }\n\n // This code was first written with assumption that 'f' and 'p' will never be infinity point:\n // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,\n // there is negate now: it is possible that negated element from low value\n // would be the same as high element, which will create carry into next window.\n // It's not obvious how this can fail, but still worth investigating later.\n\n // Check if we're onto Zero point.\n // Add random point inside current window to f.\n const offset1 = offset;\n const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero\n const cond1 = window % 2 !== 0;\n const cond2 = wbits < 0;\n if (wbits === 0) {\n // The most important part for const-time getPublicKey\n f = f.add(constTimeNegate(cond1, precomputes[offset1]));\n } else {\n p = p.add(constTimeNegate(cond2, precomputes[offset2]));\n }\n }\n // JIT-compiler should not eliminate f here, since it will later be used in normalizeZ()\n // Even if the variable is still unused, there are some checks which will\n // throw an exception, so compiler needs to prove they won't happen, which is hard.\n // At this point there is a way to F be infinity-point even if p is not,\n // which makes it less const-time: around 1 bigint multiply.\n return { p, f };\n },\n\n wNAFCached(P: T, precomputesMap: Map, n: bigint, transform: Mapper): { p: T; f: T } {\n // @ts-ignore\n const W: number = P._WINDOW_SIZE || 1;\n // Calculate precomputes on a first run, reuse them after\n let comp = precomputesMap.get(P);\n if (!comp) {\n comp = this.precomputeWindow(P, W) as T[];\n if (W !== 1) {\n precomputesMap.set(P, transform(comp));\n }\n }\n return this.wNAF(W, comp, n);\n },\n };\n}\n\n// Generic BasicCurve interface: works even for polynomial fields (BLS): P, n, h would be ok.\n// Though generator can be different (Fp2 / Fp6 for BLS).\nexport type BasicCurve = {\n Fp: IField; // Field over which we'll do calculations (Fp)\n n: bigint; // Curve order, total count of valid points in the field\n nBitLength?: number; // bit length of curve order\n nByteLength?: number; // byte length of curve order\n h: bigint; // cofactor. we can assign default=1, but users will just ignore it w/o validation\n hEff?: bigint; // Number to multiply to clear cofactor\n Gx: T; // base point X coordinate\n Gy: T; // base point Y coordinate\n allowInfinityPoint?: boolean; // bls12-381 requires it. ZERO point is valid, but invalid pubkey\n};\n\nexport function validateBasic(curve: BasicCurve & T) {\n validateField(curve.Fp);\n validateObject(\n curve,\n {\n n: 'bigint',\n h: 'bigint',\n Gx: 'field',\n Gy: 'field',\n },\n {\n nBitLength: 'isSafeInteger',\n nByteLength: 'isSafeInteger',\n }\n );\n // Set defaults\n return Object.freeze({\n ...nLength(curve.n, curve.nBitLength),\n ...curve,\n ...{ p: curve.Fp.ORDER },\n } as const);\n}\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// Short Weierstrass curve. The formula is: y\u00B2 = x\u00B3 + ax + b\nimport * as mod from './modular.js';\nimport * as ut from './utils.js';\nimport { CHash, Hex, PrivKey, ensureBytes } from './utils.js';\nimport { Group, GroupConstructor, wNAF, BasicCurve, validateBasic, AffinePoint } from './curve.js';\n\nexport type { AffinePoint };\ntype HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;\ntype EndomorphismOpts = {\n beta: bigint;\n splitScalar: (k: bigint) => { k1neg: boolean; k1: bigint; k2neg: boolean; k2: bigint };\n};\nexport type BasicWCurve = BasicCurve & {\n // Params: a, b\n a: T;\n b: T;\n\n // Optional params\n allowedPrivateKeyLengths?: readonly number[]; // for P521\n wrapPrivateKey?: boolean; // bls12-381 requires mod(n) instead of rejecting keys >= n\n endo?: EndomorphismOpts; // Endomorphism options for Koblitz curves\n // When a cofactor != 1, there can be an effective methods to:\n // 1. Determine whether a point is torsion-free\n isTorsionFree?: (c: ProjConstructor, point: ProjPointType) => boolean;\n // 2. Clear torsion component\n clearCofactor?: (c: ProjConstructor, point: ProjPointType) => ProjPointType;\n};\n\ntype Entropy = Hex | true;\nexport type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };\nexport type VerOpts = { lowS?: boolean; prehash?: boolean };\n\n/**\n * ### Design rationale for types\n *\n * * Interaction between classes from different curves should fail:\n * `k256.Point.BASE.add(p256.Point.BASE)`\n * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime\n * * Different calls of `curve()` would return different classes -\n * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,\n * it won't affect others\n *\n * TypeScript can't infer types for classes created inside a function. Classes is one instance of nominative types in TypeScript and interfaces only check for shape, so it's hard to create unique type for every function call.\n *\n * We can use generic types via some param, like curve opts, but that would:\n * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)\n * which is hard to debug.\n * 2. Params can be generic and we can't enforce them to be constant value:\n * if somebody creates curve from non-constant params,\n * it would be allowed to interact with other curves with non-constant params\n *\n * TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol\n */\n\n// Instance for 3d XYZ points\nexport interface ProjPointType extends Group> {\n readonly px: T;\n readonly py: T;\n readonly pz: T;\n get x(): T;\n get y(): T;\n multiply(scalar: bigint): ProjPointType;\n toAffine(iz?: T): AffinePoint;\n isTorsionFree(): boolean;\n clearCofactor(): ProjPointType;\n assertValidity(): void;\n hasEvenY(): boolean;\n toRawBytes(isCompressed?: boolean): Uint8Array;\n toHex(isCompressed?: boolean): string;\n\n multiplyUnsafe(scalar: bigint): ProjPointType;\n multiplyAndAddUnsafe(Q: ProjPointType, a: bigint, b: bigint): ProjPointType | undefined;\n _setWindowSize(windowSize: number): void;\n}\n// Static methods for 3d XYZ points\nexport interface ProjConstructor extends GroupConstructor> {\n new (x: T, y: T, z: T): ProjPointType;\n fromAffine(p: AffinePoint): ProjPointType;\n fromHex(hex: Hex): ProjPointType;\n fromPrivateKey(privateKey: PrivKey): ProjPointType;\n normalizeZ(points: ProjPointType[]): ProjPointType[];\n}\n\nexport type CurvePointsType = BasicWCurve & {\n // Bytes\n fromBytes?: (bytes: Uint8Array) => AffinePoint;\n toBytes?: (c: ProjConstructor, point: ProjPointType, isCompressed: boolean) => Uint8Array;\n};\n\nfunction validatePointOpts(curve: CurvePointsType) {\n const opts = validateBasic(curve);\n ut.validateObject(\n opts,\n {\n a: 'field',\n b: 'field',\n },\n {\n allowedPrivateKeyLengths: 'array',\n wrapPrivateKey: 'boolean',\n isTorsionFree: 'function',\n clearCofactor: 'function',\n allowInfinityPoint: 'boolean',\n fromBytes: 'function',\n toBytes: 'function',\n }\n );\n const { endo, Fp, a } = opts;\n if (endo) {\n if (!Fp.eql(a, Fp.ZERO)) {\n throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');\n }\n if (\n typeof endo !== 'object' ||\n typeof endo.beta !== 'bigint' ||\n typeof endo.splitScalar !== 'function'\n ) {\n throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');\n }\n }\n return Object.freeze({ ...opts } as const);\n}\n\nexport type CurvePointsRes = {\n ProjectivePoint: ProjConstructor;\n normPrivateKeyToScalar: (key: PrivKey) => bigint;\n weierstrassEquation: (x: T) => T;\n isWithinCurveOrder: (num: bigint) => boolean;\n};\n\n// ASN.1 DER encoding utilities\nconst { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;\nexport const DER = {\n // asn.1 DER encoding utils\n Err: class DERErr extends Error {\n constructor(m = '') {\n super(m);\n }\n },\n _parseInt(data: Uint8Array): { d: bigint; l: Uint8Array } {\n const { Err: E } = DER;\n if (data.length < 2 || data[0] !== 0x02) throw new E('Invalid signature integer tag');\n const len = data[1];\n const res = data.subarray(2, len + 2);\n if (!len || res.length !== len) throw new E('Invalid signature integer: wrong length');\n // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,\n // since we always use positive integers here. It must always be empty:\n // - add zero byte if exists\n // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)\n if (res[0] & 0b10000000) throw new E('Invalid signature integer: negative');\n if (res[0] === 0x00 && !(res[1] & 0b10000000))\n throw new E('Invalid signature integer: unnecessary leading zero');\n return { d: b2n(res), l: data.subarray(len + 2) }; // d is data, l is left\n },\n toSig(hex: string | Uint8Array): { r: bigint; s: bigint } {\n // parse DER signature\n const { Err: E } = DER;\n const data = typeof hex === 'string' ? h2b(hex) : hex;\n if (!(data instanceof Uint8Array)) throw new Error('ui8a expected');\n let l = data.length;\n if (l < 2 || data[0] != 0x30) throw new E('Invalid signature tag');\n if (data[1] !== l - 2) throw new E('Invalid signature: incorrect length');\n const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));\n const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);\n if (rBytesLeft.length) throw new E('Invalid signature: left bytes after parsing');\n return { r, s };\n },\n hexFromSig(sig: { r: bigint; s: bigint }): string {\n // Add leading zero if first byte has negative bit enabled. More details in '_parseInt'\n const slice = (s: string): string => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);\n const h = (num: number | bigint) => {\n const hex = num.toString(16);\n return hex.length & 1 ? `0${hex}` : hex;\n };\n const s = slice(h(sig.s));\n const r = slice(h(sig.r));\n const shl = s.length / 2;\n const rhl = r.length / 2;\n const sl = h(shl);\n const rl = h(rhl);\n return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;\n },\n};\n\n// Be friendly to bad ECMAScript parsers by not using bigint literals\n// prettier-ignore\nconst _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);\n\nexport function weierstrassPoints(opts: CurvePointsType) {\n const CURVE = validatePointOpts(opts);\n const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ\n\n const toBytes =\n CURVE.toBytes ||\n ((_c: ProjConstructor, point: ProjPointType, _isCompressed: boolean) => {\n const a = point.toAffine();\n return ut.concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));\n });\n const fromBytes =\n CURVE.fromBytes ||\n ((bytes: Uint8Array) => {\n // const head = bytes[0];\n const tail = bytes.subarray(1);\n // if (head !== 0x04) throw new Error('Only non-compressed encoding is supported');\n const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));\n const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));\n return { x, y };\n });\n\n /**\n * y\u00B2 = x\u00B3 + ax + b: Short weierstrass curve formula\n * @returns y\u00B2\n */\n function weierstrassEquation(x: T): T {\n const { a, b } = CURVE;\n const x2 = Fp.sqr(x); // x * x\n const x3 = Fp.mul(x2, x); // x2 * x\n return Fp.add(Fp.add(x3, Fp.mul(x, a)), b); // x3 + a * x + b\n }\n // Validate whether the passed curve params are valid.\n // We check if curve equation works for generator point.\n // `assertValidity()` won't work: `isTorsionFree()` is not available at this point in bls12-381.\n // ProjectivePoint class has not been initialized yet.\n if (!Fp.eql(Fp.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx)))\n throw new Error('bad generator point: equation left != right');\n\n // Valid group elements reside in range 1..n-1\n function isWithinCurveOrder(num: bigint): boolean {\n return typeof num === 'bigint' && _0n < num && num < CURVE.n;\n }\n function assertGE(num: bigint) {\n if (!isWithinCurveOrder(num)) throw new Error('Expected valid bigint: 0 < bigint < curve.n');\n }\n // Validates if priv key is valid and converts it to bigint.\n // Supports options allowedPrivateKeyLengths and wrapPrivateKey.\n function normPrivateKeyToScalar(key: PrivKey): bigint {\n const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;\n if (lengths && typeof key !== 'bigint') {\n if (key instanceof Uint8Array) key = ut.bytesToHex(key);\n // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes\n if (typeof key !== 'string' || !lengths.includes(key.length)) throw new Error('Invalid key');\n key = key.padStart(nByteLength * 2, '0');\n }\n let num: bigint;\n try {\n num =\n typeof key === 'bigint'\n ? key\n : ut.bytesToNumberBE(ensureBytes('private key', key, nByteLength));\n } catch (error) {\n throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);\n }\n if (wrapPrivateKey) num = mod.mod(num, n); // disabled by default, enabled for BLS\n assertGE(num); // num in range [1..N-1]\n return num;\n }\n\n const pointPrecomputes = new Map();\n function assertPrjPoint(other: unknown) {\n if (!(other instanceof Point)) throw new Error('ProjectivePoint expected');\n }\n /**\n * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) \u220B (x=x/z, y=y/z)\n * Default Point works in 2d / affine coordinates: (x, y)\n * We're doing calculations in projective, because its operations don't require costly inversion.\n */\n class Point implements ProjPointType {\n static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);\n static readonly ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);\n\n constructor(readonly px: T, readonly py: T, readonly pz: T) {\n if (px == null || !Fp.isValid(px)) throw new Error('x required');\n if (py == null || !Fp.isValid(py)) throw new Error('y required');\n if (pz == null || !Fp.isValid(pz)) throw new Error('z required');\n }\n\n // Does not validate if the point is on-curve.\n // Use fromHex instead, or call assertValidity() later.\n static fromAffine(p: AffinePoint): Point {\n const { x, y } = p || {};\n if (!p || !Fp.isValid(x) || !Fp.isValid(y)) throw new Error('invalid affine point');\n if (p instanceof Point) throw new Error('projective point not allowed');\n const is0 = (i: T) => Fp.eql(i, Fp.ZERO);\n // fromAffine(x:0, y:0) would produce (x:0, y:0, z:1), but we need (x:0, y:1, z:0)\n if (is0(x) && is0(y)) return Point.ZERO;\n return new Point(x, y, Fp.ONE);\n }\n\n get x(): T {\n return this.toAffine().x;\n }\n get y(): T {\n return this.toAffine().y;\n }\n\n /**\n * Takes a bunch of Projective Points but executes only one\n * inversion on all of them. Inversion is very slow operation,\n * so this improves performance massively.\n * Optimization: converts a list of projective points to a list of identical points with Z=1.\n */\n static normalizeZ(points: Point[]): Point[] {\n const toInv = Fp.invertBatch(points.map((p) => p.pz));\n return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);\n }\n\n /**\n * Converts hash string or Uint8Array to Point.\n * @param hex short/long ECDSA hex\n */\n static fromHex(hex: Hex): Point {\n const P = Point.fromAffine(fromBytes(ensureBytes('pointHex', hex)));\n P.assertValidity();\n return P;\n }\n\n // Multiplies generator point by privateKey.\n static fromPrivateKey(privateKey: PrivKey) {\n return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));\n }\n\n // We calculate precomputes for elliptic curve point multiplication\n // using windowed method. This specifies window size and\n // stores precomputed values. Usually only base point would be precomputed.\n _WINDOW_SIZE?: number;\n\n // \"Private method\", don't use it directly\n _setWindowSize(windowSize: number) {\n this._WINDOW_SIZE = windowSize;\n pointPrecomputes.delete(this);\n }\n\n // A point on curve is valid if it conforms to equation.\n assertValidity(): void {\n if (this.is0()) {\n // (0, 1, 0) aka ZERO is invalid in most contexts.\n // In BLS, ZERO can be serialized, so we allow it.\n // (0, 0, 0) is wrong representation of ZERO and is always invalid.\n if (CURVE.allowInfinityPoint && !Fp.is0(this.py)) return;\n throw new Error('bad point: ZERO');\n }\n // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`\n const { x, y } = this.toAffine();\n // Check if x, y are valid field elements\n if (!Fp.isValid(x) || !Fp.isValid(y)) throw new Error('bad point: x or y not FE');\n const left = Fp.sqr(y); // y\u00B2\n const right = weierstrassEquation(x); // x\u00B3 + ax + b\n if (!Fp.eql(left, right)) throw new Error('bad point: equation left != right');\n if (!this.isTorsionFree()) throw new Error('bad point: not in prime-order subgroup');\n }\n hasEvenY(): boolean {\n const { y } = this.toAffine();\n if (Fp.isOdd) return !Fp.isOdd(y);\n throw new Error(\"Field doesn't support isOdd\");\n }\n\n /**\n * Compare one point to another.\n */\n equals(other: Point): boolean {\n assertPrjPoint(other);\n const { px: X1, py: Y1, pz: Z1 } = this;\n const { px: X2, py: Y2, pz: Z2 } = other;\n const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));\n const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));\n return U1 && U2;\n }\n\n /**\n * Flips point to one corresponding to (x, -y) in Affine coordinates.\n */\n negate(): Point {\n return new Point(this.px, Fp.neg(this.py), this.pz);\n }\n\n // Renes-Costello-Batina exception-free doubling formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 3\n // Cost: 8M + 3S + 3*a + 2*b3 + 15add.\n double() {\n const { a, b } = CURVE;\n const b3 = Fp.mul(b, _3n);\n const { px: X1, py: Y1, pz: Z1 } = this;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n let t0 = Fp.mul(X1, X1); // step 1\n let t1 = Fp.mul(Y1, Y1);\n let t2 = Fp.mul(Z1, Z1);\n let t3 = Fp.mul(X1, Y1);\n t3 = Fp.add(t3, t3); // step 5\n Z3 = Fp.mul(X1, Z1);\n Z3 = Fp.add(Z3, Z3);\n X3 = Fp.mul(a, Z3);\n Y3 = Fp.mul(b3, t2);\n Y3 = Fp.add(X3, Y3); // step 10\n X3 = Fp.sub(t1, Y3);\n Y3 = Fp.add(t1, Y3);\n Y3 = Fp.mul(X3, Y3);\n X3 = Fp.mul(t3, X3);\n Z3 = Fp.mul(b3, Z3); // step 15\n t2 = Fp.mul(a, t2);\n t3 = Fp.sub(t0, t2);\n t3 = Fp.mul(a, t3);\n t3 = Fp.add(t3, Z3);\n Z3 = Fp.add(t0, t0); // step 20\n t0 = Fp.add(Z3, t0);\n t0 = Fp.add(t0, t2);\n t0 = Fp.mul(t0, t3);\n Y3 = Fp.add(Y3, t0);\n t2 = Fp.mul(Y1, Z1); // step 25\n t2 = Fp.add(t2, t2);\n t0 = Fp.mul(t2, t3);\n X3 = Fp.sub(X3, t0);\n Z3 = Fp.mul(t2, t1);\n Z3 = Fp.add(Z3, Z3); // step 30\n Z3 = Fp.add(Z3, Z3);\n return new Point(X3, Y3, Z3);\n }\n\n // Renes-Costello-Batina exception-free addition formula.\n // There is 30% faster Jacobian formula, but it is not complete.\n // https://eprint.iacr.org/2015/1060, algorithm 1\n // Cost: 12M + 0S + 3*a + 3*b3 + 23add.\n add(other: Point): Point {\n assertPrjPoint(other);\n const { px: X1, py: Y1, pz: Z1 } = this;\n const { px: X2, py: Y2, pz: Z2 } = other;\n let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore\n const a = CURVE.a;\n const b3 = Fp.mul(CURVE.b, _3n);\n let t0 = Fp.mul(X1, X2); // step 1\n let t1 = Fp.mul(Y1, Y2);\n let t2 = Fp.mul(Z1, Z2);\n let t3 = Fp.add(X1, Y1);\n let t4 = Fp.add(X2, Y2); // step 5\n t3 = Fp.mul(t3, t4);\n t4 = Fp.add(t0, t1);\n t3 = Fp.sub(t3, t4);\n t4 = Fp.add(X1, Z1);\n let t5 = Fp.add(X2, Z2); // step 10\n t4 = Fp.mul(t4, t5);\n t5 = Fp.add(t0, t2);\n t4 = Fp.sub(t4, t5);\n t5 = Fp.add(Y1, Z1);\n X3 = Fp.add(Y2, Z2); // step 15\n t5 = Fp.mul(t5, X3);\n X3 = Fp.add(t1, t2);\n t5 = Fp.sub(t5, X3);\n Z3 = Fp.mul(a, t4);\n X3 = Fp.mul(b3, t2); // step 20\n Z3 = Fp.add(X3, Z3);\n X3 = Fp.sub(t1, Z3);\n Z3 = Fp.add(t1, Z3);\n Y3 = Fp.mul(X3, Z3);\n t1 = Fp.add(t0, t0); // step 25\n t1 = Fp.add(t1, t0);\n t2 = Fp.mul(a, t2);\n t4 = Fp.mul(b3, t4);\n t1 = Fp.add(t1, t2);\n t2 = Fp.sub(t0, t2); // step 30\n t2 = Fp.mul(a, t2);\n t4 = Fp.add(t4, t2);\n t0 = Fp.mul(t1, t4);\n Y3 = Fp.add(Y3, t0);\n t0 = Fp.mul(t5, t4); // step 35\n X3 = Fp.mul(t3, X3);\n X3 = Fp.sub(X3, t0);\n t0 = Fp.mul(t3, t1);\n Z3 = Fp.mul(t5, Z3);\n Z3 = Fp.add(Z3, t0); // step 40\n return new Point(X3, Y3, Z3);\n }\n\n subtract(other: Point) {\n return this.add(other.negate());\n }\n\n private is0() {\n return this.equals(Point.ZERO);\n }\n private wNAF(n: bigint): { p: Point; f: Point } {\n return wnaf.wNAFCached(this, pointPrecomputes, n, (comp: Point[]) => {\n const toInv = Fp.invertBatch(comp.map((p) => p.pz));\n return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);\n });\n }\n\n /**\n * Non-constant-time multiplication. Uses double-and-add algorithm.\n * It's faster, but should only be used when you don't care about\n * an exposed private key e.g. sig verification, which works over *public* keys.\n */\n multiplyUnsafe(n: bigint): Point {\n const I = Point.ZERO;\n if (n === _0n) return I;\n assertGE(n); // Will throw on 0\n if (n === _1n) return this;\n const { endo } = CURVE;\n if (!endo) return wnaf.unsafeLadder(this, n);\n\n // Apply endomorphism\n let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let k1p = I;\n let k2p = I;\n let d: Point = this;\n while (k1 > _0n || k2 > _0n) {\n if (k1 & _1n) k1p = k1p.add(d);\n if (k2 & _1n) k2p = k2p.add(d);\n d = d.double();\n k1 >>= _1n;\n k2 >>= _1n;\n }\n if (k1neg) k1p = k1p.negate();\n if (k2neg) k2p = k2p.negate();\n k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);\n return k1p.add(k2p);\n }\n\n /**\n * Constant time multiplication.\n * Uses wNAF method. Windowed method may be 10% faster,\n * but takes 2x longer to generate and consumes 2x memory.\n * Uses precomputes when available.\n * Uses endomorphism for Koblitz curves.\n * @param scalar by which the point would be multiplied\n * @returns New point\n */\n multiply(scalar: bigint): Point {\n assertGE(scalar);\n let n = scalar;\n let point: Point, fake: Point; // Fake point is used to const-time mult\n const { endo } = CURVE;\n if (endo) {\n const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);\n let { p: k1p, f: f1p } = this.wNAF(k1);\n let { p: k2p, f: f2p } = this.wNAF(k2);\n k1p = wnaf.constTimeNegate(k1neg, k1p);\n k2p = wnaf.constTimeNegate(k2neg, k2p);\n k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);\n point = k1p.add(k2p);\n fake = f1p.add(f2p);\n } else {\n const { p, f } = this.wNAF(n);\n point = p;\n fake = f;\n }\n // Normalize `z` for both points, but return only real one\n return Point.normalizeZ([point, fake])[0];\n }\n\n /**\n * Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.\n * Not using Strauss-Shamir trick: precomputation tables are faster.\n * The trick could be useful if both P and Q are not G (not in our case).\n * @returns non-zero affine point\n */\n multiplyAndAddUnsafe(Q: Point, a: bigint, b: bigint): Point | undefined {\n const G = Point.BASE; // No Strauss-Shamir trick: we have 10% faster G precomputes\n const mul = (\n P: Point,\n a: bigint // Select faster multiply() method\n ) => (a === _0n || a === _1n || !P.equals(G) ? P.multiplyUnsafe(a) : P.multiply(a));\n const sum = mul(this, a).add(mul(Q, b));\n return sum.is0() ? undefined : sum;\n }\n\n // Converts Projective point to affine (x, y) coordinates.\n // Can accept precomputed Z^-1 - for example, from invertBatch.\n // (x, y, z) \u220B (x=x/z, y=y/z)\n toAffine(iz?: T): AffinePoint {\n const { px: x, py: y, pz: z } = this;\n const is0 = this.is0();\n // If invZ was 0, we return zero point. However we still want to execute\n // all operations, so we replace invZ with a random number, 1.\n if (iz == null) iz = is0 ? Fp.ONE : Fp.inv(z);\n const ax = Fp.mul(x, iz);\n const ay = Fp.mul(y, iz);\n const zz = Fp.mul(z, iz);\n if (is0) return { x: Fp.ZERO, y: Fp.ZERO };\n if (!Fp.eql(zz, Fp.ONE)) throw new Error('invZ was invalid');\n return { x: ax, y: ay };\n }\n isTorsionFree(): boolean {\n const { h: cofactor, isTorsionFree } = CURVE;\n if (cofactor === _1n) return true; // No subgroups, always torsion-free\n if (isTorsionFree) return isTorsionFree(Point, this);\n throw new Error('isTorsionFree() has not been declared for the elliptic curve');\n }\n clearCofactor(): Point {\n const { h: cofactor, clearCofactor } = CURVE;\n if (cofactor === _1n) return this; // Fast-path\n if (clearCofactor) return clearCofactor(Point, this) as Point;\n return this.multiplyUnsafe(CURVE.h);\n }\n\n toRawBytes(isCompressed = true): Uint8Array {\n this.assertValidity();\n return toBytes(Point, this, isCompressed);\n }\n\n toHex(isCompressed = true): string {\n return ut.bytesToHex(this.toRawBytes(isCompressed));\n }\n }\n const _bits = CURVE.nBitLength;\n const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);\n // Validate if generator point is on curve\n return {\n CURVE,\n ProjectivePoint: Point as ProjConstructor,\n normPrivateKeyToScalar,\n weierstrassEquation,\n isWithinCurveOrder,\n };\n}\n\n// Instance\nexport interface SignatureType {\n readonly r: bigint;\n readonly s: bigint;\n readonly recovery?: number;\n assertValidity(): void;\n addRecoveryBit(recovery: number): RecoveredSignatureType;\n hasHighS(): boolean;\n normalizeS(): SignatureType;\n recoverPublicKey(msgHash: Hex): ProjPointType;\n toCompactRawBytes(): Uint8Array;\n toCompactHex(): string;\n // DER-encoded\n toDERRawBytes(isCompressed?: boolean): Uint8Array;\n toDERHex(isCompressed?: boolean): string;\n}\nexport type RecoveredSignatureType = SignatureType & {\n readonly recovery: number;\n};\n// Static methods\nexport type SignatureConstructor = {\n new (r: bigint, s: bigint): SignatureType;\n fromCompact(hex: Hex): SignatureType;\n fromDER(hex: Hex): SignatureType;\n};\ntype SignatureLike = { r: bigint; s: bigint };\n\nexport type PubKey = Hex | ProjPointType;\n\nexport type CurveType = BasicWCurve & {\n hash: CHash; // CHash not FHash because we need outputLen for DRBG\n hmac: HmacFnSync;\n randomBytes: (bytesLength?: number) => Uint8Array;\n lowS?: boolean;\n bits2int?: (bytes: Uint8Array) => bigint;\n bits2int_modN?: (bytes: Uint8Array) => bigint;\n};\n\nfunction validateOpts(curve: CurveType) {\n const opts = validateBasic(curve);\n ut.validateObject(\n opts,\n {\n hash: 'hash',\n hmac: 'function',\n randomBytes: 'function',\n },\n {\n bits2int: 'function',\n bits2int_modN: 'function',\n lowS: 'boolean',\n }\n );\n return Object.freeze({ lowS: true, ...opts } as const);\n}\n\nexport type CurveFn = {\n CURVE: ReturnType;\n getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;\n getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;\n sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => RecoveredSignatureType;\n verify: (signature: Hex | SignatureLike, msgHash: Hex, publicKey: Hex, opts?: VerOpts) => boolean;\n ProjectivePoint: ProjConstructor;\n Signature: SignatureConstructor;\n utils: {\n normPrivateKeyToScalar: (key: PrivKey) => bigint;\n isValidPrivateKey(privateKey: PrivKey): boolean;\n randomPrivateKey: () => Uint8Array;\n precompute: (windowSize?: number, point?: ProjPointType) => ProjPointType;\n };\n};\n\nexport function weierstrass(curveDef: CurveType): CurveFn {\n const CURVE = validateOpts(curveDef) as ReturnType;\n const { Fp, n: CURVE_ORDER } = CURVE;\n const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32\n const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32\n\n function isValidFieldElement(num: bigint): boolean {\n return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE\n }\n function modN(a: bigint) {\n return mod.mod(a, CURVE_ORDER);\n }\n function invN(a: bigint) {\n return mod.invert(a, CURVE_ORDER);\n }\n\n const {\n ProjectivePoint: Point,\n normPrivateKeyToScalar,\n weierstrassEquation,\n isWithinCurveOrder,\n } = weierstrassPoints({\n ...CURVE,\n toBytes(_c, point, isCompressed: boolean): Uint8Array {\n const a = point.toAffine();\n const x = Fp.toBytes(a.x);\n const cat = ut.concatBytes;\n if (isCompressed) {\n return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);\n } else {\n return cat(Uint8Array.from([0x04]), x, Fp.toBytes(a.y));\n }\n },\n fromBytes(bytes: Uint8Array) {\n const len = bytes.length;\n const head = bytes[0];\n const tail = bytes.subarray(1);\n // this.assertValidity() is done inside of fromHex\n if (len === compressedLen && (head === 0x02 || head === 0x03)) {\n const x = ut.bytesToNumberBE(tail);\n if (!isValidFieldElement(x)) throw new Error('Point is not on curve');\n const y2 = weierstrassEquation(x); // y\u00B2 = x\u00B3 + ax + b\n let y = Fp.sqrt(y2); // y = y\u00B2 ^ (p+1)/4\n const isYOdd = (y & _1n) === _1n;\n // ECDSA\n const isHeadOdd = (head & 1) === 1;\n if (isHeadOdd !== isYOdd) y = Fp.neg(y);\n return { x, y };\n } else if (len === uncompressedLen && head === 0x04) {\n const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));\n const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));\n return { x, y };\n } else {\n throw new Error(\n `Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`\n );\n }\n },\n });\n const numToNByteStr = (num: bigint): string =>\n ut.bytesToHex(ut.numberToBytesBE(num, CURVE.nByteLength));\n\n function isBiggerThanHalfOrder(number: bigint) {\n const HALF = CURVE_ORDER >> _1n;\n return number > HALF;\n }\n\n function normalizeS(s: bigint) {\n return isBiggerThanHalfOrder(s) ? modN(-s) : s;\n }\n // slice bytes num\n const slcNum = (b: Uint8Array, from: number, to: number) => ut.bytesToNumberBE(b.slice(from, to));\n\n /**\n * ECDSA signature with its (r, s) properties. Supports DER & compact representations.\n */\n class Signature implements SignatureType {\n constructor(readonly r: bigint, readonly s: bigint, readonly recovery?: number) {\n this.assertValidity();\n }\n\n // pair (bytes of r, bytes of s)\n static fromCompact(hex: Hex) {\n const l = CURVE.nByteLength;\n hex = ensureBytes('compactSignature', hex, l * 2);\n return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));\n }\n\n // DER encoded ECDSA signature\n // https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script\n static fromDER(hex: Hex) {\n const { r, s } = DER.toSig(ensureBytes('DER', hex));\n return new Signature(r, s);\n }\n\n assertValidity(): void {\n // can use assertGE here\n if (!isWithinCurveOrder(this.r)) throw new Error('r must be 0 < r < CURVE.n');\n if (!isWithinCurveOrder(this.s)) throw new Error('s must be 0 < s < CURVE.n');\n }\n\n addRecoveryBit(recovery: number): RecoveredSignature {\n return new Signature(this.r, this.s, recovery) as RecoveredSignature;\n }\n\n recoverPublicKey(msgHash: Hex): typeof Point.BASE {\n const { r, s, recovery: rec } = this;\n const h = bits2int_modN(ensureBytes('msgHash', msgHash)); // Truncate hash\n if (rec == null || ![0, 1, 2, 3].includes(rec)) throw new Error('recovery id invalid');\n const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;\n if (radj >= Fp.ORDER) throw new Error('recovery id 2 or 3 invalid');\n const prefix = (rec & 1) === 0 ? '02' : '03';\n const R = Point.fromHex(prefix + numToNByteStr(radj));\n const ir = invN(radj); // r^-1\n const u1 = modN(-h * ir); // -hr^-1\n const u2 = modN(s * ir); // sr^-1\n const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2); // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1)\n if (!Q) throw new Error('point at infinify'); // unsafe is fine: no priv data leaked\n Q.assertValidity();\n return Q;\n }\n\n // Signatures should be low-s, to prevent malleability.\n hasHighS(): boolean {\n return isBiggerThanHalfOrder(this.s);\n }\n\n normalizeS() {\n return this.hasHighS() ? new Signature(this.r, modN(-this.s), this.recovery) : this;\n }\n\n // DER-encoded\n toDERRawBytes() {\n return ut.hexToBytes(this.toDERHex());\n }\n toDERHex() {\n return DER.hexFromSig({ r: this.r, s: this.s });\n }\n\n // padded bytes of r, then padded bytes of s\n toCompactRawBytes() {\n return ut.hexToBytes(this.toCompactHex());\n }\n toCompactHex() {\n return numToNByteStr(this.r) + numToNByteStr(this.s);\n }\n }\n type RecoveredSignature = Signature & { recovery: number };\n\n const utils = {\n isValidPrivateKey(privateKey: PrivKey) {\n try {\n normPrivateKeyToScalar(privateKey);\n return true;\n } catch (error) {\n return false;\n }\n },\n normPrivateKeyToScalar: normPrivateKeyToScalar,\n\n /**\n * Produces cryptographically secure private key from random of size\n * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.\n */\n randomPrivateKey: (): Uint8Array => {\n const length = mod.getMinHashLength(CURVE.n);\n return mod.mapHashToField(CURVE.randomBytes(length), CURVE.n);\n },\n\n /**\n * Creates precompute table for an arbitrary EC point. Makes point \"cached\".\n * Allows to massively speed-up `point.multiply(scalar)`.\n * @returns cached point\n * @example\n * const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));\n * fast.multiply(privKey); // much faster ECDH now\n */\n precompute(windowSize = 8, point = Point.BASE): typeof Point.BASE {\n point._setWindowSize(windowSize);\n point.multiply(BigInt(3)); // 3 is arbitrary, just need any number here\n return point;\n },\n };\n\n /**\n * Computes public key for a private key. Checks for validity of the private key.\n * @param privateKey private key\n * @param isCompressed whether to return compact (default), or full key\n * @returns Public key, full when isCompressed=false; short when isCompressed=true\n */\n function getPublicKey(privateKey: PrivKey, isCompressed = true): Uint8Array {\n return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);\n }\n\n /**\n * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.\n */\n function isProbPub(item: PrivKey | PubKey): boolean {\n const arr = item instanceof Uint8Array;\n const str = typeof item === 'string';\n const len = (arr || str) && (item as Hex).length;\n if (arr) return len === compressedLen || len === uncompressedLen;\n if (str) return len === 2 * compressedLen || len === 2 * uncompressedLen;\n if (item instanceof Point) return true;\n return false;\n }\n\n /**\n * ECDH (Elliptic Curve Diffie Hellman).\n * Computes shared public key from private key and public key.\n * Checks: 1) private key validity 2) shared key is on-curve.\n * Does NOT hash the result.\n * @param privateA private key\n * @param publicB different public key\n * @param isCompressed whether to return compact (default), or full key\n * @returns shared public key\n */\n function getSharedSecret(privateA: PrivKey, publicB: Hex, isCompressed = true): Uint8Array {\n if (isProbPub(privateA)) throw new Error('first arg must be private key');\n if (!isProbPub(publicB)) throw new Error('second arg must be public key');\n const b = Point.fromHex(publicB); // check for being on-curve\n return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);\n }\n\n // RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.\n // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which matches bits2int.\n // bits2int can produce res>N, we can do mod(res, N) since the bitLen is the same.\n // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors\n const bits2int =\n CURVE.bits2int ||\n function (bytes: Uint8Array): bigint {\n // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)\n // for some cases, since bytes.length * 8 is not actual bitLength.\n const num = ut.bytesToNumberBE(bytes); // check for == u8 done here\n const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits\n return delta > 0 ? num >> BigInt(delta) : num;\n };\n const bits2int_modN =\n CURVE.bits2int_modN ||\n function (bytes: Uint8Array): bigint {\n return modN(bits2int(bytes)); // can't use bytesToNumberBE here\n };\n // NOTE: pads output with zero as per spec\n const ORDER_MASK = ut.bitMask(CURVE.nBitLength);\n /**\n * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.\n */\n function int2octets(num: bigint): Uint8Array {\n if (typeof num !== 'bigint') throw new Error('bigint expected');\n if (!(_0n <= num && num < ORDER_MASK))\n throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);\n // works with order, can have different size than numToField!\n return ut.numberToBytesBE(num, CURVE.nByteLength);\n }\n\n // Steps A, D of RFC6979 3.2\n // Creates RFC6979 seed; converts msg/privKey to numbers.\n // Used only in sign, not in verify.\n // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.\n // Also it can be bigger for P224 + SHA256\n function prepSig(msgHash: Hex, privateKey: PrivKey, opts = defaultSigOpts) {\n if (['recovered', 'canonical'].some((k) => k in opts))\n throw new Error('sign() legacy options not supported');\n const { hash, randomBytes } = CURVE;\n let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default\n if (lowS == null) lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash\n msgHash = ensureBytes('msgHash', msgHash);\n if (prehash) msgHash = ensureBytes('prehashed msgHash', hash(msgHash));\n\n // We can't later call bits2octets, since nested bits2int is broken for curves\n // with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.\n // const bits2octets = (bits) => int2octets(bits2int_modN(bits))\n const h1int = bits2int_modN(msgHash);\n const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint\n const seedArgs = [int2octets(d), int2octets(h1int)];\n // extraEntropy. RFC6979 3.6: additional k' (optional).\n if (ent != null) {\n // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')\n const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is\n seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes\n }\n const seed = ut.concatBytes(...seedArgs); // Step D of RFC6979 3.2\n const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!\n // Converts signature params into point w r/s, checks result for validity.\n function k2sig(kBytes: Uint8Array): RecoveredSignature | undefined {\n // RFC 6979 Section 3.2, step 3: k = bits2int(T)\n const k = bits2int(kBytes); // Cannot use fields methods, since it is group element\n if (!isWithinCurveOrder(k)) return; // Important: all mod() calls here must be done over N\n const ik = invN(k); // k^-1 mod n\n const q = Point.BASE.multiply(k).toAffine(); // q = Gk\n const r = modN(q.x); // r = q.x mod n\n if (r === _0n) return;\n // Can use scalar blinding b^-1(bm + bdr) where b \u2208 [1,q\u22121] according to\n // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:\n // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT\n const s = modN(ik * modN(m + r * d)); // Not using blinding here\n if (s === _0n) return;\n let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)\n let normS = s;\n if (lowS && isBiggerThanHalfOrder(s)) {\n normS = normalizeS(s); // if lowS was passed, ensure s is always\n recovery ^= 1; // // in the bottom half of N\n }\n return new Signature(r, normS, recovery) as RecoveredSignature; // use normS, not s\n }\n return { seed, k2sig };\n }\n const defaultSigOpts: SignOpts = { lowS: CURVE.lowS, prehash: false };\n const defaultVerOpts: VerOpts = { lowS: CURVE.lowS, prehash: false };\n\n /**\n * Signs message hash with a private key.\n * ```\n * sign(m, d, k) where\n * (x, y) = G \u00D7 k\n * r = x mod n\n * s = (m + dr)/k mod n\n * ```\n * @param msgHash NOT message. msg needs to be hashed to `msgHash`, or use `prehash`.\n * @param privKey private key\n * @param opts lowS for non-malleable sigs. extraEntropy for mixing randomness into k. prehash will hash first arg.\n * @returns signature with recovery param\n */\n function sign(msgHash: Hex, privKey: PrivKey, opts = defaultSigOpts): RecoveredSignature {\n const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.\n const C = CURVE;\n const drbg = ut.createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac);\n return drbg(seed, k2sig); // Steps B, C, D, E, F, G\n }\n\n // Enable precomputes. Slows down first publicKey computation by 20ms.\n Point.BASE._setWindowSize(8);\n // utils.precompute(8, ProjectivePoint.BASE)\n\n /**\n * Verifies a signature against message hash and public key.\n * Rejects lowS signatures by default: to override,\n * specify option `{lowS: false}`. Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:\n *\n * ```\n * verify(r, s, h, P) where\n * U1 = hs^-1 mod n\n * U2 = rs^-1 mod n\n * R = U1\u22C5G - U2\u22C5P\n * mod(R.x, n) == r\n * ```\n */\n function verify(\n signature: Hex | SignatureLike,\n msgHash: Hex,\n publicKey: Hex,\n opts = defaultVerOpts\n ): boolean {\n const sg = signature;\n msgHash = ensureBytes('msgHash', msgHash);\n publicKey = ensureBytes('publicKey', publicKey);\n if ('strict' in opts) throw new Error('options.strict was renamed to lowS');\n const { lowS, prehash } = opts;\n\n let _sig: Signature | undefined = undefined;\n let P: ProjPointType;\n try {\n if (typeof sg === 'string' || sg instanceof Uint8Array) {\n // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).\n // Since DER can also be 2*nByteLength bytes, we check for it first.\n try {\n _sig = Signature.fromDER(sg);\n } catch (derError) {\n if (!(derError instanceof DER.Err)) throw derError;\n _sig = Signature.fromCompact(sg);\n }\n } else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {\n const { r, s } = sg;\n _sig = new Signature(r, s);\n } else {\n throw new Error('PARSE');\n }\n P = Point.fromHex(publicKey);\n } catch (error) {\n if ((error as Error).message === 'PARSE')\n throw new Error(`signature must be Signature instance, Uint8Array or hex string`);\n return false;\n }\n if (lowS && _sig.hasHighS()) return false;\n if (prehash) msgHash = CURVE.hash(msgHash);\n const { r, s } = _sig;\n const h = bits2int_modN(msgHash); // Cannot use fields methods, since it is group element\n const is = invN(s); // s^-1\n const u1 = modN(h * is); // u1 = hs^-1 mod n\n const u2 = modN(r * is); // u2 = rs^-1 mod n\n const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2)?.toAffine(); // R = u1\u22C5G + u2\u22C5P\n if (!R) return false;\n const v = modN(R.x);\n return v === r;\n }\n return {\n CURVE,\n getPublicKey,\n getSharedSecret,\n sign,\n verify,\n ProjectivePoint: Point,\n Signature,\n utils,\n };\n}\n\n/**\n * Implementation of the Shallue and van de Woestijne method for any weierstrass curve.\n * TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.\n * b = True and y = sqrt(u / v) if (u / v) is square in F, and\n * b = False and y = sqrt(Z * (u / v)) otherwise.\n * @param Fp\n * @param Z\n * @returns\n */\nexport function SWUFpSqrtRatio(Fp: mod.IField, Z: T) {\n // Generic implementation\n const q = Fp.ORDER;\n let l = _0n;\n for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;\n const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.\n // We need 2n ** c1 and 2n ** (c1-1). We can't use **; but we can use <<.\n // 2n ** c1 == 2n << (c1-1)\n const _2n_pow_c1_1 = _2n << (c1 - _1n - _1n);\n const _2n_pow_c1 = _2n_pow_c1_1 * _2n;\n const c2 = (q - _1n) / _2n_pow_c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic\n const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic\n const c4 = _2n_pow_c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic\n const c5 = _2n_pow_c1_1; // 5. c5 = 2^(c1 - 1) # Integer arithmetic\n const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2\n const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)\n let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {\n let tv1 = c6; // 1. tv1 = c6\n let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4\n let tv3 = Fp.sqr(tv2); // 3. tv3 = tv2^2\n tv3 = Fp.mul(tv3, v); // 4. tv3 = tv3 * v\n let tv5 = Fp.mul(u, tv3); // 5. tv5 = u * tv3\n tv5 = Fp.pow(tv5, c3); // 6. tv5 = tv5^c3\n tv5 = Fp.mul(tv5, tv2); // 7. tv5 = tv5 * tv2\n tv2 = Fp.mul(tv5, v); // 8. tv2 = tv5 * v\n tv3 = Fp.mul(tv5, u); // 9. tv3 = tv5 * u\n let tv4 = Fp.mul(tv3, tv2); // 10. tv4 = tv3 * tv2\n tv5 = Fp.pow(tv4, c5); // 11. tv5 = tv4^c5\n let isQR = Fp.eql(tv5, Fp.ONE); // 12. isQR = tv5 == 1\n tv2 = Fp.mul(tv3, c7); // 13. tv2 = tv3 * c7\n tv5 = Fp.mul(tv4, tv1); // 14. tv5 = tv4 * tv1\n tv3 = Fp.cmov(tv2, tv3, isQR); // 15. tv3 = CMOV(tv2, tv3, isQR)\n tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)\n // 17. for i in (c1, c1 - 1, ..., 2):\n for (let i = c1; i > _1n; i--) {\n let tv5 = i - _2n; // 18. tv5 = i - 2\n tv5 = _2n << (tv5 - _1n); // 19. tv5 = 2^tv5\n let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5\n const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1\n tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1\n tv1 = Fp.mul(tv1, tv1); // 23. tv1 = tv1 * tv1\n tvv5 = Fp.mul(tv4, tv1); // 24. tv5 = tv4 * tv1\n tv3 = Fp.cmov(tv2, tv3, e1); // 25. tv3 = CMOV(tv2, tv3, e1)\n tv4 = Fp.cmov(tvv5, tv4, e1); // 26. tv4 = CMOV(tv5, tv4, e1)\n }\n return { isValid: isQR, value: tv3 };\n };\n if (Fp.ORDER % _4n === _3n) {\n // sqrt_ratio_3mod4(u, v)\n const c1 = (Fp.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic\n const c2 = Fp.sqrt(Fp.neg(Z)); // 2. c2 = sqrt(-Z)\n sqrtRatio = (u: T, v: T) => {\n let tv1 = Fp.sqr(v); // 1. tv1 = v^2\n const tv2 = Fp.mul(u, v); // 2. tv2 = u * v\n tv1 = Fp.mul(tv1, tv2); // 3. tv1 = tv1 * tv2\n let y1 = Fp.pow(tv1, c1); // 4. y1 = tv1^c1\n y1 = Fp.mul(y1, tv2); // 5. y1 = y1 * tv2\n const y2 = Fp.mul(y1, c2); // 6. y2 = y1 * c2\n const tv3 = Fp.mul(Fp.sqr(y1), v); // 7. tv3 = y1^2; 8. tv3 = tv3 * v\n const isQR = Fp.eql(tv3, u); // 9. isQR = tv3 == u\n let y = Fp.cmov(y2, y1, isQR); // 10. y = CMOV(y2, y1, isQR)\n return { isValid: isQR, value: y }; // 11. return (isQR, y) isQR ? y : y*c2\n };\n }\n // No curves uses that\n // if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8\n return sqrtRatio;\n}\n/**\n * Simplified Shallue-van de Woestijne-Ulas Method\n * https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2\n */\nexport function mapToCurveSimpleSWU(\n Fp: mod.IField,\n opts: {\n A: T;\n B: T;\n Z: T;\n }\n) {\n mod.validateField(Fp);\n if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))\n throw new Error('mapToCurveSimpleSWU: invalid opts');\n const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);\n if (!Fp.isOdd) throw new Error('Fp.isOdd is not implemented!');\n // Input: u, an element of F.\n // Output: (x, y), a point on E.\n return (u: T): { x: T; y: T } => {\n // prettier-ignore\n let tv1, tv2, tv3, tv4, tv5, tv6, x, y;\n tv1 = Fp.sqr(u); // 1. tv1 = u^2\n tv1 = Fp.mul(tv1, opts.Z); // 2. tv1 = Z * tv1\n tv2 = Fp.sqr(tv1); // 3. tv2 = tv1^2\n tv2 = Fp.add(tv2, tv1); // 4. tv2 = tv2 + tv1\n tv3 = Fp.add(tv2, Fp.ONE); // 5. tv3 = tv2 + 1\n tv3 = Fp.mul(tv3, opts.B); // 6. tv3 = B * tv3\n tv4 = Fp.cmov(opts.Z, Fp.neg(tv2), !Fp.eql(tv2, Fp.ZERO)); // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)\n tv4 = Fp.mul(tv4, opts.A); // 8. tv4 = A * tv4\n tv2 = Fp.sqr(tv3); // 9. tv2 = tv3^2\n tv6 = Fp.sqr(tv4); // 10. tv6 = tv4^2\n tv5 = Fp.mul(tv6, opts.A); // 11. tv5 = A * tv6\n tv2 = Fp.add(tv2, tv5); // 12. tv2 = tv2 + tv5\n tv2 = Fp.mul(tv2, tv3); // 13. tv2 = tv2 * tv3\n tv6 = Fp.mul(tv6, tv4); // 14. tv6 = tv6 * tv4\n tv5 = Fp.mul(tv6, opts.B); // 15. tv5 = B * tv6\n tv2 = Fp.add(tv2, tv5); // 16. tv2 = tv2 + tv5\n x = Fp.mul(tv1, tv3); // 17. x = tv1 * tv3\n const { isValid, value } = sqrtRatio(tv2, tv6); // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)\n y = Fp.mul(tv1, u); // 19. y = tv1 * u -> Z * u^3 * y1\n y = Fp.mul(y, value); // 20. y = y * y1\n x = Fp.cmov(x, tv3, isValid); // 21. x = CMOV(x, tv3, is_gx1_square)\n y = Fp.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)\n const e1 = Fp.isOdd!(u) === Fp.isOdd!(y); // 23. e1 = sgn0(u) == sgn0(y)\n y = Fp.cmov(Fp.neg(y), y, e1); // 24. y = CMOV(-y, y, e1)\n x = Fp.div(x, tv4); // 25. x = x / tv4\n return { x, y };\n };\n}\n", "import { hash as assertHash, bytes as assertBytes, exists as assertExists } from './_assert.js';\nimport { Hash, CHash, Input, toBytes } from './utils.js';\n// HMAC (RFC 2104)\nexport class HMAC> extends Hash> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: CHash, _key: Input) {\n super();\n assertHash(hash);\n const key = toBytes(_key);\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n pad.fill(0);\n }\n update(buf: Input) {\n assertExists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: Uint8Array) {\n assertExists(this);\n assertBytes(out, this.outputLen);\n this.finished = true;\n this.iHash.digestInto(out);\n this.oHash.update(out);\n this.oHash.digestInto(out);\n this.destroy();\n }\n digest() {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out;\n }\n _cloneInto(to?: HMAC): HMAC {\n // Create new instance without calling constructor since key already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n destroy() {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n */\nexport const hmac = (hash: CHash, key: Input, message: Input): Uint8Array =>\n new HMAC(hash, key).update(message).digest();\nhmac.create = (hash: CHash, key: Input) => new HMAC(hash, key);\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { hmac } from '@noble/hashes/hmac';\nimport { concatBytes, randomBytes } from '@noble/hashes/utils';\nimport { weierstrass, CurveType } from './abstract/weierstrass.js';\nimport { CHash } from './abstract/utils.js';\n\n// connects noble-curves to noble-hashes\nexport function getHash(hash: CHash) {\n return {\n hash,\n hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(hash, key, concatBytes(...msgs)),\n randomBytes,\n };\n}\n// Same API as @noble/hashes, with ability to create curve with custom hash\ntype CurveDef = Readonly>;\nexport function createCurve(curveDef: CurveDef, defHash: CHash) {\n const create = (hash: CHash) => weierstrass({ ...curveDef, ...getHash(hash) });\n return Object.freeze({ ...create(defHash), create });\n}\n", "/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nimport { sha256 } from '@noble/hashes/sha256';\nimport { randomBytes } from '@noble/hashes/utils';\nimport { Field, mod, pow2 } from './abstract/modular.js';\nimport { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js';\nimport type { Hex, PrivKey } from './abstract/utils.js';\nimport { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js';\nimport { createHasher, isogenyMap } from './abstract/hash-to-curve.js';\nimport { createCurve } from './_shortw_utils.js';\n\nconst secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');\nconst secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst divNearest = (a: bigint, b: bigint) => (a + b / _2n) / b;\n\n/**\n * \u221An = n^((p+1)/4) for fields p = 3 mod 4. We unwrap the loop and multiply bit-by-bit.\n * (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]\n */\nfunction sqrtMod(y: bigint): bigint {\n const P = secp256k1P;\n // prettier-ignore\n const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);\n // prettier-ignore\n const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);\n const b2 = (y * y * y) % P; // x^3, 11\n const b3 = (b2 * b2 * y) % P; // x^7\n const b6 = (pow2(b3, _3n, P) * b3) % P;\n const b9 = (pow2(b6, _3n, P) * b3) % P;\n const b11 = (pow2(b9, _2n, P) * b2) % P;\n const b22 = (pow2(b11, _11n, P) * b11) % P;\n const b44 = (pow2(b22, _22n, P) * b22) % P;\n const b88 = (pow2(b44, _44n, P) * b44) % P;\n const b176 = (pow2(b88, _88n, P) * b88) % P;\n const b220 = (pow2(b176, _44n, P) * b44) % P;\n const b223 = (pow2(b220, _3n, P) * b3) % P;\n const t1 = (pow2(b223, _23n, P) * b22) % P;\n const t2 = (pow2(t1, _6n, P) * b2) % P;\n const root = pow2(t2, _2n, P);\n if (!Fp.eql(Fp.sqr(root), y)) throw new Error('Cannot find square root');\n return root;\n}\n\nconst Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });\n\nexport const secp256k1 = createCurve(\n {\n a: BigInt(0), // equation params: a, b\n b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975\n Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n\n n: secp256k1N, // Curve order, total count of valid points in the field\n // Base point (x, y) aka generator point\n Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),\n Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),\n h: BigInt(1), // Cofactor\n lowS: true, // Allow only low-S signatures by default in sign() and verify()\n /**\n * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.\n * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.\n * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.\n * Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066\n */\n endo: {\n beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),\n splitScalar: (k: bigint) => {\n const n = secp256k1N;\n const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');\n const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');\n const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');\n const b2 = a1;\n const POW_2_128 = BigInt('0x100000000000000000000000000000000'); // (2n**128n).toString(16)\n\n const c1 = divNearest(b2 * k, n);\n const c2 = divNearest(-b1 * k, n);\n let k1 = mod(k - c1 * a1 - c2 * a2, n);\n let k2 = mod(-c1 * b1 - c2 * b2, n);\n const k1neg = k1 > POW_2_128;\n const k2neg = k2 > POW_2_128;\n if (k1neg) k1 = n - k1;\n if (k2neg) k2 = n - k2;\n if (k1 > POW_2_128 || k2 > POW_2_128) {\n throw new Error('splitScalar: Endomorphism failed, k=' + k);\n }\n return { k1neg, k1, k2neg, k2 };\n },\n },\n },\n sha256\n);\n\n// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.\n// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki\nconst _0n = BigInt(0);\nconst fe = (x: bigint) => typeof x === 'bigint' && _0n < x && x < secp256k1P;\nconst ge = (x: bigint) => typeof x === 'bigint' && _0n < x && x < secp256k1N;\n/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */\nconst TAGGED_HASH_PREFIXES: { [tag: string]: Uint8Array } = {};\nfunction taggedHash(tag: string, ...messages: Uint8Array[]): Uint8Array {\n let tagP = TAGGED_HASH_PREFIXES[tag];\n if (tagP === undefined) {\n const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));\n tagP = concatBytes(tagH, tagH);\n TAGGED_HASH_PREFIXES[tag] = tagP;\n }\n return sha256(concatBytes(tagP, ...messages));\n}\n\n// ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03\nconst pointToBytes = (point: PointType) => point.toRawBytes(true).slice(1);\nconst numTo32b = (n: bigint) => numberToBytesBE(n, 32);\nconst modP = (x: bigint) => mod(x, secp256k1P);\nconst modN = (x: bigint) => mod(x, secp256k1N);\nconst Point = secp256k1.ProjectivePoint;\nconst GmulAdd = (Q: PointType, a: bigint, b: bigint) =>\n Point.BASE.multiplyAndAddUnsafe(Q, a, b);\n\n// Calculate point, scalar and bytes\nfunction schnorrGetExtPubKey(priv: PrivKey) {\n let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey\n let p = Point.fromPrivateKey(d_); // P = d'\u22C5G; 0 < d' < n check is done inside\n const scalar = p.hasEvenY() ? d_ : modN(-d_);\n return { scalar: scalar, bytes: pointToBytes(p) };\n}\n/**\n * lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.\n * @returns valid point checked for being on-curve\n */\nfunction lift_x(x: bigint): PointType {\n if (!fe(x)) throw new Error('bad x: need 0 < x < p'); // Fail if x \u2265 p.\n const xx = modP(x * x);\n const c = modP(xx * x + BigInt(7)); // Let c = x\u00B3 + 7 mod p.\n let y = sqrtMod(c); // Let y = c^(p+1)/4 mod p.\n if (y % _2n !== _0n) y = modP(-y); // Return the unique point P such that x(P) = x and\n const p = new Point(x, y, _1n); // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.\n p.assertValidity();\n return p;\n}\n/**\n * Create tagged hash, convert it to bigint, reduce modulo-n.\n */\nfunction challenge(...args: Uint8Array[]): bigint {\n return modN(bytesToNumberBE(taggedHash('BIP0340/challenge', ...args)));\n}\n\n/**\n * Schnorr public key is just `x` coordinate of Point as per BIP340.\n */\nfunction schnorrGetPublicKey(privateKey: Hex): Uint8Array {\n return schnorrGetExtPubKey(privateKey).bytes; // d'=int(sk). Fail if d'=0 or d'\u2265n. Ret bytes(d'\u22C5G)\n}\n\n/**\n * Creates Schnorr signature as per BIP340. Verifies itself before returning anything.\n * auxRand is optional and is not the sole source of k generation: bad CSPRNG won't be dangerous.\n */\nfunction schnorrSign(\n message: Hex,\n privateKey: PrivKey,\n auxRand: Hex = randomBytes(32)\n): Uint8Array {\n const m = ensureBytes('message', message);\n const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey); // checks for isWithinCurveOrder\n const a = ensureBytes('auxRand', auxRand, 32); // Auxiliary random data a: a 32-byte array\n const t = numTo32b(d ^ bytesToNumberBE(taggedHash('BIP0340/aux', a))); // Let t be the byte-wise xor of bytes(d) and hash/aux(a)\n const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)\n const k_ = modN(bytesToNumberBE(rand)); // Let k' = int(rand) mod n\n if (k_ === _0n) throw new Error('sign failed: k is zero'); // Fail if k' = 0.\n const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'\u22C5G.\n const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.\n const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).\n sig.set(rx, 0);\n sig.set(numTo32b(modN(k + e * d)), 32);\n // If Verify(bytes(P), m, sig) (see below) returns failure, abort\n if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');\n return sig;\n}\n\n/**\n * Verifies Schnorr signature.\n * Will swallow errors & return false except for initial type validation of arguments.\n */\nfunction schnorrVerify(signature: Hex, message: Hex, publicKey: Hex): boolean {\n const sig = ensureBytes('signature', signature, 64);\n const m = ensureBytes('message', message);\n const pub = ensureBytes('publicKey', publicKey, 32);\n try {\n const P = lift_x(bytesToNumberBE(pub)); // P = lift_x(int(pk)); fail if that fails\n const r = bytesToNumberBE(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r \u2265 p.\n if (!fe(r)) return false;\n const s = bytesToNumberBE(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s \u2265 n.\n if (!ge(s)) return false;\n const e = challenge(numTo32b(r), pointToBytes(P), m); // int(challenge(bytes(r)||bytes(P)||m))%n\n const R = GmulAdd(P, s, modN(-e)); // R = s\u22C5G - e\u22C5P\n if (!R || !R.hasEvenY() || R.toAffine().x !== r) return false; // -eP == (n-e)P\n return true; // Fail if is_infinite(R) / not has_even_y(R) / x(R) \u2260 r.\n } catch (error) {\n return false;\n }\n}\n\nexport const schnorr = /* @__PURE__ */ (() => ({\n getPublicKey: schnorrGetPublicKey,\n sign: schnorrSign,\n verify: schnorrVerify,\n utils: {\n randomPrivateKey: secp256k1.utils.randomPrivateKey,\n lift_x,\n pointToBytes,\n numberToBytesBE,\n bytesToNumberBE,\n taggedHash,\n mod,\n },\n}))();\n\nconst isoMap = /* @__PURE__ */ (() =>\n isogenyMap(\n Fp,\n [\n // xNum\n [\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',\n '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',\n '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',\n '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',\n ],\n // xDen\n [\n '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',\n '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n // yNum\n [\n '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',\n '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',\n '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',\n '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',\n ],\n // yDen\n [\n '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',\n '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',\n '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',\n '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1\n ],\n ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]]\n ))();\nconst mapSWU = /* @__PURE__ */ (() =>\n mapToCurveSimpleSWU(Fp, {\n A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),\n B: BigInt('1771'),\n Z: Fp.create(BigInt('-11')),\n }))();\nconst htf = /* @__PURE__ */ (() =>\n createHasher(\n secp256k1.ProjectivePoint,\n (scalars: bigint[]) => {\n const { x, y } = mapSWU(Fp.create(scalars[0]));\n return isoMap(x, y);\n },\n {\n DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',\n encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',\n p: Fp.ORDER,\n m: 1,\n k: 128,\n expand: 'xmd',\n hash: sha256,\n }\n ))();\nexport const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();\nexport const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();\n", "// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// See utils.ts for details.\ndeclare const globalThis: Record | undefined;\nexport const crypto =\n typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\n", "/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated, we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\n\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\nconst u8a = (a: any): a is Uint8Array => a instanceof Uint8Array;\n// Cast array to different type\nexport const u8 = (arr: TypedArray) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u32 = (arr: TypedArray) =>\n new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n\n// Cast array to view\nexport const createView = (arr: TypedArray) =>\n new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n\n// The rotate right (circular right shift) operation for uint32\nexport const rotr = (word: number, shift: number) => (word << (32 - shift)) | (word >>> shift);\n\n// big-endian hardware is rare. Just in case someone still decides to run hashes:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE) throw new Error('Non little-endian hardware is not supported');\n\nconst hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n if (!u8a(bytes)) throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex: string): Uint8Array {\n if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2) throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => {};\n\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters: number, tick: number, cb: (i: number) => void) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols in both browsers and Node.js since v11\n// See https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str: string): Uint8Array {\n if (typeof str !== 'string') throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\nexport type Input = Uint8Array | string;\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data: Input): Uint8Array {\n if (typeof data === 'string') data = utf8ToBytes(data);\n if (!u8a(data)) throw new Error(`expected Uint8Array, got ${typeof data}`);\n return data;\n}\n\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a)) throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n\n// For runtime check if class implements interface\nexport abstract class Hash> {\n abstract blockLen: number; // Bytes per block\n abstract outputLen: number; // Bytes in output\n abstract update(buf: Input): this;\n // Writes digest into buf\n abstract digestInto(buf: Uint8Array): void;\n abstract digest(): Uint8Array;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n abstract destroy(): void;\n /**\n * Clones hash instance. Unsafe: doesn't check whether `to` is valid. Can be used as `clone()`\n * when no options are passed.\n * Reasons to use `_cloneInto` instead of clone: 1) performance 2) reuse instance => all internal\n * buffers are overwritten => causes buffer overwrite which is used for digest in some cases.\n * There are no guarantees for clean-up because it's impossible in JS.\n */\n abstract _cloneInto(to?: T): T;\n // Safe version that clones internal state\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF> = Hash & {\n xof(bytes: number): Uint8Array; // Read 'bytes' bytes from digest stream\n xofInto(buf: Uint8Array): Uint8Array; // read buf.length bytes from digest stream into buf\n};\n\n// Check if object doens't have custom constructor (like Uint8Array/Array)\nconst isPlainObject = (obj: any) =>\n Object.prototype.toString.call(obj) === '[object Object]' && obj.constructor === Object;\n\ntype EmptyObj = {};\nexport function checkOpts(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && (typeof opts !== 'object' || !isPlainObject(opts)))\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\nexport type CHash = ReturnType;\n\nexport function wrapConstructor>(hashCons: () => Hash) {\n const hashC = (msg: Input): Uint8Array => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\n\nexport function wrapConstructorWithOpts, T extends Object>(\n hashCons: (opts?: T) => Hash\n) {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\nexport function wrapXOFConstructorWithOpts, T extends Object>(\n hashCons: (opts?: T) => HashXOF\n) {\n const hashC = (msg: Input, opts?: T): Uint8Array => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({} as T);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts: T) => hashCons(opts);\n return hashC;\n}\n\n/**\n * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.\n */\nexport function randomBytes(bytesLength = 32): Uint8Array {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n", "export function number(n: number) {\n if (!Number.isSafeInteger(n) || n < 0) throw new Error(`Wrong positive integer: ${n}`);\n}\n\nexport function bool(b: boolean) {\n if (typeof b !== 'boolean') throw new Error(`Expected boolean, not ${b}`);\n}\n\nexport function bytes(b: Uint8Array | undefined, ...lengths: number[]) {\n if (!(b instanceof Uint8Array)) throw new Error('Expected Uint8Array');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);\n}\n\ntype Hash = {\n (data: Uint8Array): Uint8Array;\n blockLen: number;\n outputLen: number;\n create: any;\n};\nexport function hash(hash: Hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('Hash should be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\n\nexport function exists(instance: any, checkFinished = true) {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\nexport function output(out: any, instance: any) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\n\nconst assert = {\n number,\n bool,\n bytes,\n hash,\n exists,\n output,\n};\n\nexport default assert;\n", "import assert from './_assert.js';\nimport { Hash, createView, Input, toBytes } from './utils.js';\n\n// Polyfill for Safari 14\nfunction setBigUint64(view: DataView, byteOffset: number, value: bigint, isLE: boolean): void {\n if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n\n// Base SHA2 class (RFC 6234)\nexport abstract class SHA2> extends Hash {\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(\n readonly blockLen: number,\n public outputLen: number,\n readonly padOffset: number,\n readonly isLE: boolean\n ) {\n super();\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: Input): this {\n assert.exists(this);\n const { view, buffer, blockLen } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input, cast it to view and process\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: Uint8Array) {\n assert.exists(this);\n assert.output(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n this.buffer.subarray(pos).fill(0);\n // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n // So we just write lowest 64 bits of that value.\n setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen should be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest() {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.length = length;\n to.pos = pos;\n to.finished = finished;\n to.destroyed = destroyed;\n if (length % blockLen) to.buffer.set(buffer);\n return to;\n }\n}\n", "import { SHA2 } from './_sha2.js';\nimport { rotr, wrapConstructor } from './utils.js';\n\n// Choice: a ? b : c\nconst Chi = (a: number, b: number, c: number) => (a & b) ^ (~a & c);\n// Majority function, true if any two inpust is true\nconst Maj = (a: number, b: number, c: number) => (a & b) ^ (a & c) ^ (b & c);\n\n// Round constants:\n// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\n// prettier-ignore\nconst SHA256_K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n// prettier-ignore\nconst IV = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n]);\n\n// Temporary buffer, not used to store anything between runs\n// Named this way because it matches specification.\nconst SHA256_W = new Uint32Array(64);\nclass SHA256 extends SHA2 {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n A = IV[0] | 0;\n B = IV[1] | 0;\n C = IV[2] | 0;\n D = IV[3] | 0;\n E = IV[4] | 0;\n F = IV[5] | 0;\n G = IV[6] | 0;\n H = IV[7] | 0;\n\n constructor() {\n super(64, 32, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean() {\n SHA256_W.fill(0);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n this.buffer.fill(0);\n }\n}\n// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf\nclass SHA224 extends SHA256 {\n A = 0xc1059ed8 | 0;\n B = 0x367cd507 | 0;\n C = 0x3070dd17 | 0;\n D = 0xf70e5939 | 0;\n E = 0xffc00b31 | 0;\n F = 0x68581511 | 0;\n G = 0x64f98fa7 | 0;\n H = 0xbefa4fa4 | 0;\n constructor() {\n super();\n this.outputLen = 28;\n }\n}\n\n/**\n * SHA2-256 hash function\n * @param message - data that would be hashed\n */\nexport const sha256 = wrapConstructor(() => new SHA256());\nexport const sha224 = wrapConstructor(() => new SHA224());\n", "// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] === \"object\")\n return false;\n }\n }\n return true;\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\nfunction normalizeURL(url) {\n if (url.indexOf(\"://\") === -1)\n url = \"wss://\" + url;\n let p = new URL(url);\n p.pathname = p.pathname.replace(/\\/+/g, \"/\");\n if (p.pathname.endsWith(\"/\"))\n p.pathname = p.pathname.slice(0, -1);\n if (p.port === \"80\" && p.protocol === \"ws:\" || p.port === \"443\" && p.protocol === \"wss:\")\n p.port = \"\";\n p.searchParams.sort();\n p.hash = \"\";\n return p.toString();\n}\nvar QueueNode = class {\n value;\n next = null;\n prev = null;\n constructor(message) {\n this.value = message;\n }\n};\nvar Queue = class {\n first;\n last;\n constructor() {\n this.first = null;\n this.last = null;\n }\n enqueue(value) {\n const newNode = new QueueNode(value);\n if (!this.last) {\n this.first = newNode;\n this.last = newNode;\n } else if (this.last === this.first) {\n this.last = newNode;\n this.last.prev = this.first;\n this.first.next = newNode;\n } else {\n newNode.prev = this.last;\n this.last.next = newNode;\n this.last = newNode;\n }\n return true;\n }\n dequeue() {\n if (!this.first)\n return null;\n if (this.first === this.last) {\n const target2 = this.first;\n this.first = null;\n this.last = null;\n return target2.value;\n }\n const target = this.first;\n this.first = target.next;\n return target.value;\n }\n};\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\n\n// kinds.ts\nvar ClientAuth = 22242;\n\n// filter.ts\nfunction matchFilter(filter, event) {\n if (filter.ids && filter.ids.indexOf(event.id) === -1) {\n return false;\n }\n if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {\n return false;\n }\n if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {\n return false;\n }\n for (let f in filter) {\n if (f[0] === \"#\") {\n let tagName = f.slice(1);\n let values = filter[`#${tagName}`];\n if (values && !event.tags.find(([t, v]) => t === f.slice(1) && values.indexOf(v) !== -1))\n return false;\n }\n }\n if (filter.since && event.created_at < filter.since)\n return false;\n if (filter.until && event.created_at > filter.until)\n return false;\n return true;\n}\nfunction matchFilters(filters, event) {\n for (let i2 = 0; i2 < filters.length; i2++) {\n if (matchFilter(filters[i2], event)) {\n return true;\n }\n }\n return false;\n}\n\n// fakejson.ts\nfunction getHex64(json, field) {\n let len = field.length + 3;\n let idx = json.indexOf(`\"${field}\":`) + len;\n let s = json.slice(idx).indexOf(`\"`) + idx + 1;\n return json.slice(s, s + 64);\n}\nfunction getSubscriptionId(json) {\n let idx = json.slice(0, 22).indexOf(`\"EVENT\"`);\n if (idx === -1)\n return null;\n let pstart = json.slice(idx + 7 + 1).indexOf(`\"`);\n if (pstart === -1)\n return null;\n let start = idx + 7 + 1 + pstart;\n let pend = json.slice(start + 1, 80).indexOf(`\"`);\n if (pend === -1)\n return null;\n let end = start + 1 + pend;\n return json.slice(start + 1, end);\n}\n\n// nip42.ts\nfunction makeAuthEvent(relayURL, challenge) {\n return {\n kind: ClientAuth,\n created_at: Math.floor(Date.now() / 1e3),\n tags: [\n [\"relay\", relayURL],\n [\"challenge\", challenge]\n ],\n content: \"\"\n };\n}\n\n// helpers.ts\nasync function yieldThread() {\n return new Promise((resolve) => {\n const ch = new MessageChannel();\n const handler = () => {\n ch.port1.removeEventListener(\"message\", handler);\n resolve();\n };\n ch.port1.addEventListener(\"message\", handler);\n ch.port2.postMessage(0);\n ch.port1.start();\n });\n}\nvar alwaysTrue = (t) => {\n t[verifiedSymbol] = true;\n return true;\n};\n\n// abstract-relay.ts\nvar AbstractRelay = class {\n url;\n _connected = false;\n onclose = null;\n onnotice = (msg) => console.debug(`NOTICE from ${this.url}: ${msg}`);\n _onauth = null;\n baseEoseTimeout = 4400;\n connectionTimeout = 4400;\n publishTimeout = 4400;\n openSubs = /* @__PURE__ */ new Map();\n connectionTimeoutHandle;\n connectionPromise;\n openCountRequests = /* @__PURE__ */ new Map();\n openEventPublishes = /* @__PURE__ */ new Map();\n ws;\n incomingMessageQueue = new Queue();\n queueRunning = false;\n challenge;\n serial = 0;\n verifyEvent;\n _WebSocket;\n constructor(url, opts) {\n this.url = normalizeURL(url);\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation || WebSocket;\n }\n static async connect(url, opts) {\n const relay = new AbstractRelay(url, opts);\n await relay.connect();\n return relay;\n }\n closeAllSubscriptions(reason) {\n for (let [_, sub] of this.openSubs) {\n sub.close(reason);\n }\n this.openSubs.clear();\n for (let [_, ep] of this.openEventPublishes) {\n ep.reject(new Error(reason));\n }\n this.openEventPublishes.clear();\n for (let [_, cr] of this.openCountRequests) {\n cr.reject(new Error(reason));\n }\n this.openCountRequests.clear();\n }\n get connected() {\n return this._connected;\n }\n async connect() {\n if (this.connectionPromise)\n return this.connectionPromise;\n this.challenge = void 0;\n this.connectionPromise = new Promise((resolve, reject) => {\n this.connectionTimeoutHandle = setTimeout(() => {\n reject(\"connection timed out\");\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection timed out\");\n }, this.connectionTimeout);\n try {\n this.ws = new this._WebSocket(this.url);\n } catch (err) {\n reject(err);\n return;\n }\n this.ws.onopen = () => {\n clearTimeout(this.connectionTimeoutHandle);\n this._connected = true;\n resolve();\n };\n this.ws.onerror = (ev) => {\n reject(ev.message || \"websocket error\");\n if (this._connected) {\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection errored\");\n }\n };\n this.ws.onclose = async () => {\n if (this._connected) {\n this._connected = false;\n this.connectionPromise = void 0;\n this.onclose?.();\n this.closeAllSubscriptions(\"relay connection closed\");\n }\n };\n this.ws.onmessage = this._onmessage.bind(this);\n });\n return this.connectionPromise;\n }\n async runQueue() {\n this.queueRunning = true;\n while (true) {\n if (false === this.handleNext()) {\n break;\n }\n await yieldThread();\n }\n this.queueRunning = false;\n }\n handleNext() {\n const json = this.incomingMessageQueue.dequeue();\n if (!json) {\n return false;\n }\n const subid = getSubscriptionId(json);\n if (subid) {\n const so = this.openSubs.get(subid);\n if (!so) {\n return;\n }\n const id = getHex64(json, \"id\");\n const alreadyHave = so.alreadyHaveEvent?.(id);\n so.receivedEvent?.(this, id);\n if (alreadyHave) {\n return;\n }\n }\n try {\n let data = JSON.parse(json);\n switch (data[0]) {\n case \"EVENT\": {\n const so = this.openSubs.get(data[1]);\n const event = data[2];\n if (this.verifyEvent(event) && matchFilters(so.filters, event)) {\n so.onevent(event);\n }\n return;\n }\n case \"COUNT\": {\n const id = data[1];\n const payload = data[2];\n const cr = this.openCountRequests.get(id);\n if (cr) {\n cr.resolve(payload.count);\n this.openCountRequests.delete(id);\n }\n return;\n }\n case \"EOSE\": {\n const so = this.openSubs.get(data[1]);\n if (!so)\n return;\n so.receivedEose();\n return;\n }\n case \"OK\": {\n const id = data[1];\n const ok = data[2];\n const reason = data[3];\n const ep = this.openEventPublishes.get(id);\n if (ep) {\n if (ok)\n ep.resolve(reason);\n else\n ep.reject(new Error(reason));\n this.openEventPublishes.delete(id);\n }\n return;\n }\n case \"CLOSED\": {\n const id = data[1];\n const so = this.openSubs.get(id);\n if (!so)\n return;\n so.closed = true;\n so.close(data[2]);\n return;\n }\n case \"NOTICE\":\n this.onnotice(data[1]);\n return;\n case \"AUTH\": {\n this.challenge = data[1];\n this._onauth?.(data[1]);\n return;\n }\n }\n } catch (err) {\n return;\n }\n }\n async send(message) {\n if (!this.connectionPromise)\n throw new Error(\"sending on closed connection\");\n this.connectionPromise.then(() => {\n this.ws?.send(message);\n });\n }\n async auth(signAuthEvent) {\n if (!this.challenge)\n throw new Error(\"can't perform auth, no challenge was received\");\n const evt = await signAuthEvent(makeAuthEvent(this.url, this.challenge));\n const ret = new Promise((resolve, reject) => {\n this.openEventPublishes.set(evt.id, { resolve, reject });\n });\n this.send('[\"AUTH\",' + JSON.stringify(evt) + \"]\");\n return ret;\n }\n async publish(event) {\n const ret = new Promise((resolve, reject) => {\n this.openEventPublishes.set(event.id, { resolve, reject });\n });\n this.send('[\"EVENT\",' + JSON.stringify(event) + \"]\");\n setTimeout(() => {\n const ep = this.openEventPublishes.get(event.id);\n if (ep) {\n ep.reject(new Error(\"publish timed out\"));\n this.openEventPublishes.delete(event.id);\n }\n }, this.publishTimeout);\n return ret;\n }\n async count(filters, params) {\n this.serial++;\n const id = params?.id || \"count:\" + this.serial;\n const ret = new Promise((resolve, reject) => {\n this.openCountRequests.set(id, { resolve, reject });\n });\n this.send('[\"COUNT\",\"' + id + '\",' + JSON.stringify(filters).substring(1));\n return ret;\n }\n subscribe(filters, params) {\n const subscription = this.prepareSubscription(filters, params);\n subscription.fire();\n return subscription;\n }\n prepareSubscription(filters, params) {\n this.serial++;\n const id = params.id || \"sub:\" + this.serial;\n const subscription = new Subscription(this, id, filters, params);\n this.openSubs.set(id, subscription);\n return subscription;\n }\n close() {\n this.closeAllSubscriptions(\"relay connection closed by us\");\n this._connected = false;\n this.ws?.close();\n }\n _onmessage(ev) {\n this.incomingMessageQueue.enqueue(ev.data);\n if (!this.queueRunning) {\n this.runQueue();\n }\n }\n};\nvar Subscription = class {\n relay;\n id;\n closed = false;\n eosed = false;\n filters;\n alreadyHaveEvent;\n receivedEvent;\n onevent;\n oneose;\n onclose;\n eoseTimeout;\n eoseTimeoutHandle;\n constructor(relay, id, filters, params) {\n this.relay = relay;\n this.filters = filters;\n this.id = id;\n this.alreadyHaveEvent = params.alreadyHaveEvent;\n this.receivedEvent = params.receivedEvent;\n this.eoseTimeout = params.eoseTimeout || relay.baseEoseTimeout;\n this.oneose = params.oneose;\n this.onclose = params.onclose;\n this.onevent = params.onevent || ((event) => {\n console.warn(\n `onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,\n event\n );\n });\n }\n fire() {\n this.relay.send('[\"REQ\",\"' + this.id + '\",' + JSON.stringify(this.filters).substring(1));\n this.eoseTimeoutHandle = setTimeout(this.receivedEose.bind(this), this.eoseTimeout);\n }\n receivedEose() {\n if (this.eosed)\n return;\n clearTimeout(this.eoseTimeoutHandle);\n this.eosed = true;\n this.oneose?.();\n }\n close(reason = \"closed by caller\") {\n if (!this.closed && this.relay.connected) {\n this.relay.send('[\"CLOSE\",' + JSON.stringify(this.id) + \"]\");\n this.closed = true;\n }\n this.relay.openSubs.delete(this.id);\n this.onclose?.(reason);\n }\n};\n\n// abstract-pool.ts\nvar AbstractSimplePool = class {\n relays = /* @__PURE__ */ new Map();\n seenOn = /* @__PURE__ */ new Map();\n trackRelays = false;\n verifyEvent;\n trustedRelayURLs = /* @__PURE__ */ new Set();\n _WebSocket;\n constructor(opts) {\n this.verifyEvent = opts.verifyEvent;\n this._WebSocket = opts.websocketImplementation;\n }\n async ensureRelay(url, params) {\n url = normalizeURL(url);\n let relay = this.relays.get(url);\n if (!relay) {\n relay = new AbstractRelay(url, {\n verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,\n websocketImplementation: this._WebSocket\n });\n if (params?.connectionTimeout)\n relay.connectionTimeout = params.connectionTimeout;\n this.relays.set(url, relay);\n }\n await relay.connect();\n return relay;\n }\n close(relays) {\n relays.map(normalizeURL).forEach((url) => {\n this.relays.get(url)?.close();\n });\n }\n subscribeMany(relays, filters, params) {\n return this.subscribeManyMap(Object.fromEntries(relays.map((url) => [url, filters])), params);\n }\n subscribeManyMap(requests, params) {\n if (this.trackRelays) {\n params.receivedEvent = (relay, id) => {\n let set = this.seenOn.get(id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(id, set);\n }\n set.add(relay);\n };\n }\n const _knownIds = /* @__PURE__ */ new Set();\n const subs = [];\n const relaysLength = Object.keys(requests).length;\n const eosesReceived = [];\n let handleEose = (i2) => {\n eosesReceived[i2] = true;\n if (eosesReceived.filter((a) => a).length === relaysLength) {\n params.oneose?.();\n handleEose = () => {\n };\n }\n };\n const closesReceived = [];\n let handleClose = (i2, reason) => {\n handleEose(i2);\n closesReceived[i2] = reason;\n if (closesReceived.filter((a) => a).length === relaysLength) {\n params.onclose?.(closesReceived);\n handleClose = () => {\n };\n }\n };\n const localAlreadyHaveEventHandler = (id) => {\n if (params.alreadyHaveEvent?.(id)) {\n return true;\n }\n const have = _knownIds.has(id);\n _knownIds.add(id);\n return have;\n };\n const allOpened = Promise.all(\n Object.entries(requests).map(async (req, i2, arr) => {\n if (arr.indexOf(req) !== i2) {\n handleClose(i2, \"duplicate url\");\n return;\n }\n let [url, filters] = req;\n url = normalizeURL(url);\n let relay;\n try {\n relay = await this.ensureRelay(url, {\n connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : void 0\n });\n } catch (err) {\n handleClose(i2, err?.message || String(err));\n return;\n }\n let subscription = relay.subscribe(filters, {\n ...params,\n oneose: () => handleEose(i2),\n onclose: (reason) => handleClose(i2, reason),\n alreadyHaveEvent: localAlreadyHaveEventHandler,\n eoseTimeout: params.maxWait\n });\n subs.push(subscription);\n })\n );\n return {\n async close() {\n await allOpened;\n subs.forEach((sub) => {\n sub.close();\n });\n }\n };\n }\n subscribeManyEose(relays, filters, params) {\n const subcloser = this.subscribeMany(relays, filters, {\n ...params,\n oneose() {\n subcloser.close();\n }\n });\n return subcloser;\n }\n async querySync(relays, filter, params) {\n return new Promise(async (resolve) => {\n const events = [];\n this.subscribeManyEose(relays, [filter], {\n ...params,\n onevent(event) {\n events.push(event);\n },\n onclose(_) {\n resolve(events);\n }\n });\n });\n }\n async get(relays, filter, params) {\n filter.limit = 1;\n const events = await this.querySync(relays, filter, params);\n events.sort((a, b) => b.created_at - a.created_at);\n return events[0] || null;\n }\n publish(relays, event) {\n return relays.map(normalizeURL).map(async (url, i2, arr) => {\n if (arr.indexOf(url) !== i2) {\n return Promise.reject(\"duplicate url\");\n }\n let r = await this.ensureRelay(url);\n return r.publish(event).then((reason) => {\n if (this.trackRelays) {\n let set = this.seenOn.get(event.id);\n if (!set) {\n set = /* @__PURE__ */ new Set();\n this.seenOn.set(event.id, set);\n }\n set.add(r);\n }\n return reason;\n });\n });\n }\n listConnectionStatus() {\n const map = /* @__PURE__ */ new Map();\n this.relays.forEach((relay, url) => map.set(url, relay.connected));\n return map;\n }\n destroy() {\n this.relays.forEach((conn) => conn.close());\n this.relays = /* @__PURE__ */ new Map();\n }\n};\n\n// pool.ts\nvar _WebSocket;\ntry {\n _WebSocket = WebSocket;\n} catch {\n}\nfunction useWebSocketImplementation(websocketImplementation) {\n _WebSocket = websocketImplementation;\n}\nvar SimplePool = class extends AbstractSimplePool {\n constructor() {\n super({ verifyEvent, websocketImplementation: _WebSocket });\n }\n};\nexport {\n AbstractSimplePool,\n SimplePool,\n useWebSocketImplementation\n};\n", "import { template as _$template } from \"solid-js/web\";\nimport { delegateEvents as _$delegateEvents } from \"solid-js/web\";\nimport { classList as _$classList } from \"solid-js/web\";\nimport { use as _$use } from \"solid-js/web\";\nimport { getOwner as _$getOwner } from \"solid-js/web\";\nimport { memo as _$memo } from \"solid-js/web\";\nimport { setAttribute as _$setAttribute } from \"solid-js/web\";\nimport { effect as _$effect } from \"solid-js/web\";\nimport { createComponent as _$createComponent } from \"solid-js/web\";\nimport { insert as _$insert } from \"solid-js/web\";\nvar _tmpl$ = /*#__PURE__*/_$template(``),\n _tmpl$2 = /*#__PURE__*/_$template(`

`),\n _tmpl$3 = /*#__PURE__*/_$template(`

`),\n _tmpl$4 = /*#__PURE__*/_$template(`