@zxcvbn-ts_core.js 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. import {
  2. __pow,
  3. __spreadProps,
  4. __spreadValues,
  5. init_define_APP_INFO
  6. } from "./chunk-XY75H3MP.js";
  7. // dep:@zxcvbn-ts_core
  8. init_define_APP_INFO();
  9. // node_modules/@zxcvbn-ts/core/dist/index.esm.js
  10. init_define_APP_INFO();
  11. // node_modules/@zxcvbn-ts/core/dist/Matching.esm.js
  12. init_define_APP_INFO();
  13. // node_modules/@zxcvbn-ts/core/dist/helper.esm.js
  14. init_define_APP_INFO();
  15. var empty = (obj) => Object.keys(obj).length === 0;
  16. var extend = (listToExtend, list) => listToExtend.push.apply(listToExtend, list);
  17. var translate = (string, chrMap) => {
  18. const tempArray = string.split("");
  19. return tempArray.map((char) => chrMap[char] || char).join("");
  20. };
  21. var sorted = (matches) => matches.sort((m1, m2) => m1.i - m2.i || m1.j - m2.j);
  22. var buildRankedDictionary = (orderedList) => {
  23. const result = {};
  24. let counter = 1;
  25. orderedList.forEach((word) => {
  26. result[word] = counter;
  27. counter += 1;
  28. });
  29. return result;
  30. };
  31. // node_modules/@zxcvbn-ts/core/dist/matcher/date/matching.esm.js
  32. init_define_APP_INFO();
  33. // node_modules/@zxcvbn-ts/core/dist/data/const.esm.js
  34. init_define_APP_INFO();
  35. // node_modules/@zxcvbn-ts/core/dist/data/dateSplits.esm.js
  36. init_define_APP_INFO();
  37. var dateSplits = {
  38. 4: [[1, 2], [2, 3]],
  39. 5: [[1, 3], [2, 3]],
  40. 6: [[1, 2], [2, 4], [4, 5]],
  41. 7: [[1, 3], [2, 3], [4, 5], [4, 6]],
  42. 8: [[2, 4], [4, 6]]
  43. };
  44. // node_modules/@zxcvbn-ts/core/dist/data/const.esm.js
  45. var DATE_MAX_YEAR = 2050;
  46. var DATE_MIN_YEAR = 1e3;
  47. var DATE_SPLITS = dateSplits;
  48. var BRUTEFORCE_CARDINALITY = 10;
  49. var MIN_GUESSES_BEFORE_GROWING_SEQUENCE = 1e4;
  50. var MIN_SUBMATCH_GUESSES_SINGLE_CHAR = 10;
  51. var MIN_SUBMATCH_GUESSES_MULTI_CHAR = 50;
  52. var MIN_YEAR_SPACE = 20;
  53. var START_UPPER = /^[A-Z\xbf-\xdf][^A-Z\xbf-\xdf]+$/;
  54. var END_UPPER = /^[^A-Z\xbf-\xdf]+[A-Z\xbf-\xdf]$/;
  55. var ALL_UPPER = /^[A-Z\xbf-\xdf]+$/;
  56. var ALL_UPPER_INVERTED = /^[^a-z\xdf-\xff]+$/;
  57. var ALL_LOWER = /^[a-z\xdf-\xff]+$/;
  58. var ALL_LOWER_INVERTED = /^[^A-Z\xbf-\xdf]+$/;
  59. var ONE_UPPER = /[a-z\xdf-\xff]/;
  60. var ONE_LOWER = /[A-Z\xbf-\xdf]/;
  61. var ALPHA_INVERTED = /[^A-Za-z\xbf-\xdf]/gi;
  62. var ALL_DIGIT = /^\d+$/;
  63. var REFERENCE_YEAR = new Date().getFullYear();
  64. var REGEXEN = {
  65. recentYear: /19\d\d|200\d|201\d|202\d/g
  66. };
  67. // node_modules/@zxcvbn-ts/core/dist/matcher/date/matching.esm.js
  68. var MatchDate = class {
  69. match({
  70. password
  71. }) {
  72. const matches = [...this.getMatchesWithoutSeparator(password), ...this.getMatchesWithSeparator(password)];
  73. const filteredMatches = this.filterNoise(matches);
  74. return sorted(filteredMatches);
  75. }
  76. getMatchesWithSeparator(password) {
  77. const matches = [];
  78. const maybeDateWithSeparator = /^(\d{1,4})([\s/\\_.-])(\d{1,2})\2(\d{1,4})$/;
  79. for (let i = 0; i <= Math.abs(password.length - 6); i += 1) {
  80. for (let j = i + 5; j <= i + 9; j += 1) {
  81. if (j >= password.length) {
  82. break;
  83. }
  84. const token = password.slice(i, +j + 1 || 9e9);
  85. const regexMatch = maybeDateWithSeparator.exec(token);
  86. if (regexMatch != null) {
  87. const dmy = this.mapIntegersToDayMonthYear([parseInt(regexMatch[1], 10), parseInt(regexMatch[3], 10), parseInt(regexMatch[4], 10)]);
  88. if (dmy != null) {
  89. matches.push({
  90. pattern: "date",
  91. token,
  92. i,
  93. j,
  94. separator: regexMatch[2],
  95. year: dmy.year,
  96. month: dmy.month,
  97. day: dmy.day
  98. });
  99. }
  100. }
  101. }
  102. }
  103. return matches;
  104. }
  105. getMatchesWithoutSeparator(password) {
  106. const matches = [];
  107. const maybeDateNoSeparator = /^\d{4,8}$/;
  108. const metric = (candidate) => Math.abs(candidate.year - REFERENCE_YEAR);
  109. for (let i = 0; i <= Math.abs(password.length - 4); i += 1) {
  110. for (let j = i + 3; j <= i + 7; j += 1) {
  111. if (j >= password.length) {
  112. break;
  113. }
  114. const token = password.slice(i, +j + 1 || 9e9);
  115. if (maybeDateNoSeparator.exec(token)) {
  116. const candidates = [];
  117. const index = token.length;
  118. const splittedDates = DATE_SPLITS[index];
  119. splittedDates.forEach(([k, l]) => {
  120. const dmy = this.mapIntegersToDayMonthYear([parseInt(token.slice(0, k), 10), parseInt(token.slice(k, l), 10), parseInt(token.slice(l), 10)]);
  121. if (dmy != null) {
  122. candidates.push(dmy);
  123. }
  124. });
  125. if (candidates.length > 0) {
  126. let bestCandidate = candidates[0];
  127. let minDistance = metric(candidates[0]);
  128. candidates.slice(1).forEach((candidate) => {
  129. const distance = metric(candidate);
  130. if (distance < minDistance) {
  131. bestCandidate = candidate;
  132. minDistance = distance;
  133. }
  134. });
  135. matches.push({
  136. pattern: "date",
  137. token,
  138. i,
  139. j,
  140. separator: "",
  141. year: bestCandidate.year,
  142. month: bestCandidate.month,
  143. day: bestCandidate.day
  144. });
  145. }
  146. }
  147. }
  148. }
  149. return matches;
  150. }
  151. filterNoise(matches) {
  152. return matches.filter((match) => {
  153. let isSubmatch = false;
  154. const matchesLength = matches.length;
  155. for (let o = 0; o < matchesLength; o += 1) {
  156. const otherMatch = matches[o];
  157. if (match !== otherMatch) {
  158. if (otherMatch.i <= match.i && otherMatch.j >= match.j) {
  159. isSubmatch = true;
  160. break;
  161. }
  162. }
  163. }
  164. return !isSubmatch;
  165. });
  166. }
  167. mapIntegersToDayMonthYear(integers) {
  168. if (integers[1] > 31 || integers[1] <= 0) {
  169. return null;
  170. }
  171. let over12 = 0;
  172. let over31 = 0;
  173. let under1 = 0;
  174. for (let o = 0, len1 = integers.length; o < len1; o += 1) {
  175. const int = integers[o];
  176. if (int > 99 && int < DATE_MIN_YEAR || int > DATE_MAX_YEAR) {
  177. return null;
  178. }
  179. if (int > 31) {
  180. over31 += 1;
  181. }
  182. if (int > 12) {
  183. over12 += 1;
  184. }
  185. if (int <= 0) {
  186. under1 += 1;
  187. }
  188. }
  189. if (over31 >= 2 || over12 === 3 || under1 >= 2) {
  190. return null;
  191. }
  192. return this.getDayMonth(integers);
  193. }
  194. getDayMonth(integers) {
  195. const possibleYearSplits = [
  196. [integers[2], integers.slice(0, 2)],
  197. [integers[0], integers.slice(1, 3)]
  198. ];
  199. const possibleYearSplitsLength = possibleYearSplits.length;
  200. for (let j = 0; j < possibleYearSplitsLength; j += 1) {
  201. const [y, rest] = possibleYearSplits[j];
  202. if (DATE_MIN_YEAR <= y && y <= DATE_MAX_YEAR) {
  203. const dm = this.mapIntegersToDayMonth(rest);
  204. if (dm != null) {
  205. return {
  206. year: y,
  207. month: dm.month,
  208. day: dm.day
  209. };
  210. }
  211. return null;
  212. }
  213. }
  214. for (let k = 0; k < possibleYearSplitsLength; k += 1) {
  215. const [y, rest] = possibleYearSplits[k];
  216. const dm = this.mapIntegersToDayMonth(rest);
  217. if (dm != null) {
  218. return {
  219. year: this.twoToFourDigitYear(y),
  220. month: dm.month,
  221. day: dm.day
  222. };
  223. }
  224. }
  225. return null;
  226. }
  227. mapIntegersToDayMonth(integers) {
  228. const temp = [integers, integers.slice().reverse()];
  229. for (let i = 0; i < temp.length; i += 1) {
  230. const data = temp[i];
  231. const day = data[0];
  232. const month = data[1];
  233. if (day >= 1 && day <= 31 && month >= 1 && month <= 12) {
  234. return {
  235. day,
  236. month
  237. };
  238. }
  239. }
  240. return null;
  241. }
  242. twoToFourDigitYear(year) {
  243. if (year > 99) {
  244. return year;
  245. }
  246. if (year > 50) {
  247. return year + 1900;
  248. }
  249. return year + 2e3;
  250. }
  251. };
  252. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/matching.esm.js
  253. init_define_APP_INFO();
  254. // node_modules/@zxcvbn-ts/core/dist/Options.esm.js
  255. init_define_APP_INFO();
  256. // node_modules/@zxcvbn-ts/core/dist/data/l33tTable.esm.js
  257. init_define_APP_INFO();
  258. var l33tTable = {
  259. a: ["4", "@"],
  260. b: ["8"],
  261. c: ["(", "{", "[", "<"],
  262. e: ["3"],
  263. g: ["6", "9"],
  264. i: ["1", "!", "|"],
  265. l: ["1", "|", "7"],
  266. o: ["0"],
  267. s: ["$", "5"],
  268. t: ["+", "7"],
  269. x: ["%"],
  270. z: ["2"]
  271. };
  272. // node_modules/@zxcvbn-ts/core/dist/data/translationKeys.esm.js
  273. init_define_APP_INFO();
  274. var translationKeys = {
  275. warnings: {
  276. straightRow: "straightRow",
  277. keyPattern: "keyPattern",
  278. simpleRepeat: "simpleRepeat",
  279. extendedRepeat: "extendedRepeat",
  280. sequences: "sequences",
  281. recentYears: "recentYears",
  282. dates: "dates",
  283. topTen: "topTen",
  284. topHundred: "topHundred",
  285. common: "common",
  286. similarToCommon: "similarToCommon",
  287. wordByItself: "wordByItself",
  288. namesByThemselves: "namesByThemselves",
  289. commonNames: "commonNames",
  290. userInputs: "userInputs"
  291. },
  292. suggestions: {
  293. l33t: "l33t",
  294. reverseWords: "reverseWords",
  295. allUppercase: "allUppercase",
  296. capitalization: "capitalization",
  297. dates: "dates",
  298. recentYears: "recentYears",
  299. associatedYears: "associatedYears",
  300. sequences: "sequences",
  301. repeated: "repeated",
  302. longerKeyboardPattern: "longerKeyboardPattern",
  303. anotherWord: "anotherWord",
  304. useWords: "useWords",
  305. noNeed: "noNeed"
  306. },
  307. timeEstimation: {
  308. ltSecond: "ltSecond",
  309. second: "second",
  310. seconds: "seconds",
  311. minute: "minute",
  312. minutes: "minutes",
  313. hour: "hour",
  314. hours: "hours",
  315. day: "day",
  316. days: "days",
  317. month: "month",
  318. months: "months",
  319. year: "year",
  320. years: "years",
  321. centuries: "centuries"
  322. }
  323. };
  324. // node_modules/@zxcvbn-ts/core/dist/Options.esm.js
  325. var Options = class {
  326. constructor() {
  327. this.matchers = {};
  328. this.l33tTable = l33tTable;
  329. this.dictionary = {
  330. userInputs: []
  331. };
  332. this.rankedDictionaries = {};
  333. this.translations = translationKeys;
  334. this.graphs = {};
  335. this.availableGraphs = [];
  336. this.setRankedDictionaries();
  337. }
  338. setOptions(options = {}) {
  339. if (options.l33tTable) {
  340. this.l33tTable = options.l33tTable;
  341. }
  342. if (options.dictionary) {
  343. this.dictionary = options.dictionary;
  344. this.setRankedDictionaries();
  345. }
  346. if (options.translations) {
  347. this.setTranslations(options.translations);
  348. }
  349. if (options.graphs) {
  350. this.graphs = options.graphs;
  351. }
  352. }
  353. setTranslations(translations) {
  354. if (this.checkCustomTranslations(translations)) {
  355. this.translations = translations;
  356. } else {
  357. throw new Error("Invalid translations object fallback to keys");
  358. }
  359. }
  360. checkCustomTranslations(translations) {
  361. let valid = true;
  362. Object.keys(translationKeys).forEach((type) => {
  363. if (type in translations) {
  364. const translationType = type;
  365. Object.keys(translationKeys[translationType]).forEach((key) => {
  366. if (!(key in translations[translationType])) {
  367. valid = false;
  368. }
  369. });
  370. } else {
  371. valid = false;
  372. }
  373. });
  374. return valid;
  375. }
  376. setRankedDictionaries() {
  377. const rankedDictionaries = {};
  378. Object.keys(this.dictionary).forEach((name) => {
  379. rankedDictionaries[name] = this.getRankedDictionary(name);
  380. });
  381. this.rankedDictionaries = rankedDictionaries;
  382. }
  383. getRankedDictionary(name) {
  384. const list = this.dictionary[name];
  385. if (name === "userInputs") {
  386. const sanitizedInputs = [];
  387. list.forEach((input) => {
  388. const inputType = typeof input;
  389. if (inputType === "string" || inputType === "number" || inputType === "boolean") {
  390. sanitizedInputs.push(input.toString().toLowerCase());
  391. }
  392. });
  393. return buildRankedDictionary(sanitizedInputs);
  394. }
  395. return buildRankedDictionary(list);
  396. }
  397. extendUserInputsDictionary(dictionary) {
  398. if (this.dictionary.userInputs) {
  399. this.dictionary.userInputs = [...this.dictionary.userInputs, ...dictionary];
  400. } else {
  401. this.dictionary.userInputs = dictionary;
  402. }
  403. this.rankedDictionaries.userInputs = this.getRankedDictionary("userInputs");
  404. }
  405. addMatcher(name, matcher) {
  406. if (this.matchers[name]) {
  407. console.info("Matcher already exists");
  408. } else {
  409. this.matchers[name] = matcher;
  410. }
  411. }
  412. };
  413. var Options$1 = new Options();
  414. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/matching/reverse.esm.js
  415. init_define_APP_INFO();
  416. var MatchL33t = class {
  417. constructor(defaultMatch) {
  418. this.defaultMatch = defaultMatch;
  419. }
  420. match({
  421. password
  422. }) {
  423. const passwordReversed = password.split("").reverse().join("");
  424. return this.defaultMatch({
  425. password: passwordReversed
  426. }).map((match) => __spreadProps(__spreadValues({}, match), {
  427. token: match.token.split("").reverse().join(""),
  428. reversed: true,
  429. i: password.length - 1 - match.j,
  430. j: password.length - 1 - match.i
  431. }));
  432. }
  433. };
  434. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/matching/l33t.esm.js
  435. init_define_APP_INFO();
  436. var MatchL33t2 = class {
  437. constructor(defaultMatch) {
  438. this.defaultMatch = defaultMatch;
  439. }
  440. match({
  441. password
  442. }) {
  443. const matches = [];
  444. const enumeratedSubs = this.enumerateL33tSubs(this.relevantL33tSubtable(password, Options$1.l33tTable));
  445. for (let i = 0; i < enumeratedSubs.length; i += 1) {
  446. const sub = enumeratedSubs[i];
  447. if (empty(sub)) {
  448. break;
  449. }
  450. const subbedPassword = translate(password, sub);
  451. const matchedDictionary = this.defaultMatch({
  452. password: subbedPassword
  453. });
  454. matchedDictionary.forEach((match) => {
  455. const token = password.slice(match.i, +match.j + 1 || 9e9);
  456. if (token.toLowerCase() !== match.matchedWord) {
  457. const matchSub = {};
  458. Object.keys(sub).forEach((subbedChr) => {
  459. const chr = sub[subbedChr];
  460. if (token.indexOf(subbedChr) !== -1) {
  461. matchSub[subbedChr] = chr;
  462. }
  463. });
  464. const subDisplay = Object.keys(matchSub).map((k) => `${k} -> ${matchSub[k]}`).join(", ");
  465. matches.push(__spreadProps(__spreadValues({}, match), {
  466. l33t: true,
  467. token,
  468. sub: matchSub,
  469. subDisplay
  470. }));
  471. }
  472. });
  473. }
  474. return matches.filter((match) => match.token.length > 1);
  475. }
  476. relevantL33tSubtable(password, table) {
  477. const passwordChars = {};
  478. const subTable = {};
  479. password.split("").forEach((char) => {
  480. passwordChars[char] = true;
  481. });
  482. Object.keys(table).forEach((letter) => {
  483. const subs = table[letter];
  484. const relevantSubs = subs.filter((sub) => sub in passwordChars);
  485. if (relevantSubs.length > 0) {
  486. subTable[letter] = relevantSubs;
  487. }
  488. });
  489. return subTable;
  490. }
  491. enumerateL33tSubs(table) {
  492. const tableKeys = Object.keys(table);
  493. const subs = this.getSubs(tableKeys, [[]], table);
  494. return subs.map((sub) => {
  495. const subDict = {};
  496. sub.forEach(([l33tChr, chr]) => {
  497. subDict[l33tChr] = chr;
  498. });
  499. return subDict;
  500. });
  501. }
  502. getSubs(keys, subs, table) {
  503. if (!keys.length) {
  504. return subs;
  505. }
  506. const firstKey = keys[0];
  507. const restKeys = keys.slice(1);
  508. const nextSubs = [];
  509. table[firstKey].forEach((l33tChr) => {
  510. subs.forEach((sub) => {
  511. let dupL33tIndex = -1;
  512. for (let i = 0; i < sub.length; i += 1) {
  513. if (sub[i][0] === l33tChr) {
  514. dupL33tIndex = i;
  515. break;
  516. }
  517. }
  518. if (dupL33tIndex === -1) {
  519. const subExtension = sub.concat([[l33tChr, firstKey]]);
  520. nextSubs.push(subExtension);
  521. } else {
  522. const subAlternative = sub.slice(0);
  523. subAlternative.splice(dupL33tIndex, 1);
  524. subAlternative.push([l33tChr, firstKey]);
  525. nextSubs.push(sub);
  526. nextSubs.push(subAlternative);
  527. }
  528. });
  529. });
  530. const newSubs = this.dedup(nextSubs);
  531. if (restKeys.length) {
  532. return this.getSubs(restKeys, newSubs, table);
  533. }
  534. return newSubs;
  535. }
  536. dedup(subs) {
  537. const deduped = [];
  538. const members = {};
  539. subs.forEach((sub) => {
  540. const assoc = sub.map((k, index) => [k, index]);
  541. assoc.sort();
  542. const label = assoc.map(([k, v]) => `${k},${v}`).join("-");
  543. if (!(label in members)) {
  544. members[label] = true;
  545. deduped.push(sub);
  546. }
  547. });
  548. return deduped;
  549. }
  550. };
  551. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/matching.esm.js
  552. var MatchDictionary = class {
  553. constructor() {
  554. this.l33t = new MatchL33t2(this.defaultMatch);
  555. this.reverse = new MatchL33t(this.defaultMatch);
  556. }
  557. match({
  558. password
  559. }) {
  560. const matches = [...this.defaultMatch({
  561. password
  562. }), ...this.reverse.match({
  563. password
  564. }), ...this.l33t.match({
  565. password
  566. })];
  567. return sorted(matches);
  568. }
  569. defaultMatch({
  570. password
  571. }) {
  572. const matches = [];
  573. const passwordLength = password.length;
  574. const passwordLower = password.toLowerCase();
  575. Object.keys(Options$1.rankedDictionaries).forEach((dictionaryName) => {
  576. const rankedDict = Options$1.rankedDictionaries[dictionaryName];
  577. for (let i = 0; i < passwordLength; i += 1) {
  578. for (let j = i; j < passwordLength; j += 1) {
  579. if (passwordLower.slice(i, +j + 1 || 9e9) in rankedDict) {
  580. const word = passwordLower.slice(i, +j + 1 || 9e9);
  581. const rank = rankedDict[word];
  582. matches.push({
  583. pattern: "dictionary",
  584. i,
  585. j,
  586. token: password.slice(i, +j + 1 || 9e9),
  587. matchedWord: word,
  588. rank,
  589. dictionaryName,
  590. reversed: false,
  591. l33t: false
  592. });
  593. }
  594. }
  595. }
  596. });
  597. return matches;
  598. }
  599. };
  600. // node_modules/@zxcvbn-ts/core/dist/matcher/regex/matching.esm.js
  601. init_define_APP_INFO();
  602. var MatchRegex = class {
  603. match({
  604. password,
  605. regexes = REGEXEN
  606. }) {
  607. const matches = [];
  608. Object.keys(regexes).forEach((name) => {
  609. const regex = regexes[name];
  610. regex.lastIndex = 0;
  611. const regexMatch = regex.exec(password);
  612. if (regexMatch) {
  613. const token = regexMatch[0];
  614. matches.push({
  615. pattern: "regex",
  616. token,
  617. i: regexMatch.index,
  618. j: regexMatch.index + regexMatch[0].length - 1,
  619. regexName: name,
  620. regexMatch
  621. });
  622. }
  623. });
  624. return sorted(matches);
  625. }
  626. };
  627. // node_modules/@zxcvbn-ts/core/dist/matcher/repeat/matching.esm.js
  628. init_define_APP_INFO();
  629. // node_modules/@zxcvbn-ts/core/dist/scoring/index.esm.js
  630. init_define_APP_INFO();
  631. // node_modules/@zxcvbn-ts/core/dist/scoring/utils.esm.js
  632. init_define_APP_INFO();
  633. var utils = {
  634. nCk(n, k) {
  635. let count = n;
  636. if (k > count) {
  637. return 0;
  638. }
  639. if (k === 0) {
  640. return 1;
  641. }
  642. let coEff = 1;
  643. for (let i = 1; i <= k; i += 1) {
  644. coEff *= count;
  645. coEff /= i;
  646. count -= 1;
  647. }
  648. return coEff;
  649. },
  650. log10(n) {
  651. return Math.log(n) / Math.log(10);
  652. },
  653. log2(n) {
  654. return Math.log(n) / Math.log(2);
  655. },
  656. factorial(num) {
  657. let rval = 1;
  658. for (let i = 2; i <= num; i += 1)
  659. rval *= i;
  660. return rval;
  661. }
  662. };
  663. // node_modules/@zxcvbn-ts/core/dist/scoring/estimate.esm.js
  664. init_define_APP_INFO();
  665. // node_modules/@zxcvbn-ts/core/dist/matcher/bruteforce/scoring.esm.js
  666. init_define_APP_INFO();
  667. var bruteforceMatcher = ({
  668. token
  669. }) => {
  670. let guesses = __pow(BRUTEFORCE_CARDINALITY, token.length);
  671. if (guesses === Number.POSITIVE_INFINITY) {
  672. guesses = Number.MAX_VALUE;
  673. }
  674. let minGuesses;
  675. if (token.length === 1) {
  676. minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR + 1;
  677. } else {
  678. minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR + 1;
  679. }
  680. return Math.max(guesses, minGuesses);
  681. };
  682. // node_modules/@zxcvbn-ts/core/dist/matcher/date/scoring.esm.js
  683. init_define_APP_INFO();
  684. var dateMatcher = ({
  685. year,
  686. separator
  687. }) => {
  688. const yearSpace = Math.max(Math.abs(year - REFERENCE_YEAR), MIN_YEAR_SPACE);
  689. let guesses = yearSpace * 365;
  690. if (separator) {
  691. guesses *= 4;
  692. }
  693. return guesses;
  694. };
  695. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/scoring.esm.js
  696. init_define_APP_INFO();
  697. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/scoring/uppercase.esm.js
  698. init_define_APP_INFO();
  699. var getVariations = (cleanedWord) => {
  700. const wordArray = cleanedWord.split("");
  701. const upperCaseCount = wordArray.filter((char) => char.match(ONE_UPPER)).length;
  702. const lowerCaseCount = wordArray.filter((char) => char.match(ONE_LOWER)).length;
  703. let variations = 0;
  704. const variationLength = Math.min(upperCaseCount, lowerCaseCount);
  705. for (let i = 1; i <= variationLength; i += 1) {
  706. variations += utils.nCk(upperCaseCount + lowerCaseCount, i);
  707. }
  708. return variations;
  709. };
  710. var uppercaseVariant = (word) => {
  711. const cleanedWord = word.replace(ALPHA_INVERTED, "");
  712. if (cleanedWord.match(ALL_LOWER_INVERTED) || cleanedWord.toLowerCase() === cleanedWord) {
  713. return 1;
  714. }
  715. const commonCases = [START_UPPER, END_UPPER, ALL_UPPER_INVERTED];
  716. const commonCasesLength = commonCases.length;
  717. for (let i = 0; i < commonCasesLength; i += 1) {
  718. const regex = commonCases[i];
  719. if (cleanedWord.match(regex)) {
  720. return 2;
  721. }
  722. }
  723. return getVariations(cleanedWord);
  724. };
  725. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/scoring/l33t.esm.js
  726. init_define_APP_INFO();
  727. var getCounts = ({
  728. subs,
  729. subbed,
  730. token
  731. }) => {
  732. const unsubbed = subs[subbed];
  733. const chrs = token.toLowerCase().split("");
  734. const subbedCount = chrs.filter((char) => char === subbed).length;
  735. const unsubbedCount = chrs.filter((char) => char === unsubbed).length;
  736. return {
  737. subbedCount,
  738. unsubbedCount
  739. };
  740. };
  741. var l33tVariant = ({
  742. l33t,
  743. sub,
  744. token
  745. }) => {
  746. if (!l33t) {
  747. return 1;
  748. }
  749. let variations = 1;
  750. const subs = sub;
  751. Object.keys(subs).forEach((subbed) => {
  752. const {
  753. subbedCount,
  754. unsubbedCount
  755. } = getCounts({
  756. subs,
  757. subbed,
  758. token
  759. });
  760. if (subbedCount === 0 || unsubbedCount === 0) {
  761. variations *= 2;
  762. } else {
  763. const p = Math.min(unsubbedCount, subbedCount);
  764. let possibilities = 0;
  765. for (let i = 1; i <= p; i += 1) {
  766. possibilities += utils.nCk(unsubbedCount + subbedCount, i);
  767. }
  768. variations *= possibilities;
  769. }
  770. });
  771. return variations;
  772. };
  773. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/scoring.esm.js
  774. var dictionaryMatcher = ({
  775. rank,
  776. reversed,
  777. l33t,
  778. sub,
  779. token
  780. }) => {
  781. const baseGuesses = rank;
  782. const uppercaseVariations = uppercaseVariant(token);
  783. const l33tVariations = l33tVariant({
  784. l33t,
  785. sub,
  786. token
  787. });
  788. const reversedVariations = reversed && 2 || 1;
  789. const calculation = baseGuesses * uppercaseVariations * l33tVariations * reversedVariations;
  790. return {
  791. baseGuesses,
  792. uppercaseVariations,
  793. l33tVariations,
  794. calculation
  795. };
  796. };
  797. // node_modules/@zxcvbn-ts/core/dist/matcher/regex/scoring.esm.js
  798. init_define_APP_INFO();
  799. var regexMatcher = ({
  800. regexName,
  801. regexMatch,
  802. token
  803. }) => {
  804. const charClassBases = {
  805. alphaLower: 26,
  806. alphaUpper: 26,
  807. alpha: 52,
  808. alphanumeric: 62,
  809. digits: 10,
  810. symbols: 33
  811. };
  812. if (regexName in charClassBases) {
  813. return __pow(charClassBases[regexName], token.length);
  814. }
  815. switch (regexName) {
  816. case "recentYear":
  817. return Math.max(Math.abs(parseInt(regexMatch[0], 10) - REFERENCE_YEAR), MIN_YEAR_SPACE);
  818. }
  819. return 0;
  820. };
  821. // node_modules/@zxcvbn-ts/core/dist/matcher/repeat/scoring.esm.js
  822. init_define_APP_INFO();
  823. var repeatMatcher = ({
  824. baseGuesses,
  825. repeatCount
  826. }) => baseGuesses * repeatCount;
  827. // node_modules/@zxcvbn-ts/core/dist/matcher/sequence/scoring.esm.js
  828. init_define_APP_INFO();
  829. var sequenceMatcher = ({
  830. token,
  831. ascending
  832. }) => {
  833. const firstChr = token.charAt(0);
  834. let baseGuesses = 0;
  835. const startingPoints = ["a", "A", "z", "Z", "0", "1", "9"];
  836. if (startingPoints.includes(firstChr)) {
  837. baseGuesses = 4;
  838. } else if (firstChr.match(/\d/)) {
  839. baseGuesses = 10;
  840. } else {
  841. baseGuesses = 26;
  842. }
  843. if (!ascending) {
  844. baseGuesses *= 2;
  845. }
  846. return baseGuesses * token.length;
  847. };
  848. // node_modules/@zxcvbn-ts/core/dist/matcher/spatial/scoring.esm.js
  849. init_define_APP_INFO();
  850. var calcAverageDegree = (graph) => {
  851. let average = 0;
  852. Object.keys(graph).forEach((key) => {
  853. const neighbors = graph[key];
  854. average += neighbors.filter((entry) => !!entry).length;
  855. });
  856. average /= Object.entries(graph).length;
  857. return average;
  858. };
  859. var estimatePossiblePatterns = ({
  860. token,
  861. graph,
  862. turns
  863. }) => {
  864. const startingPosition = Object.keys(Options$1.graphs[graph]).length;
  865. const averageDegree = calcAverageDegree(Options$1.graphs[graph]);
  866. let guesses = 0;
  867. const tokenLength = token.length;
  868. for (let i = 2; i <= tokenLength; i += 1) {
  869. const possibleTurns = Math.min(turns, i - 1);
  870. for (let j = 1; j <= possibleTurns; j += 1) {
  871. guesses += utils.nCk(i - 1, j - 1) * startingPosition * __pow(averageDegree, j);
  872. }
  873. }
  874. return guesses;
  875. };
  876. var spatialMatcher = ({
  877. graph,
  878. token,
  879. shiftedCount,
  880. turns
  881. }) => {
  882. let guesses = estimatePossiblePatterns({
  883. token,
  884. graph,
  885. turns
  886. });
  887. if (shiftedCount) {
  888. const unShiftedCount = token.length - shiftedCount;
  889. if (shiftedCount === 0 || unShiftedCount === 0) {
  890. guesses *= 2;
  891. } else {
  892. let shiftedVariations = 0;
  893. for (let i = 1; i <= Math.min(shiftedCount, unShiftedCount); i += 1) {
  894. shiftedVariations += utils.nCk(shiftedCount + unShiftedCount, i);
  895. }
  896. guesses *= shiftedVariations;
  897. }
  898. }
  899. return Math.round(guesses);
  900. };
  901. // node_modules/@zxcvbn-ts/core/dist/scoring/estimate.esm.js
  902. var getMinGuesses = (match, password) => {
  903. let minGuesses = 1;
  904. if (match.token.length < password.length) {
  905. if (match.token.length === 1) {
  906. minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR;
  907. } else {
  908. minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR;
  909. }
  910. }
  911. return minGuesses;
  912. };
  913. var matchers = {
  914. bruteforce: bruteforceMatcher,
  915. date: dateMatcher,
  916. dictionary: dictionaryMatcher,
  917. regex: regexMatcher,
  918. repeat: repeatMatcher,
  919. sequence: sequenceMatcher,
  920. spatial: spatialMatcher
  921. };
  922. var getScoring = (name, match) => {
  923. if (matchers[name]) {
  924. return matchers[name](match);
  925. }
  926. if (Options$1.matchers[name] && "scoring" in Options$1.matchers[name]) {
  927. return Options$1.matchers[name].scoring(match);
  928. }
  929. return 0;
  930. };
  931. var estimateGuesses = (match, password) => {
  932. const extraData = {};
  933. if ("guesses" in match && match.guesses != null) {
  934. return match;
  935. }
  936. const minGuesses = getMinGuesses(match, password);
  937. const estimationResult = getScoring(match.pattern, match);
  938. let guesses = 0;
  939. if (typeof estimationResult === "number") {
  940. guesses = estimationResult;
  941. } else if (match.pattern === "dictionary") {
  942. guesses = estimationResult.calculation;
  943. extraData.baseGuesses = estimationResult.baseGuesses;
  944. extraData.uppercaseVariations = estimationResult.uppercaseVariations;
  945. extraData.l33tVariations = estimationResult.l33tVariations;
  946. }
  947. const matchGuesses = Math.max(guesses, minGuesses);
  948. return __spreadProps(__spreadValues(__spreadValues({}, match), extraData), {
  949. guesses: matchGuesses,
  950. guessesLog10: utils.log10(matchGuesses)
  951. });
  952. };
  953. // node_modules/@zxcvbn-ts/core/dist/scoring/index.esm.js
  954. var scoringHelper = {
  955. password: "",
  956. optimal: {},
  957. excludeAdditive: false,
  958. fillArray(size, valueType) {
  959. const result = [];
  960. for (let i = 0; i < size; i += 1) {
  961. let value = [];
  962. if (valueType === "object") {
  963. value = {};
  964. }
  965. result.push(value);
  966. }
  967. return result;
  968. },
  969. makeBruteforceMatch(i, j) {
  970. return {
  971. pattern: "bruteforce",
  972. token: this.password.slice(i, +j + 1 || 9e9),
  973. i,
  974. j
  975. };
  976. },
  977. update(match, sequenceLength) {
  978. const k = match.j;
  979. const estimatedMatch = estimateGuesses(match, this.password);
  980. let pi = estimatedMatch.guesses;
  981. if (sequenceLength > 1) {
  982. pi *= this.optimal.pi[estimatedMatch.i - 1][sequenceLength - 1];
  983. }
  984. let g = utils.factorial(sequenceLength) * pi;
  985. if (!this.excludeAdditive) {
  986. g += __pow(MIN_GUESSES_BEFORE_GROWING_SEQUENCE, sequenceLength - 1);
  987. }
  988. let shouldSkip = false;
  989. Object.keys(this.optimal.g[k]).forEach((competingPatternLength) => {
  990. const competingMetricMatch = this.optimal.g[k][competingPatternLength];
  991. if (parseInt(competingPatternLength, 10) <= sequenceLength) {
  992. if (competingMetricMatch <= g) {
  993. shouldSkip = true;
  994. }
  995. }
  996. });
  997. if (!shouldSkip) {
  998. this.optimal.g[k][sequenceLength] = g;
  999. this.optimal.m[k][sequenceLength] = estimatedMatch;
  1000. this.optimal.pi[k][sequenceLength] = pi;
  1001. }
  1002. },
  1003. bruteforceUpdate(passwordCharIndex) {
  1004. let match = this.makeBruteforceMatch(0, passwordCharIndex);
  1005. this.update(match, 1);
  1006. for (let i = 1; i <= passwordCharIndex; i += 1) {
  1007. match = this.makeBruteforceMatch(i, passwordCharIndex);
  1008. const tmp = this.optimal.m[i - 1];
  1009. Object.keys(tmp).forEach((sequenceLength) => {
  1010. const lastMatch = tmp[sequenceLength];
  1011. if (lastMatch.pattern !== "bruteforce") {
  1012. this.update(match, parseInt(sequenceLength, 10) + 1);
  1013. }
  1014. });
  1015. }
  1016. },
  1017. unwind(passwordLength) {
  1018. const optimalMatchSequence = [];
  1019. let k = passwordLength - 1;
  1020. let sequenceLength = 0;
  1021. let g = Infinity;
  1022. const temp = this.optimal.g[k];
  1023. if (temp) {
  1024. Object.keys(temp).forEach((candidateSequenceLength) => {
  1025. const candidateMetricMatch = temp[candidateSequenceLength];
  1026. if (candidateMetricMatch < g) {
  1027. sequenceLength = parseInt(candidateSequenceLength, 10);
  1028. g = candidateMetricMatch;
  1029. }
  1030. });
  1031. }
  1032. while (k >= 0) {
  1033. const match = this.optimal.m[k][sequenceLength];
  1034. optimalMatchSequence.unshift(match);
  1035. k = match.i - 1;
  1036. sequenceLength -= 1;
  1037. }
  1038. return optimalMatchSequence;
  1039. }
  1040. };
  1041. var scoring = {
  1042. mostGuessableMatchSequence(password, matches, excludeAdditive = false) {
  1043. scoringHelper.password = password;
  1044. scoringHelper.excludeAdditive = excludeAdditive;
  1045. const passwordLength = password.length;
  1046. let matchesByCoordinateJ = scoringHelper.fillArray(passwordLength, "array");
  1047. matches.forEach((match) => {
  1048. matchesByCoordinateJ[match.j].push(match);
  1049. });
  1050. matchesByCoordinateJ = matchesByCoordinateJ.map((match) => match.sort((m1, m2) => m1.i - m2.i));
  1051. scoringHelper.optimal = {
  1052. m: scoringHelper.fillArray(passwordLength, "object"),
  1053. pi: scoringHelper.fillArray(passwordLength, "object"),
  1054. g: scoringHelper.fillArray(passwordLength, "object")
  1055. };
  1056. for (let k = 0; k < passwordLength; k += 1) {
  1057. matchesByCoordinateJ[k].forEach((match) => {
  1058. if (match.i > 0) {
  1059. Object.keys(scoringHelper.optimal.m[match.i - 1]).forEach((sequenceLength) => {
  1060. scoringHelper.update(match, parseInt(sequenceLength, 10) + 1);
  1061. });
  1062. } else {
  1063. scoringHelper.update(match, 1);
  1064. }
  1065. });
  1066. scoringHelper.bruteforceUpdate(k);
  1067. }
  1068. const optimalMatchSequence = scoringHelper.unwind(passwordLength);
  1069. const optimalSequenceLength = optimalMatchSequence.length;
  1070. const guesses = this.getGuesses(password, optimalSequenceLength);
  1071. return {
  1072. password,
  1073. guesses,
  1074. guessesLog10: utils.log10(guesses),
  1075. sequence: optimalMatchSequence
  1076. };
  1077. },
  1078. getGuesses(password, optimalSequenceLength) {
  1079. const passwordLength = password.length;
  1080. let guesses = 0;
  1081. if (password.length === 0) {
  1082. guesses = 1;
  1083. } else {
  1084. guesses = scoringHelper.optimal.g[passwordLength - 1][optimalSequenceLength];
  1085. }
  1086. return guesses;
  1087. }
  1088. };
  1089. // node_modules/@zxcvbn-ts/core/dist/matcher/repeat/matching.esm.js
  1090. var MatchRepeat = class {
  1091. match({
  1092. password,
  1093. omniMatch
  1094. }) {
  1095. const matches = [];
  1096. let lastIndex = 0;
  1097. while (lastIndex < password.length) {
  1098. const greedyMatch = this.getGreedyMatch(password, lastIndex);
  1099. const lazyMatch = this.getLazyMatch(password, lastIndex);
  1100. if (greedyMatch == null) {
  1101. break;
  1102. }
  1103. const {
  1104. match,
  1105. baseToken
  1106. } = this.setMatchToken(greedyMatch, lazyMatch);
  1107. if (match) {
  1108. const j = match.index + match[0].length - 1;
  1109. const baseGuesses = this.getBaseGuesses(baseToken, omniMatch);
  1110. matches.push(this.normalizeMatch(baseToken, j, match, baseGuesses));
  1111. lastIndex = j + 1;
  1112. }
  1113. }
  1114. const hasPromises = matches.some((match) => {
  1115. return match instanceof Promise;
  1116. });
  1117. if (hasPromises) {
  1118. return Promise.all(matches);
  1119. }
  1120. return matches;
  1121. }
  1122. normalizeMatch(baseToken, j, match, baseGuesses) {
  1123. const baseMatch = {
  1124. pattern: "repeat",
  1125. i: match.index,
  1126. j,
  1127. token: match[0],
  1128. baseToken,
  1129. baseGuesses: 0,
  1130. repeatCount: match[0].length / baseToken.length
  1131. };
  1132. if (baseGuesses instanceof Promise) {
  1133. return baseGuesses.then((resolvedBaseGuesses) => {
  1134. return __spreadProps(__spreadValues({}, baseMatch), {
  1135. baseGuesses: resolvedBaseGuesses
  1136. });
  1137. });
  1138. }
  1139. return __spreadProps(__spreadValues({}, baseMatch), {
  1140. baseGuesses
  1141. });
  1142. }
  1143. getGreedyMatch(password, lastIndex) {
  1144. const greedy = /(.+)\1+/g;
  1145. greedy.lastIndex = lastIndex;
  1146. return greedy.exec(password);
  1147. }
  1148. getLazyMatch(password, lastIndex) {
  1149. const lazy = /(.+?)\1+/g;
  1150. lazy.lastIndex = lastIndex;
  1151. return lazy.exec(password);
  1152. }
  1153. setMatchToken(greedyMatch, lazyMatch) {
  1154. const lazyAnchored = /^(.+?)\1+$/;
  1155. let match;
  1156. let baseToken = "";
  1157. if (lazyMatch && greedyMatch[0].length > lazyMatch[0].length) {
  1158. match = greedyMatch;
  1159. const temp = lazyAnchored.exec(match[0]);
  1160. if (temp) {
  1161. baseToken = temp[1];
  1162. }
  1163. } else {
  1164. match = lazyMatch;
  1165. if (match) {
  1166. baseToken = match[1];
  1167. }
  1168. }
  1169. return {
  1170. match,
  1171. baseToken
  1172. };
  1173. }
  1174. getBaseGuesses(baseToken, omniMatch) {
  1175. const matches = omniMatch.match(baseToken);
  1176. if (matches instanceof Promise) {
  1177. return matches.then((resolvedMatches) => {
  1178. const baseAnalysis2 = scoring.mostGuessableMatchSequence(baseToken, resolvedMatches);
  1179. return baseAnalysis2.guesses;
  1180. });
  1181. }
  1182. const baseAnalysis = scoring.mostGuessableMatchSequence(baseToken, matches);
  1183. return baseAnalysis.guesses;
  1184. }
  1185. };
  1186. // node_modules/@zxcvbn-ts/core/dist/matcher/sequence/matching.esm.js
  1187. init_define_APP_INFO();
  1188. var MatchSequence = class {
  1189. constructor() {
  1190. this.MAX_DELTA = 5;
  1191. }
  1192. match({
  1193. password
  1194. }) {
  1195. const result = [];
  1196. if (password.length === 1) {
  1197. return [];
  1198. }
  1199. let i = 0;
  1200. let lastDelta = null;
  1201. const passwordLength = password.length;
  1202. for (let k = 1; k < passwordLength; k += 1) {
  1203. const delta = password.charCodeAt(k) - password.charCodeAt(k - 1);
  1204. if (lastDelta == null) {
  1205. lastDelta = delta;
  1206. }
  1207. if (delta !== lastDelta) {
  1208. const j = k - 1;
  1209. this.update({
  1210. i,
  1211. j,
  1212. delta: lastDelta,
  1213. password,
  1214. result
  1215. });
  1216. i = j;
  1217. lastDelta = delta;
  1218. }
  1219. }
  1220. this.update({
  1221. i,
  1222. j: passwordLength - 1,
  1223. delta: lastDelta,
  1224. password,
  1225. result
  1226. });
  1227. return result;
  1228. }
  1229. update({
  1230. i,
  1231. j,
  1232. delta,
  1233. password,
  1234. result
  1235. }) {
  1236. if (j - i > 1 || Math.abs(delta) === 1) {
  1237. const absoluteDelta = Math.abs(delta);
  1238. if (absoluteDelta > 0 && absoluteDelta <= this.MAX_DELTA) {
  1239. const token = password.slice(i, +j + 1 || 9e9);
  1240. const {
  1241. sequenceName,
  1242. sequenceSpace
  1243. } = this.getSequence(token);
  1244. return result.push({
  1245. pattern: "sequence",
  1246. i,
  1247. j,
  1248. token: password.slice(i, +j + 1 || 9e9),
  1249. sequenceName,
  1250. sequenceSpace,
  1251. ascending: delta > 0
  1252. });
  1253. }
  1254. }
  1255. return null;
  1256. }
  1257. getSequence(token) {
  1258. let sequenceName = "unicode";
  1259. let sequenceSpace = 26;
  1260. if (ALL_LOWER.test(token)) {
  1261. sequenceName = "lower";
  1262. sequenceSpace = 26;
  1263. } else if (ALL_UPPER.test(token)) {
  1264. sequenceName = "upper";
  1265. sequenceSpace = 26;
  1266. } else if (ALL_DIGIT.test(token)) {
  1267. sequenceName = "digits";
  1268. sequenceSpace = 10;
  1269. }
  1270. return {
  1271. sequenceName,
  1272. sequenceSpace
  1273. };
  1274. }
  1275. };
  1276. // node_modules/@zxcvbn-ts/core/dist/matcher/spatial/matching.esm.js
  1277. init_define_APP_INFO();
  1278. var MatchSpatial = class {
  1279. constructor() {
  1280. this.SHIFTED_RX = /[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?]/;
  1281. }
  1282. match({
  1283. password
  1284. }) {
  1285. const matches = [];
  1286. Object.keys(Options$1.graphs).forEach((graphName) => {
  1287. const graph = Options$1.graphs[graphName];
  1288. extend(matches, this.helper(password, graph, graphName));
  1289. });
  1290. return sorted(matches);
  1291. }
  1292. checkIfShifted(graphName, password, index) {
  1293. if (!graphName.includes("keypad") && this.SHIFTED_RX.test(password.charAt(index))) {
  1294. return 1;
  1295. }
  1296. return 0;
  1297. }
  1298. helper(password, graph, graphName) {
  1299. let shiftedCount;
  1300. const matches = [];
  1301. let i = 0;
  1302. const passwordLength = password.length;
  1303. while (i < passwordLength - 1) {
  1304. let j = i + 1;
  1305. let lastDirection = 0;
  1306. let turns = 0;
  1307. shiftedCount = this.checkIfShifted(graphName, password, i);
  1308. while (true) {
  1309. const prevChar = password.charAt(j - 1);
  1310. const adjacents = graph[prevChar] || [];
  1311. let found = false;
  1312. let foundDirection = -1;
  1313. let curDirection = -1;
  1314. if (j < passwordLength) {
  1315. const curChar = password.charAt(j);
  1316. const adjacentsLength = adjacents.length;
  1317. for (let k = 0; k < adjacentsLength; k += 1) {
  1318. const adjacent = adjacents[k];
  1319. curDirection += 1;
  1320. if (adjacent) {
  1321. const adjacentIndex = adjacent.indexOf(curChar);
  1322. if (adjacentIndex !== -1) {
  1323. found = true;
  1324. foundDirection = curDirection;
  1325. if (adjacentIndex === 1) {
  1326. shiftedCount += 1;
  1327. }
  1328. if (lastDirection !== foundDirection) {
  1329. turns += 1;
  1330. lastDirection = foundDirection;
  1331. }
  1332. break;
  1333. }
  1334. }
  1335. }
  1336. }
  1337. if (found) {
  1338. j += 1;
  1339. } else {
  1340. if (j - i > 2) {
  1341. matches.push({
  1342. pattern: "spatial",
  1343. i,
  1344. j: j - 1,
  1345. token: password.slice(i, j),
  1346. graph: graphName,
  1347. turns,
  1348. shiftedCount
  1349. });
  1350. }
  1351. i = j;
  1352. break;
  1353. }
  1354. }
  1355. }
  1356. return matches;
  1357. }
  1358. };
  1359. // node_modules/@zxcvbn-ts/core/dist/Matching.esm.js
  1360. var Matching = class {
  1361. constructor() {
  1362. this.matchers = {
  1363. date: MatchDate,
  1364. dictionary: MatchDictionary,
  1365. regex: MatchRegex,
  1366. repeat: MatchRepeat,
  1367. sequence: MatchSequence,
  1368. spatial: MatchSpatial
  1369. };
  1370. }
  1371. match(password) {
  1372. const matches = [];
  1373. const promises = [];
  1374. const matchers2 = [...Object.keys(this.matchers), ...Object.keys(Options$1.matchers)];
  1375. matchers2.forEach((key) => {
  1376. if (!this.matchers[key] && !Options$1.matchers[key]) {
  1377. return;
  1378. }
  1379. const Matcher = this.matchers[key] ? this.matchers[key] : Options$1.matchers[key].Matching;
  1380. const usedMatcher = new Matcher();
  1381. const result = usedMatcher.match({
  1382. password,
  1383. omniMatch: this
  1384. });
  1385. if (result instanceof Promise) {
  1386. result.then((response) => {
  1387. extend(matches, response);
  1388. });
  1389. promises.push(result);
  1390. } else {
  1391. extend(matches, result);
  1392. }
  1393. });
  1394. if (promises.length > 0) {
  1395. return new Promise((resolve) => {
  1396. Promise.all(promises).then(() => {
  1397. resolve(sorted(matches));
  1398. });
  1399. });
  1400. }
  1401. return sorted(matches);
  1402. }
  1403. };
  1404. // node_modules/@zxcvbn-ts/core/dist/TimeEstimates.esm.js
  1405. init_define_APP_INFO();
  1406. var SECOND = 1;
  1407. var MINUTE = SECOND * 60;
  1408. var HOUR = MINUTE * 60;
  1409. var DAY = HOUR * 24;
  1410. var MONTH = DAY * 31;
  1411. var YEAR = MONTH * 12;
  1412. var CENTURY = YEAR * 100;
  1413. var times = {
  1414. second: SECOND,
  1415. minute: MINUTE,
  1416. hour: HOUR,
  1417. day: DAY,
  1418. month: MONTH,
  1419. year: YEAR,
  1420. century: CENTURY
  1421. };
  1422. var TimeEstimates = class {
  1423. translate(displayStr, value) {
  1424. let key = displayStr;
  1425. if (value !== void 0 && value !== 1) {
  1426. key += "s";
  1427. }
  1428. const {
  1429. timeEstimation
  1430. } = Options$1.translations;
  1431. return timeEstimation[key].replace("{base}", `${value}`);
  1432. }
  1433. estimateAttackTimes(guesses) {
  1434. const crackTimesSeconds = {
  1435. onlineThrottling100PerHour: guesses / (100 / 3600),
  1436. onlineNoThrottling10PerSecond: guesses / 10,
  1437. offlineSlowHashing1e4PerSecond: guesses / 1e4,
  1438. offlineFastHashing1e10PerSecond: guesses / 1e10
  1439. };
  1440. const crackTimesDisplay = {
  1441. onlineThrottling100PerHour: "",
  1442. onlineNoThrottling10PerSecond: "",
  1443. offlineSlowHashing1e4PerSecond: "",
  1444. offlineFastHashing1e10PerSecond: ""
  1445. };
  1446. Object.keys(crackTimesSeconds).forEach((scenario) => {
  1447. const seconds = crackTimesSeconds[scenario];
  1448. crackTimesDisplay[scenario] = this.displayTime(seconds);
  1449. });
  1450. return {
  1451. crackTimesSeconds,
  1452. crackTimesDisplay,
  1453. score: this.guessesToScore(guesses)
  1454. };
  1455. }
  1456. guessesToScore(guesses) {
  1457. const DELTA = 5;
  1458. if (guesses < 1e3 + DELTA) {
  1459. return 0;
  1460. }
  1461. if (guesses < 1e6 + DELTA) {
  1462. return 1;
  1463. }
  1464. if (guesses < 1e8 + DELTA) {
  1465. return 2;
  1466. }
  1467. if (guesses < 1e10 + DELTA) {
  1468. return 3;
  1469. }
  1470. return 4;
  1471. }
  1472. displayTime(seconds) {
  1473. let displayStr = "centuries";
  1474. let base;
  1475. const timeKeys = Object.keys(times);
  1476. const foundIndex = timeKeys.findIndex((time2) => seconds < times[time2]);
  1477. if (foundIndex > -1) {
  1478. displayStr = timeKeys[foundIndex - 1];
  1479. if (foundIndex !== 0) {
  1480. base = Math.round(seconds / times[displayStr]);
  1481. } else {
  1482. displayStr = "ltSecond";
  1483. }
  1484. }
  1485. return this.translate(displayStr, base);
  1486. }
  1487. };
  1488. // node_modules/@zxcvbn-ts/core/dist/Feedback.esm.js
  1489. init_define_APP_INFO();
  1490. // node_modules/@zxcvbn-ts/core/dist/matcher/bruteforce/feedback.esm.js
  1491. init_define_APP_INFO();
  1492. var bruteforceMatcher2 = () => {
  1493. return null;
  1494. };
  1495. // node_modules/@zxcvbn-ts/core/dist/matcher/date/feedback.esm.js
  1496. init_define_APP_INFO();
  1497. var dateMatcher2 = () => {
  1498. return {
  1499. warning: Options$1.translations.warnings.dates,
  1500. suggestions: [Options$1.translations.suggestions.dates]
  1501. };
  1502. };
  1503. // node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/feedback.esm.js
  1504. init_define_APP_INFO();
  1505. var getDictionaryWarningPassword = (match, isSoleMatch) => {
  1506. let warning = "";
  1507. if (isSoleMatch && !match.l33t && !match.reversed) {
  1508. if (match.rank <= 10) {
  1509. warning = Options$1.translations.warnings.topTen;
  1510. } else if (match.rank <= 100) {
  1511. warning = Options$1.translations.warnings.topHundred;
  1512. } else {
  1513. warning = Options$1.translations.warnings.common;
  1514. }
  1515. } else if (match.guessesLog10 <= 4) {
  1516. warning = Options$1.translations.warnings.similarToCommon;
  1517. }
  1518. return warning;
  1519. };
  1520. var getDictionaryWarningWikipedia = (match, isSoleMatch) => {
  1521. let warning = "";
  1522. if (isSoleMatch) {
  1523. warning = Options$1.translations.warnings.wordByItself;
  1524. }
  1525. return warning;
  1526. };
  1527. var getDictionaryWarningNames = (match, isSoleMatch) => {
  1528. if (isSoleMatch) {
  1529. return Options$1.translations.warnings.namesByThemselves;
  1530. }
  1531. return Options$1.translations.warnings.commonNames;
  1532. };
  1533. var getDictionaryWarning = (match, isSoleMatch) => {
  1534. let warning = "";
  1535. const dictName = match.dictionaryName;
  1536. const isAName = dictName === "lastnames" || dictName.toLowerCase().includes("firstnames");
  1537. if (dictName === "passwords") {
  1538. warning = getDictionaryWarningPassword(match, isSoleMatch);
  1539. } else if (dictName.includes("wikipedia")) {
  1540. warning = getDictionaryWarningWikipedia(match, isSoleMatch);
  1541. } else if (isAName) {
  1542. warning = getDictionaryWarningNames(match, isSoleMatch);
  1543. } else if (dictName === "userInputs") {
  1544. warning = Options$1.translations.warnings.userInputs;
  1545. }
  1546. return warning;
  1547. };
  1548. var dictionaryMatcher2 = (match, isSoleMatch) => {
  1549. const warning = getDictionaryWarning(match, isSoleMatch);
  1550. const suggestions = [];
  1551. const word = match.token;
  1552. if (word.match(START_UPPER)) {
  1553. suggestions.push(Options$1.translations.suggestions.capitalization);
  1554. } else if (word.match(ALL_UPPER_INVERTED) && word.toLowerCase() !== word) {
  1555. suggestions.push(Options$1.translations.suggestions.allUppercase);
  1556. }
  1557. if (match.reversed && match.token.length >= 4) {
  1558. suggestions.push(Options$1.translations.suggestions.reverseWords);
  1559. }
  1560. if (match.l33t) {
  1561. suggestions.push(Options$1.translations.suggestions.l33t);
  1562. }
  1563. return {
  1564. warning,
  1565. suggestions
  1566. };
  1567. };
  1568. // node_modules/@zxcvbn-ts/core/dist/matcher/regex/feedback.esm.js
  1569. init_define_APP_INFO();
  1570. var regexMatcher2 = (match) => {
  1571. if (match.regexName === "recentYear") {
  1572. return {
  1573. warning: Options$1.translations.warnings.recentYears,
  1574. suggestions: [Options$1.translations.suggestions.recentYears, Options$1.translations.suggestions.associatedYears]
  1575. };
  1576. }
  1577. return {
  1578. warning: "",
  1579. suggestions: []
  1580. };
  1581. };
  1582. // node_modules/@zxcvbn-ts/core/dist/matcher/repeat/feedback.esm.js
  1583. init_define_APP_INFO();
  1584. var repeatMatcher2 = (match) => {
  1585. let warning = Options$1.translations.warnings.extendedRepeat;
  1586. if (match.baseToken.length === 1) {
  1587. warning = Options$1.translations.warnings.simpleRepeat;
  1588. }
  1589. return {
  1590. warning,
  1591. suggestions: [Options$1.translations.suggestions.repeated]
  1592. };
  1593. };
  1594. // node_modules/@zxcvbn-ts/core/dist/matcher/sequence/feedback.esm.js
  1595. init_define_APP_INFO();
  1596. var sequenceMatcher2 = () => {
  1597. return {
  1598. warning: Options$1.translations.warnings.sequences,
  1599. suggestions: [Options$1.translations.suggestions.sequences]
  1600. };
  1601. };
  1602. // node_modules/@zxcvbn-ts/core/dist/matcher/spatial/feedback.esm.js
  1603. init_define_APP_INFO();
  1604. var spatialMatcher2 = (match) => {
  1605. let warning = Options$1.translations.warnings.keyPattern;
  1606. if (match.turns === 1) {
  1607. warning = Options$1.translations.warnings.straightRow;
  1608. }
  1609. return {
  1610. warning,
  1611. suggestions: [Options$1.translations.suggestions.longerKeyboardPattern]
  1612. };
  1613. };
  1614. // node_modules/@zxcvbn-ts/core/dist/Feedback.esm.js
  1615. var defaultFeedback = {
  1616. warning: "",
  1617. suggestions: []
  1618. };
  1619. var Feedback = class {
  1620. constructor() {
  1621. this.matchers = {
  1622. bruteforce: bruteforceMatcher2,
  1623. date: dateMatcher2,
  1624. dictionary: dictionaryMatcher2,
  1625. regex: regexMatcher2,
  1626. repeat: repeatMatcher2,
  1627. sequence: sequenceMatcher2,
  1628. spatial: spatialMatcher2
  1629. };
  1630. this.defaultFeedback = {
  1631. warning: "",
  1632. suggestions: []
  1633. };
  1634. this.setDefaultSuggestions();
  1635. }
  1636. setDefaultSuggestions() {
  1637. this.defaultFeedback.suggestions.push(Options$1.translations.suggestions.useWords, Options$1.translations.suggestions.noNeed);
  1638. }
  1639. getFeedback(score, sequence) {
  1640. if (sequence.length === 0) {
  1641. return this.defaultFeedback;
  1642. }
  1643. if (score > 2) {
  1644. return defaultFeedback;
  1645. }
  1646. const extraFeedback = Options$1.translations.suggestions.anotherWord;
  1647. const longestMatch = this.getLongestMatch(sequence);
  1648. let feedback = this.getMatchFeedback(longestMatch, sequence.length === 1);
  1649. if (feedback !== null && feedback !== void 0) {
  1650. feedback.suggestions.unshift(extraFeedback);
  1651. if (feedback.warning == null) {
  1652. feedback.warning = "";
  1653. }
  1654. } else {
  1655. feedback = {
  1656. warning: "",
  1657. suggestions: [extraFeedback]
  1658. };
  1659. }
  1660. return feedback;
  1661. }
  1662. getLongestMatch(sequence) {
  1663. let longestMatch = sequence[0];
  1664. const slicedSequence = sequence.slice(1);
  1665. slicedSequence.forEach((match) => {
  1666. if (match.token.length > longestMatch.token.length) {
  1667. longestMatch = match;
  1668. }
  1669. });
  1670. return longestMatch;
  1671. }
  1672. getMatchFeedback(match, isSoleMatch) {
  1673. if (this.matchers[match.pattern]) {
  1674. return this.matchers[match.pattern](match, isSoleMatch);
  1675. }
  1676. if (Options$1.matchers[match.pattern] && "feedback" in Options$1.matchers[match.pattern]) {
  1677. return Options$1.matchers[match.pattern].feedback(match, isSoleMatch);
  1678. }
  1679. return defaultFeedback;
  1680. }
  1681. };
  1682. // node_modules/@zxcvbn-ts/core/dist/index.esm.js
  1683. var time = () => new Date().getTime();
  1684. var createReturnValue = (resolvedMatches, password, start) => {
  1685. const feedback = new Feedback();
  1686. const timeEstimates = new TimeEstimates();
  1687. const matchSequence = scoring.mostGuessableMatchSequence(password, resolvedMatches);
  1688. const calcTime = time() - start;
  1689. const attackTimes = timeEstimates.estimateAttackTimes(matchSequence.guesses);
  1690. return __spreadProps(__spreadValues(__spreadValues({
  1691. calcTime
  1692. }, matchSequence), attackTimes), {
  1693. feedback: feedback.getFeedback(attackTimes.score, matchSequence.sequence)
  1694. });
  1695. };
  1696. var zxcvbn = (password, userInputs) => {
  1697. if (userInputs) {
  1698. Options$1.extendUserInputsDictionary(userInputs);
  1699. }
  1700. const matching = new Matching();
  1701. const start = time();
  1702. const matches = matching.match(password);
  1703. if (matches instanceof Promise) {
  1704. return matches.then((resolvedMatches) => {
  1705. return createReturnValue(resolvedMatches, password, start);
  1706. });
  1707. }
  1708. return createReturnValue(matches, password, start);
  1709. };
  1710. export {
  1711. Options$1 as ZxcvbnOptions,
  1712. zxcvbn
  1713. };
  1714. //# sourceMappingURL=@zxcvbn-ts_core.js.map