[{"name":"Rumkin","comment":" This module implements the popular F/OSS password strength check available at [rumkin.com](http://rumkin.com/tools/password/passchk.php). A more detailed description may be found at that link, as well as the rationale behind it.\n\n\n## Usage Notes\n\nThe results returned by this module should be identical to those obtained from the live version of the strength test at [rumkin.com](http://rumkin.com/tools/password/passchk.php). They will, however, differ from the version available as source for download, as there is a bug in which characters in keyboard punctuation \\`~-\\_=+[{]}|;:'\",<.>/?\\\\ contribute an additional sequence space of only 20 instead of the correct 22. As this bug is fixed in the live version, it is fixed in this package as well.\n\n**Warning:** Common password warnings returned by this package are _not_ factored into the overall strength of the password. As such, while a warning of \"Common password!\" will be returned for the password \"raidersofthelostark\", its strength will be `Strong` and its supposed entropy 70.5 bits, despite it being a weak, common password. Consider using `Zxcvbn`/`ZxcvbnPlus` if you require common passwords to impact the overall score and not merely be presented as warnings.\n\nThe computational performance of this library is quite good, with essentially instantaneous results.\n\nWhile it does contain a common word list, the library is relatively light. Sizes for an extremely simple example application follow:\n\n  - Compiled size -- 170 kB\n  - Minified size -- 67 kB\n  - Gzipped size -- 32 kB\n\n\n## Normal Usage\n\nFor normal usage of this module, only the function `getStats` and the returned types `RumkinResult` and `Strength` are necessary.\n\n@docs getStats, RumkinResult, Strength\n\n\n## Custom Usage\n\nThe sequence frequency and common password lists used by this package are compressed and require parsing prior to use. If you wish to control exactly when that happens (and cache it in your model), the following functions are available.\n\n@docs getCustomStats, parseFrequencyList, parseCommonList\n\n","unions":[{"name":"Strength","comment":" The overall strength of the password, along with the string that will be found in `strengthComment`. These do **not** take into account common passwords.\n\n  - `VeryWeak` -- \"Try making your password longer, including CAPITALS, or adding symbols.\"\n  - `Weak` -- \"Usually good enough for computer login passwords and to keep out the average person.\"\n  - `Reasonable` -- \"This password is fairly secure cryptographically and skilled hackers may need some good computing power to crack it. (Depends greatly on implementation!)\"\n  - `Strong` -- \"This password is typically good enough to safely guard sensitive information like financial records.\"\n  - `VeryStrong` -- \"More often than not, this level of security is overkill.\"\n\n","args":[],"cases":[["VeryWeak",[]],["Weak",[]],["Reasonable",[]],["Strong",[]],["VeryStrong",[]]]}],"aliases":[{"name":"RumkinResult","comment":" The results returned by `getStats`, containing the following fields:\n\n  - `warnings` -- A (possible empty) list of printed warnings, suitable for display to the user. If the password is a common one, a warning will be contained in this list, as will warnings about length.\n  - `length` -- The length of the password.\n  - `strength` -- The overall strength of the password, e.g. for display as a growing bar. This does **not** take into account common passwords.\n  - `strengthComment` -- A comment on the strength of the password, suitable for display to the user; a list of the comments is found in the documentation for `Strength`.\n  - `entropy` -- The estimated bits of entropy of the password; this does **not** take into account common passwords, and so the actual entropy is quite possibly considerably lower.\n  - `charsetSize` -- The total sequence space of the password, e.g. \"kjethrsfdsdgf\" would be 26, since it consists solely of lowercase Latin characters. This is _not_ Unicode aware, so it is conservative when outside the \"standard\" range.\n\n","args":[],"type":"{ warnings : List.List String.String, length : Basics.Int, strength : Rumkin.Strength, strengthComment : String.String, entropy : Basics.Float, charsetSize : Basics.Int }"}],"values":[{"name":"getCustomStats","comment":" `getStats` with a provided frequency list and common password list. This may be used to control the point at which parsing these lists is performed or to run the algorithm with custom frequency/password lists.\n","type":"Internal.Rumkin.FrequencyList -> Internal.Rumkin.CommonPasswordList -> String.String -> Rumkin.RumkinResult"},{"name":"getStats","comment":" Given a password, check it for common passwords and score it, returning the result.\n","type":"String.String -> Rumkin.RumkinResult"},{"name":"parseCommonList","comment":" Given a compressed/encoded common password list, try to parse it. In general, this should only be used to parse the list at `Rumkin.Common.commonList`, but it may be used to parse custom common password lists, if they are encoded the same. The description of the common password list encoding follows:\n\nThe compression algorithm is very basic - the first letter is upper case, and it means to copy X letters from the previous word. A = 0, B = 1, etc. So, if I had \"apple apricot banana\", it would compress to \"AappleCricotAbanana\".\n\n","type":"String.String -> Result.Result String.String Internal.Rumkin.CommonPasswordList"},{"name":"parseFrequencyList","comment":" Given a ompressed/encoded sequence frequency list, try to parse it. In general, this should only be used to parse the list at `Rumkin.Frequency.frequencyList`, but it may be used to parse custom frequency lists, if they are encoded the same. The description of the frequency list encoding follows:\n\nThe frequency thing is a bit more interesting, but still not too complex.\nEach three letters are base-95 encoded number representing the chance that\nthis combination comes next. Subtract the value of ' ' from each of the\nthree, then ((((first\\_value \\* 95) + second\\_value) \\* 95) + third\\_value) will\ngive you the odds that this pair is grouped together. The first is \" \"\n(non-alpha chars), then \" a\", \" b\", etc. \" y\", \" z\", \"a \", \"aa\", \"ab\", and\nso on. If you decrypt the table successfully, you should see a really large\nnumber for \"qu\".\n\n","type":"String.String -> Result.Result String.String Internal.Rumkin.FrequencyList"}],"binops":[]},{"name":"Rumkin.Common","comment":" This module should not be needed for typical use of `Rumkin`.\n\n`Rumkin.Common` is a dictionary file used by `Rumkin`. It is adapted from the original source available here at <http://rumkin.com/tools/password/passchk.php>\n\n\n## Common Password List\n\n@docs commonList\n\n","unions":[],"aliases":[],"values":[{"name":"commonList","comment":" A compresed list of common words.\n\nThe compression algorithm is very basic - the first letter is upper case, and it means to copy X letters from the previous word. A = 0, B = 1, etc. So, if I had \"apple apricot banana\", it would compress to \"AappleCricotAbanana\".\n\n","type":"String.String"}],"binops":[]},{"name":"Rumkin.Frequency","comment":" This module should not be needed for typical use of `Rumkin`.\n\n`Rumkin.Frequency` is a lookup table used by `Rumkin`. It is adapted from the original source available here at <http://rumkin.com/tools/password/passchk.php>\n\n\n## Frequency List\n\n@docs frequencyList\n\n","unions":[],"aliases":[],"values":[{"name":"frequencyList","comment":" A compressed and encoded letter frequency table.\n\nThe frequency thing is a bit more interesting, but still not too complex.\nEach three letters are base-95 encoded number representing the chance that\nthis combination comes next. Subtract the value of ' ' from each of the\nthree, then ((((first\\_value \\* 95) + second\\_value) \\* 95) + third\\_value) will\ngive you the odds that this pair is grouped together. The first is \" \"\n(non-alpha chars), then \" a\", \" b\", etc. \" y\", \" z\", \"a \", \"aa\", \"ab\", and\nso on. If you decrypt the table successfully, you should see a really large\nnumber for \"qu\".\n\n","type":"String.String"}],"binops":[]},{"name":"Zxcvbn","comment":" `PasswordStrength.Zxcvbn` is a native Elm implementation of the popular zxcvbn password strength javascript library. You **likely want to use `ZxcvbnPlus` instead**, unless you require exactly identical results to the reference implementation. More information may be found on its [GitHub](https://github.com/dropbox/zxcvbn). The following is excerpted from the README:\n\nzxcvbn is a password strength estimator inspired by password crackers. Through pattern matching and conservative estimation, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats (\"aaa\"), sequences (\"abcd\"), keyboard patterns (\"qwertyuiop\"), and l33t speak.\n\nConsider using zxcvbn as an algorithmic alternative to password composition policy — it is more secure, flexible, and usable when sites require a minimal complexity score in place of annoying rules like \"passwords must contain three of {lower, upper, numbers, symbols}\".\n\n  - **More secure:** policies often fail both ways, allowing weak passwords (\"P@ssword1\") and disallowing strong passwords.\n  - **More flexible:** zxcvbn allows many password styles to flourish so long as it detects sufficient complexity — passphrases are rated highly given enough uncommon words, keyboard patterns are ranked based on length and number of turns, and capitalization adds more complexity when it's unpredictaBle.\n  - **More usable:** zxcvbn is designed to power simple, rule-free interfaces that give instant feedback. In addition to strength estimation, zxcvbn includes minimal, targeted verbal feedback that can help guide users towards less guessable passwords.\n\nFor further detail and motivation, please refer to the USENIX Security '16 [paper and presentation](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler).\n\n\n## Usage Notes\n\nThe results returned by this package should in all cases be exactly identical to those returned by the reference (javascript) implementation, with two exceptions. Firstly, this has updated the recent year regex to include the new decade (as the reference implementation only checked up to `201*`). Secondly, exceedingly difficult to crack passwords may differ; as Elm lacks `Number.MAX_VALUE`, a value of `1.7976931348623157e+308` is used instead, which may differ slightly from `Number.MAX_VALUE`. If you do not require exactly identical results, consider using `ZxcvbnPlus` instead, which is a slightly more optimized and \"Elm\"-y implementation.\n\nThe computational performance of this library is quite good, with essentially instantaneous results for normal length passwords and barely perceptible delays even with ~100-character passwords.\n\nIt should be noted that the zxcvbn library is not \"light\" by any means, given the large dictionaries of common words it requires. Sizes for an extremely simple example application follow:\n\n  - Compiled size -- 3.67 MB\n  - Minified size -- 1.84 MB\n  - Gzipped size -- 693 KB\n\n\n## Known Issues\n\nWith _exceedingly_ difficult to crack passwords, the algorithm may report bruteforce matches as \"more guessable\" than actual matches in the password. This is because the number of possible guesses for bruteforce caps at approximately `10^308` guesses. Since this is truly absurdly large, it should never be problematic in normal use.\n\n\n## Functions\n\nThis package exposes exactly one function, `zxcvbn`, which requires no configuration of any kind and may be simply called with a password (and possible-empty list of additional patterns).\n\n@docs zxcvbn\n\n\n## Result Types\n\nThe sole function in this package returns one relatively complex record containing the full results of the password strength check.\n\n@docs ZxcvbnResult, Feedback, DisplayCrackTimes, NumericCrackTimes\n\n","unions":[],"aliases":[{"name":"DisplayCrackTimes","comment":" Crack times for password in user-friendly format (e.g. \"less than a second\", \"10 years\", etc.) for various cases.\n\n  - `onlineThrottling100PerHour` -- Online attack on a service that ratelimits password auth attempts.\n  - `onlineNoThrottling10PerSecond` -- Online attack on a service that doesn't ratelimit, or where an attacker has outsmarted ratelimiting.\n  - `offlineSlowHashing1e4PerSecond` -- Offline attack. assumes multiple attackers, proper user-unique salting, and a slow hash function w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.\n  - `offlineFastHashing1e10PerSecond` -- Offline attack with user-unique salting but a fast hash function like SHA-1, SHA-256 or MD5. A wide range of reasonable numbers anywhere from one billion - one trillion guesses per second, depending on number of cores and machines. Ballparking at 10B/sec.\n\n","args":[],"type":"{ onlineThrottling100PerHour : String.String, onlineNoThrottling10PerSecond : String.String, offlineSlowHashing1e4PerSecond : String.String, offlineFastHashing1e10PerSecond : String.String }"},{"name":"Feedback","comment":" Contains feedback inteded to be displayed to the user trying to create a password.\n\n  - `warning`: Explains what's wrong, e.g. \"This is a top-10 common password\". Will be empty if no applicable warnings are found.\n  - `suggestion`: A possibly-empty list of suggestions to help choose a less guessable password, e.g. \"Add another word or two\".\n\n","args":[],"type":"{ warning : String.String, suggestions : List.List String.String }"},{"name":"NumericCrackTimes","comment":" Crack times for password in seconds for various cases.\n\n  - `onlineThrottling100PerHour` -- Online attack on a service that ratelimits password auth attempts.\n  - `onlineNoThrottling10PerSecond` -- Online attack on a service that doesn't ratelimit, or where an attacker has outsmarted ratelimiting.\n  - `offlineSlowHashing1e4PerSecond` -- Offline attack. assumes multiple attackers, proper user-unique salting, and a slow hash function w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.\n  - `offlineFastHashing1e10PerSecond` -- Offline attack with user-unique salting but a fast hash function like SHA-1, SHA-256 or MD5. A wide range of reasonable numbers anywhere from one billion - one trillion guesses per second, depending on number of cores and machines. Ballparking at 10B/sec.\n\n","args":[],"type":"{ onlineThrottling100PerHour : Basics.Float, onlineNoThrottling10PerSecond : Basics.Float, offlineSlowHashing1e4PerSecond : Basics.Float, offlineFastHashing1e10PerSecond : Basics.Float }"},{"name":"ZxcvbnResult","comment":" `ZxcvbnResult` is returned by `zxcvbn` and holds the results of the password strength check. It has the following fields:\n\n  - `score` -- The overall score of the password from 0-4 (useful for displaying to the user, e.g. as a strength bar).\n      - 0 -- Risky password: \"too guessable\"\n      - 1 -- Modest protection from throttled online attacks: \"very guessable\"\n      - 2 -- Modest protection from unthrottled online attacks: \"somewhat guessable\"\n      - 3 -- Modest protection from offline attacks: \"safely unguessable\" assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc\n      - 4 -- Strong protection from offline attacks under same scenario: \"very unguessable\"\n  - `feedback` -- A record containing user-friendly feedback to help choose better passwords; is empty if the score is sufficiently high.\n  - `crackTimesDisplay` -- A record with user-friendly display strings for the crack time estimations, e.g. \"less than a second\", \"3 hours\", \"centuries\", etc.\n  - `crackTimesSeconds` -- A record containing back-of-the-envelope crack time estimations, in seconds, based on a few scenarios.\n  - `guesses` -- The estimated guesses needed to crack the password.\n  - `guessesLog10` -- The order of magnitude of the estimated number of guesses to crack the password.\n  - `password` -- The password that was checked.\n  - `sequence` -- The list of patterns that zxcvbn based the guess calculation on. Rather complicated and typically unnecessary, but the contained types are exposed in `Zxcvbn.MatchTypes` if they are needed.\n\n","args":[],"type":"{ score : Basics.Int, feedback : Zxcvbn.Feedback, crackTimesDisplay : Zxcvbn.DisplayCrackTimes, crackTimesSeconds : Zxcvbn.NumericCrackTimes, guesses : Basics.Int, guessesLog10 : Basics.Float, password : String.String, sequence : List.List Zxcvbn.MatchTypes.ScoredMatch }"}],"values":[{"name":"zxcvbn","comment":" `zxcvbn` takes two arguments, a `List String` of user patterns and a `String` password, and returns a result record of type `ZxcvbnResult`.\n\nThe user patterns argument (which may be an empty list) is an array of strings that `zxcvbn` will treat as an extra dictionary. This can be whatever list of strings you like but is meant for user inputs from other fields of the form, like name and email. That way a password that includes a user's personal information can be heavily penalized. This list is also good for site-specific vocabulary -- Acme Brick Co. might want to include `[\"acme\", \"brick\", \"acmebrick\", etc]`. This list is ordered in increasing rank, which the first element of the list being the highest rank (most common). Entries with higher ranks are more strongly penalized. However, unless a truly massive list is used, the ordering is unlikely to be relevant. User patterns are not case-sensitive.\n\n","type":"List.List String.String -> String.String -> Zxcvbn.ZxcvbnResult"}],"binops":[]},{"name":"Zxcvbn.MatchTypes","comment":" This module is not necessary for normal use of the `Zxcvbn` module; instead, it contains the types necessary for examining the actual matches in the most-guessable sequence contained in `ZxcvbnResult.sequence`.\n\n\n## Types\n\n@docs ScoredMatch, MatchDetails, DictionaryDetails\n\n","unions":[{"name":"DictionaryDetails","comment":" `DictionaryDetails` for specifying which kind of dictionary match a specific match is and any other details (e.g. which substitutions were made for l33t matches).\n\n  - `Dictionary` -- A standard dictionary match.\n  - `ReverseDictionary` -- A dictionary match where the token in the password was reversed, e.g. \"drowssap\" matches \"password\".\n  - `L33tDictionary` -- A dictionary match featuring common \"l33t\" substitutions, e.g. \"p@ssw0rd\" matches \"password\".\n      - `sub` -- A dictionary with keys of characters in the password and values of characters they were substituted with to make the match, e.g. `Dict.fromList [ ( '@', 'a' ), ( '0', 'o' ) ) ]` for \"p@ssw0rd\".\n      - `subDisplay` -- A human-readable description of the substitutions listed in `sub`.\n\n","args":[],"cases":[["Dictionary",[]],["ReverseDictionary",[]],["L33tDictionary",["{ sub : Dict.Dict Char.Char Char.Char, subDisplay : String.String }"]]]},{"name":"MatchDetails","comment":" `MatchDetails` type for holding all of the fields only relevant to specific types of matches.\n\n  - `DictionaryMatch` -- A match against common password, name, or English word dictionaries.\n      - `dictionaryDetails` -- Details of the dictionary match, e.g. whether it was a reverse match or not.\n      - `dictionaryName` -- The name of the dictionary that was matched against, e.g. \"englishWikipedia\"\n      - `rank` -- The frequency rank of the match, with 1 being the most common.\n      - `matchedWord` -- The word in the dictionary that was matched.\n\n  - `SpatialMatch` -- A match against sequences on the keyboard, e.g. \"asdfg\".\n      - `graph` -- The name of the specific keyboard layout that was matched, e.g. \"qwerty\" or \"dvorak\".\n      - `turns` -- Number of directions that the sequence travels in, e.g. \"zxcdert\" has 3.\n      - `shiftedCount` -- Number of characters that are the shifted version (e.g. 'A' instead of 'a').\n\n  - `SequenceMatch` -- A match against repetitive increases in unicode code point, e.g. \"abcdefg\" or \"aceg\".\n      - `sequenceName` -- The name of the matched sequence; will be \"lower\", \"upper\", \"digits\", or \"unicode\"\n      - `sequenceSpace` -- The number of \"characters\" in the sequence, e.g. 26 for alphabetical or 10 for digits. Defaults to 26 for unicode per the reference implementation.\n      - `ascending` -- Whether the match is ascending, e.g. \"12345\" or descending, e.g. \"54321\".\n\n  - `RepeatMatch` -- A match against 2 or more repeats, e.g. \"abcabcabc\"\n      - `baseToken` -- The base repeating unit, e.g. \"abc\" in \"abcabcabc\"\n      - `baseGuesses` -- The estimated number of guesses to \"crack\" the base token.\n      - `baseMatches` -- All matches for the base token.\n      - `repeatCount` -- The number of times the base token is repeated.\n\n  - `RegexMatch` -- A match agains a regex. Per reference implementation, this only matched 4-digit years.\n      - `regexName` -- The name of the regex that matched. Per reference implementation, this will only ever be \"recentYear\"\n      - `regexMatch` -- The regex match object for the match.\n\n  - `DateMatch` -- A match on an apparent numeric date, with or without separators.\n      - `separator` -- The separator of the date, e.g. \"/\" for \"5/5/1955\"; may be an empty string if no separator.\n      - `year`, `month`, `day` -- The date matched.\n\n  - `BruteforceMatch` -- A segment of password that didn't match any other match and thus would have to be bruteforced.\n\n","args":[],"cases":[["DictionaryMatch",["{ dictionaryDetails : Zxcvbn.MatchTypes.DictionaryDetails, dictionaryName : String.String, rank : Basics.Int, matchedWord : String.String }"]],["SpatialMatch",["{ graph : String.String, turns : Basics.Int, shiftedCount : Basics.Int }"]],["SequenceMatch",["{ sequenceName : String.String, sequenceSpace : Basics.Int, ascending : Basics.Bool }"]],["RepeatMatch",["{ baseToken : String.String, baseGuesses : Basics.Int, baseMatches : List.List Zxcvbn.MatchTypes.ScoredMatch, repeatCount : Basics.Int }"]],["RegexMatch",["{ regexName : String.String, regexMatch : Regex.Match }"]],["DateMatch",["{ separator : String.String, year : Basics.Int, month : Basics.Int, day : Basics.Int }"]],["BruteforceMatch",[]]]}],"aliases":[{"name":"ScoredMatch","comment":" Matches after estimated guesses have been calculated.\n\n  - `pattern` -- The type of the match, i.e. a dictionary match versus a date match.\n  - `token` -- the portion of the password that triggered the match.\n  - `i`, `j` -- The start/end positions of `token` in the original password.\n  - `guesses` -- The estimated number of guesses to \"crack\" a match.\n  - `guessesLog10` -- The order of magnitude of the estimated number of guesses to crack the match.\n\n","args":[],"type":"{ pattern : Zxcvbn.MatchTypes.MatchDetails, token : String.String, i : Basics.Int, j : Basics.Int, guesses : Basics.Int, guessesLog10 : Basics.Float }"}],"values":[],"binops":[]},{"name":"ZxcvbnPlus","comment":" `PasswordStrength.ZxcvbnPlus` is a native Elm implementation of the popular zxcvbn password strength javascript library. If you require exactly identical results to the reference implementation, please use `PasswordStrength.Zxcvbn` instead. More information may be found on its [GitHub](https://github.com/dropbox/zxcvbn). The following is excerpted from the README:\n\nzxcvbn is a password strength estimator inspired by password crackers. Through pattern matching and conservative estimation, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats (\"aaa\"), sequences (\"abcd\"), keyboard patterns (\"qwertyuiop\"), and l33t speak.\n\nConsider using zxcvbn as an algorithmic alternative to password composition policy — it is more secure, flexible, and usable when sites require a minimal complexity score in place of annoying rules like \"passwords must contain three of {lower, upper, numbers, symbols}\".\n\n  - **More secure:** policies often fail both ways, allowing weak passwords (\"P@ssword1\") and disallowing strong passwords.\n  - **More flexible:** zxcvbn allows many password styles to flourish so long as it detects sufficient complexity — passphrases are rated highly given enough uncommon words, keyboard patterns are ranked based on length and number of turns, and capitalization adds more complexity when it's unpredictaBle.\n  - **More usable:** zxcvbn is designed to power simple, rule-free interfaces that give instant feedback. In addition to strength estimation, zxcvbn includes minimal, targeted verbal feedback that can help guide users towards less guessable passwords.\n\nFor further detail and motivation, please refer to the USENIX Security '16 [paper and presentation](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler).\n\n\n## Usage Notes\n\nThe results returned by this package differ somewhat from the reference (javascript) implementation. If you require exactly identical results, consider using `Zxcvbn` instead.\n\nThe computational performance of this library is quite good, with essentially instantaneous results for normal length passwords and barely perceptible delays even with ~100-character passwords.\n\nIt should be noted that the zxcvbn library is not \"light\" by any means, given the large dictionaries of common words it requires. Sizes for an extremely simple example application follow:\n\n  - Compiled size -- 3.69 MB\n  - Minified size -- 1.85 MB\n  - Gzipped size -- 694 KB\n\n\n## Differences from `Zxcvbn`\n\nIn general, this package differs from the reference implementation in being more \"Elm\"-y. For example, custom types are used in place of strings in return values, regexes are avoided in favor of parsers, etc. Unlike the reference implementation, it also will not erroneously flag invalid dates, e.g. February 31st.\n\n\n## Known Issues\n\nWith _exceedingly_ difficult to crack passwords, the algorithm may report bruteforce matches as \"more guessable\" than actual matches in the password. This is because the number of possible guesses for bruteforce caps at approximately `10^308` guesses. Since this is truly absurdly large, it should never be problematic in normal use.\n\n\n## Functions\n\nThis package exposes exactly one function, `zxcvbnPlus`, which requires no configuration of any kind and may be simply called with a password (and possibly-empty list of additional patterns).\n\n@docs zxcvbnPlus\n\n\n## Result Types\n\nThe sole function in this package returns one relatively complex record containing the full results of the password strength check.\n\n@docs ZxcvbnPlusResult, Score, Feedback, DisplayCrackTimes, NumericCrackTimes\n\n","unions":[{"name":"Score","comment":" The overall score for a password's quality, e.g. for display to the user as a growing bar.\n\n  - `TooGuessable` -- Risky password: \"too guessable\"\n  - `VeryGuessable` -- Modest protection from throttled online attacks: \"very guessable\"\n  - `SomewhatGuessable` -- Modest protection from unthrottled online attacks: \"somewhat guessable\"\n  - `SafellyUnguessable` -- Modest protection from offline attacks: \"safely unguessable\" assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc\n  - `VeryUnguessable` -- Strong protection from offline attacks under same scenario: \"very unguessable\"\n\n","args":[],"cases":[["TooGuessable",[]],["VeryGuessable",[]],["SomewhatGuessable",[]],["SafelyUnguessable",[]],["VeryUnguessable",[]]]}],"aliases":[{"name":"DisplayCrackTimes","comment":" Crack times for password in user-friendly format (e.g. \"less than a second\", \"10 years\", etc.) for various cases.\n\n  - `onlineThrottling100PerHour` -- Online attack on a service that ratelimits password auth attempts.\n  - `onlineNoThrottling10PerSecond` -- Online attack on a service that doesn't ratelimit, or where an attacker has outsmarted ratelimiting.\n  - `offlineSlowHashing1e4PerSecond` -- Offline attack. assumes multiple attackers, proper user-unique salting, and a slow hash function w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.\n  - `offlineFastHashing1e10PerSecond` -- Offline attack with user-unique salting but a fast hash function like SHA-1, SHA-256 or MD5. A wide range of reasonable numbers anywhere from one billion - one trillion guesses per second, depending on number of cores and machines. Ballparking at 10B/sec.\n\n","args":[],"type":"{ onlineThrottling100PerHour : String.String, onlineNoThrottling10PerSecond : String.String, offlineSlowHashing1e4PerSecond : String.String, offlineFastHashing1e10PerSecond : String.String }"},{"name":"Feedback","comment":" Contains feedback inteded to be displayed to the user trying to create a password.\n\n  - `warning`: Explains what's wrong, e.g. \"This is a top-10 common password\". Will be `Nothing` if no applicable warnings are found.\n  - `suggestion`: A possibly-empty list of suggestions to help choose a less guessable password, e.g. \"Add another word or two\".\n\n","args":[],"type":"{ warning : Maybe.Maybe String.String, suggestions : List.List String.String }"},{"name":"NumericCrackTimes","comment":" Crack times for password in seconds for various cases.\n\n  - `onlineThrottling100PerHour` -- Online attack on a service that ratelimits password auth attempts.\n  - `onlineNoThrottling10PerSecond` -- Online attack on a service that doesn't ratelimit, or where an attacker has outsmarted ratelimiting.\n  - `offlineSlowHashing1e4PerSecond` -- Offline attack. assumes multiple attackers, proper user-unique salting, and a slow hash function w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.\n  - `offlineFastHashing1e10PerSecond` -- Offline attack with user-unique salting but a fast hash function like SHA-1, SHA-256 or MD5. A wide range of reasonable numbers anywhere from one billion - one trillion guesses per second, depending on number of cores and machines. Ballparking at 10B/sec.\n\n","args":[],"type":"{ onlineThrottling100PerHour : Basics.Float, onlineNoThrottling10PerSecond : Basics.Float, offlineSlowHashing1e4PerSecond : Basics.Float, offlineFastHashing1e10PerSecond : Basics.Float }"},{"name":"ZxcvbnPlusResult","comment":" `ZxcvbnPlusResult` is returned by `zxcvbnPlus` and holds the results of the password strength check. It has the following fields:\n\n  - `score` -- The overall score of the password (useful for displaying to the user, e.g. as a strength bar).\n  - `feedback` -- A record containing user-friendly feedback to help choose better passwords; is empty if the score is sufficiently high.\n  - `crackTimesDisplay` -- A record with user-friendly display strings for the crack time estimations, e.g. \"less than a second\", \"3 hours\", \"centuries\", etc.\n  - `crackTimesSeconds` -- A record containing back-of-the-envelope crack time estimations, in seconds, based on a few scenarios.\n  - `guesses` -- The estimated guesses needed to crack the password.\n  - `guessesLog10` -- The order of magnitude of the estimated number of guesses to crack the password.\n  - `password` -- The password that was checked.\n  - `sequence` -- The list of patterns that zxcvbn based the guess calculation on. Rather complicated and typically unnecessary, but the contained types are exposed in `ZxcvbnPlus.MatchTypes` if they are needed.\n\n","args":[],"type":"{ score : ZxcvbnPlus.Score, feedback : ZxcvbnPlus.Feedback, crackTimesDisplay : ZxcvbnPlus.DisplayCrackTimes, crackTimesSeconds : ZxcvbnPlus.NumericCrackTimes, guesses : Basics.Int, guessesLog10 : Basics.Float, password : String.String, matchSequence : List.List ZxcvbnPlus.MatchTypes.ScoredMatch }"}],"values":[{"name":"zxcvbnPlus","comment":" `zxcvbnPlus` takes two arguments, a `List String` of user patterns and a `String` password, and returns a result record of type `ZxcvbnResult`.\n\nThe user patterns argument (which may be an empty list) is an array of strings that `zxcvbnPlus` will treat as an extra dictionary. This can be whatever list of strings you like but is meant for user inputs from other fields of the form, like name and email. That way a password that includes a user's personal information can be heavily penalized. This list is also good for site-specific vocabulary -- Acme Brick Co. might want to include `[\"acme\", \"brick\", \"acmebrick\", etc]`. This list is ordered in increasing rank, which the first element of the list being the highest rank (most common). Entries with higher ranks are more strongly penalized. However, unless a truly massive list is used, the ordering is unlikely to be relevant. User patterns are not case-sensitive.\n\n","type":"List.List String.String -> String.String -> ZxcvbnPlus.ZxcvbnPlusResult"}],"binops":[]},{"name":"ZxcvbnPlus.MatchTypes","comment":" This module is not necessary for normal use of the `ZxcvbnPlus` module; instead, it contains the types necessary for examining the actual matches in the most-guessable sequence contained in `ZxcvbnPlusResult.matchSequence`.\n\n\n## Match Types\n\n@docs ScoredMatch, MatchDetails\n\n\n## Dictionary Match Specific\n\n@docs DictionaryDetails, Dictionary, EnglishSource, NameType\n\n\n## Date Match Specific\n\n@docs DateDetails\n\n\n## Key Adjacency Match Specific\n\n@docs KeyboardLayout\n\n\n## Ordinal Sequence Specific\n\n@docs OrdinalSequence\n\n","unions":[{"name":"DateDetails","comment":" The specific details for a date match.\n\n  - `RecentYear` -- A 4-digit year only, from 1900-present.\n  - `FullDate` -- A full date, specifying a month and day, as well as a possible separator character (e.g. '/').\n\n","args":[],"cases":[["RecentYear",[]],["FullDate",["{ separator : Maybe.Maybe Char.Char, month : Basics.Int, day : Basics.Int }"]]]},{"name":"Dictionary","comment":" The source for a dictionary match.\n\n  - `CommonPassword` -- Matched against a list of the 30,000 most-common passwords.\n  - `EnglishWord` -- Matched a common English-language word.\n  - `Name` -- Matched a common (English-language) given name/surname.\n  - `UserPattern` -- Matched one of the strings provided to `zxcvbnPlus` (typically site-specific words and/or user information).\n\n","args":[],"cases":[["CommonPassword",[]],["EnglishWord",["ZxcvbnPlus.MatchTypes.EnglishSource"]],["Name",["ZxcvbnPlus.MatchTypes.NameType"]],["UserPattern",[]]]},{"name":"DictionaryDetails","comment":" `DictionaryDetails` specifies which kind of dictionary match a specific match is and any other relevant details (e.g. which substitutions were made for l33t matches).\n\n  - `Dictionary` -- A standard dictionary match.\n  - `ReverseDictionary` -- A dictionary match where the token in the password was reversed, e.g. \"drowssap\" matches \"password\".\n  - `L33tDictionary` -- A dictionary match featuring common \"l33t\" substitutions, e.g. \"p@ssw0rd\" matches \"password\".\n      - `sub` -- A dictionary with keys of characters in the password and values of characters they were substituted with to make the match, e.g. `Dict.fromList [ ( '@', 'a' ), ( '0', 'o' ) ) ]` for \"p@ssw0rd\".\n\n","args":[],"cases":[["NormalDictionary",[]],["ReverseDictionary",[]],["L33tDictionary",["Dict.Dict Char.Char Char.Char"]]]},{"name":"EnglishSource","comment":" The frequency list against which an English word was matched.\n","args":[],"cases":[["Wikipedia",[]],["TvAndFilm",[]]]},{"name":"KeyboardLayout","comment":" The specific keyboard layout a key adjacency match was made against.\n","args":[],"cases":[["Qwerty",[]],["Dvorak",[]],["Keypad",[]],["MacKeypad",[]]]},{"name":"MatchDetails","comment":" `MatchDetails` type to specify the type and details of a specific match.\n\n  - `DictionaryMatch` -- A match against common password, name, or English word dictionaries.\n      - `dictionaryDetails` -- Details of the dictionary match, e.g. whether it was a reverse match or not.\n      - `dictionary` -- The dictionary source that was matched against, e.g. `CommonPassword` or `EnglishWord`.\n      - `rank` -- The frequency rank of the match, with 1 being the most common.\n      - `matchedWord` -- The word in the dictionary that was matched.\n\n  - `KeyAdjacencyMatch` -- A match against sequences on the keyboard, e.g. \"asdfg\".\n      - `layout` -- The name specific keyboard layout that was matched, e.g. `Qwerty` or `Dvorak`.\n      - `turns` -- Number of directions that the sequence travels in, e.g. \"zxcdert\" has 3.\n      - `shiftedKeys` -- Number of characters that are the shifted version (e.g. 'A' instead of 'a').\n\n  - `OrdinalSequenceMatch` -- A match against repetitive increases in unicode code point, e.g. \"abcdefg\" or \"aceg\".\n      - `sequence` -- The matched sequence, e.g. `LowercaseLatin` or `Unicode`.\n      - `delta` -- The offset betwen codepoints; may be positive or negative. For example, \"zyxw\" has `delta` of `-1`, and \"aceg\" has `delta` of 2.\n      - `obviousStart` -- Whether the matched sequence begins somewhere \"obvious\", e.g. \"0\" or \"a\".\n\n  - `RepeatMatch` -- A match against 2 or more repeats, e.g. \"abcabcabc\"\n      - `baseToken` -- The base repeating unit, e.g. \"abc\" in \"abcabcabc\"\n      - `baseGuesses` -- The estimated number of guesses to \"crack\" the base token.\n      - `baseMatchSequence` -- The estimated most-guessable match sequence for the base token.\n      - `repeatCount` -- The number of times the base token is repeated, e.g. 3 in \"ababab\".\n\n  - `DateMatch` -- A match on an apparent numeric date.\n      - `year` -- The year matched, e.g. 1954 for \"1/1/1954\".\n      - `dateDetails` -- The details of the found date, e.g. month and day, separator, whether it's only a recent year, etc.\n\n  - `BruteforceMatch` -- A segment of password that didn't match any other match and thus would have to be bruteforced.\n\n","args":[],"cases":[["DictionaryMatch",["{ dictionaryDetails : ZxcvbnPlus.MatchTypes.DictionaryDetails, dictionary : ZxcvbnPlus.MatchTypes.Dictionary, rank : Basics.Int, matchedWord : String.String }"]],["KeyAdjacencyMatch",["{ layout : ZxcvbnPlus.MatchTypes.KeyboardLayout, turns : Basics.Int, shiftedKeys : Basics.Int }"]],["OrdinalSequenceMatch",["{ sequence : ZxcvbnPlus.MatchTypes.OrdinalSequence, delta : Basics.Int, obviousStart : Basics.Bool }"]],["RepeatMatch",["{ baseToken : String.String, baseGuesses : Basics.Int, baseMatchSequence : List.List ZxcvbnPlus.MatchTypes.ScoredMatch, repeatCount : Basics.Int }"]],["DateMatch",["{ dateDetails : ZxcvbnPlus.MatchTypes.DateDetails, year : Basics.Int }"]],["BruteforceMatch",[]]]},{"name":"NameType","comment":" The type of name (e.g. surname, female given name, etc.) a common name is.\n","args":[],"cases":[["Surname",[]],["MaleName",[]],["FemaleName",[]]]},{"name":"OrdinalSequence","comment":" The specific ordinal sequence of characters that was matched.\n\n  - `UppercaseLatin` -- A sequence like \"ABCDEF\".\n  - `LowercaseLatin` -- A sequence like \"zyxwv\".\n  - `Digits` -- A sequence like \"5678\".\n  - `Unicode` -- Any other sequence, e.g. \"ㄅㄆㄇㄈ\".\n\n","args":[],"cases":[["UppercaseLatin",[]],["LowercaseLatin",[]],["Digits",[]],["Unicode",[]]]}],"aliases":[{"name":"ScoredMatch","comment":" A match for which estimated guesses have been calculated.\n\n  - `pattern` -- The type of the match, e.g. a dictionary match versus a date match.\n  - `token` -- the portion of the password that triggered the match.\n  - `i`, `j` -- The start/end positions of `token` in the original password.\n  - `guesses` -- The estimated number of guesses to \"crack\" the match.\n\n","args":[],"type":"{ pattern : ZxcvbnPlus.MatchTypes.MatchDetails, token : String.String, i : Basics.Int, j : Basics.Int, guesses : Basics.Int }"}],"values":[],"binops":[]}]