@twardoch/namzy 1.0.11 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/mangle.d.ts +7 -2
- package/dist/mangle.js +39 -8
- package/dist/wordlist.d.ts +0 -2
- package/dist/wordlist.js +105 -38
- package/package.json +1 -1
- package/src/index.ts +3 -3
- package/src/mangle.ts +44 -8
- package/src/wordlist.ts +105 -39
package/README.md
CHANGED
|
@@ -37,11 +37,11 @@ console.log(name, seeded);
|
|
|
37
37
|
|
|
38
38
|
## Wordlist
|
|
39
39
|
|
|
40
|
-
Namzy uses the shared bundled wordlists of
|
|
40
|
+
Namzy uses the shared bundled wordlists of 500 geographic words and 500 common words. Each pair may be joined in either order, for 500,000 raw ordered pairings before seam cleanup and replacement collisions.
|
|
41
41
|
|
|
42
42
|
## How it works
|
|
43
43
|
|
|
44
|
-
Picks one geographic name and one evocative common word, joins them in either order, cleans awkward seams,
|
|
44
|
+
Picks one geographic name and one evocative common word, joins them in either order, cleans awkward seams, then activates a seed-derived subset of 1 to 10 replacement rules from `c→q · f→v · k→c · q→k · s→z · z→s · v→f · w→u · b→p · p→b`. Results are deterministic for a given seed.
|
|
45
45
|
|
|
46
46
|
## License
|
|
47
47
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
1
|
+
import { activeRotationMask, joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
2
2
|
export interface NamzyOptions {
|
|
3
3
|
seed?: number;
|
|
4
4
|
}
|
|
@@ -8,4 +8,4 @@ export interface NamzyOptions {
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function generate(opts?: NamzyOptions): Promise<string>;
|
|
10
10
|
export { COMMON, GEO } from "./wordlist.js";
|
|
11
|
-
export { joinClean, mangle, mulberry32 };
|
|
11
|
+
export { activeRotationMask, joinClean, mangle, mulberry32 };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// this_file: src/index.ts
|
|
2
|
-
import { joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
2
|
+
import { activeRotationMask, joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
3
3
|
import { COMMON, GEO } from "./wordlist.js";
|
|
4
4
|
function capitalize(s) {
|
|
5
5
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -18,7 +18,7 @@ export async function generate(opts) {
|
|
|
18
18
|
const w2 = pick(COMMON, rng).toLowerCase();
|
|
19
19
|
const [first, second] = rng() < 0.5 ? [w1, w2] : [w2, w1];
|
|
20
20
|
const fused = joinClean(first, second);
|
|
21
|
-
return capitalize(mangle(fused));
|
|
21
|
+
return capitalize(mangle(fused, activeRotationMask(rng)));
|
|
22
22
|
}
|
|
23
23
|
export { COMMON, GEO } from "./wordlist.js";
|
|
24
|
-
export { joinClean, mangle, mulberry32 };
|
|
24
|
+
export { activeRotationMask, joinClean, mangle, mulberry32 };
|
package/dist/mangle.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/** Simple seeded mulberry32 RNG — returns a function that yields [0,1) floats */
|
|
2
2
|
export declare function mulberry32(seed: number): () => number;
|
|
3
|
-
|
|
4
|
-
export declare
|
|
3
|
+
type RotationRule = readonly [from: string, to: string];
|
|
4
|
+
export declare const ROTATION_RULES: readonly RotationRule[];
|
|
5
|
+
/** Choose 1..10 active consonant-rotation rules from the seeded RNG. */
|
|
6
|
+
export declare function activeRotationMask(rng: () => number): number;
|
|
7
|
+
/** Consonant rotation. Case-preserving. Defaults to all rules for direct helper use. */
|
|
8
|
+
export declare function mangle(s: string, activeMask?: number): string;
|
|
5
9
|
/**
|
|
6
10
|
* Fuse two lowercase words at a clean junction.
|
|
7
11
|
* Drops the first char of `b` while it duplicates the tail of `a`,
|
|
8
12
|
* or while the seam is vowel-vowel. Max two trims.
|
|
9
13
|
*/
|
|
10
14
|
export declare function joinClean(a: string, b: string): string;
|
|
15
|
+
export {};
|
package/dist/mangle.js
CHANGED
|
@@ -9,16 +9,47 @@ export function mulberry32(seed) {
|
|
|
9
9
|
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
const
|
|
13
|
-
c
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
export const ROTATION_RULES = [
|
|
13
|
+
["c", "q"],
|
|
14
|
+
["f", "v"],
|
|
15
|
+
["k", "c"],
|
|
16
|
+
["q", "k"],
|
|
17
|
+
["s", "z"],
|
|
18
|
+
["z", "s"],
|
|
19
|
+
["v", "f"],
|
|
20
|
+
["w", "u"],
|
|
21
|
+
["b", "p"],
|
|
22
|
+
["p", "b"],
|
|
23
|
+
];
|
|
24
|
+
const ALL_ROTATIONS = (1 << ROTATION_RULES.length) - 1;
|
|
25
|
+
function rotationFor(lower, activeMask) {
|
|
26
|
+
for (let i = 0; i < ROTATION_RULES.length; i++) {
|
|
27
|
+
if ((activeMask & (1 << i)) === 0) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const [from, to] = ROTATION_RULES[i];
|
|
31
|
+
if (lower === from) {
|
|
32
|
+
return to;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/** Choose 1..10 active consonant-rotation rules from the seeded RNG. */
|
|
38
|
+
export function activeRotationMask(rng) {
|
|
39
|
+
const order = ROTATION_RULES.map((_, i) => i);
|
|
40
|
+
const activeCount = 1 + Math.floor(rng() * ROTATION_RULES.length);
|
|
41
|
+
for (let i = 0; i < activeCount; i++) {
|
|
42
|
+
const swap = i + Math.floor(rng() * (order.length - i));
|
|
43
|
+
[order[i], order[swap]] = [order[swap], order[i]];
|
|
44
|
+
}
|
|
45
|
+
return order.slice(0, activeCount).reduce((mask, i) => mask | (1 << i), 0);
|
|
46
|
+
}
|
|
47
|
+
/** Consonant rotation. Case-preserving. Defaults to all rules for direct helper use. */
|
|
48
|
+
export function mangle(s, activeMask = ALL_ROTATIONS) {
|
|
18
49
|
let out = "";
|
|
19
50
|
for (const ch of s) {
|
|
20
51
|
const lower = ch.toLowerCase();
|
|
21
|
-
const repl =
|
|
52
|
+
const repl = rotationFor(lower, activeMask);
|
|
22
53
|
if (repl === undefined) {
|
|
23
54
|
out += ch;
|
|
24
55
|
}
|
|
@@ -35,7 +66,7 @@ const VOWELS = new Set(["a", "e", "i", "o", "u", "y"]);
|
|
|
35
66
|
* or while the seam is vowel-vowel. Max two trims.
|
|
36
67
|
*/
|
|
37
68
|
export function joinClean(a, b) {
|
|
38
|
-
|
|
69
|
+
const head = a;
|
|
39
70
|
let tail = b;
|
|
40
71
|
for (let i = 0; i < 2 && head.length > 0 && tail.length > 0; i++) {
|
|
41
72
|
const last = head[head.length - 1].toLowerCase();
|
package/dist/wordlist.d.ts
CHANGED
package/dist/wordlist.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
/** Geographic names (A-Za-z only, no diacritics). Shared across all implementations. */
|
|
1
|
+
// Geographic names (A-Za-z only, no diacritics). Shared across all implementations.
|
|
3
2
|
export const GEO = [
|
|
4
3
|
"tokyo", "paris", "oslo", "berlin", "lagos", "lima",
|
|
5
4
|
"boston", "vienna", "cairo", "kyoto", "dubai", "seoul",
|
|
6
5
|
"milan", "tunis", "perth", "genoa", "porto", "bruges",
|
|
7
|
-
"ghent", "brest", "
|
|
8
|
-
"basel", "natal", "recife", "darwin", "hobart", "
|
|
6
|
+
"ghent", "brest", "ashford", "sofia", "riga", "lyon",
|
|
7
|
+
"basel", "natal", "recife", "darwin", "hobart", "ashbury",
|
|
9
8
|
"varna", "split", "kotor", "tirana", "skopje", "bitola",
|
|
10
9
|
"plovdiv", "gabrovo", "ruse", "delhi", "rome", "athens",
|
|
11
10
|
"nairobi", "bali", "havana", "lisbon", "bogota", "dakar",
|
|
@@ -17,42 +16,76 @@ export const GEO = [
|
|
|
17
16
|
"tucson", "reno", "boise", "fargo", "tulsa", "tampa",
|
|
18
17
|
"miami", "salem", "dover", "trenton", "helena", "juneau",
|
|
19
18
|
"topeka", "albany", "amsterdam", "antwerp", "arusha", "aspen",
|
|
20
|
-
"atlanta", "auckland", "
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"jerusalem", "karachi", "krakow", "kuwait", "leipzig", "lille",
|
|
19
|
+
"atlanta", "auckland", "baku", "bangkok", "barcelona", "ashgrove",
|
|
20
|
+
"ashfield", "bergen", "bilbao", "bordeaux", "braga", "brisbane",
|
|
21
|
+
"bristol", "brussels", "bucharest", "budapest", "calgary", "canberra",
|
|
22
|
+
"cardiff", "casablanca", "chicago", "cologne", "colombo", "copenhagen",
|
|
23
|
+
"cork", "dresden", "durban", "edinburgh", "florence", "frankfurt",
|
|
24
|
+
"gdansk", "glasgow", "granada", "guangzhou", "hamburg", "hanoi",
|
|
25
|
+
"helsinki", "houston", "jakarta", "krakow", "leipzig", "lille",
|
|
28
26
|
"london", "luanda", "lucerne", "madrid", "malaga", "manila",
|
|
29
|
-
"marrakesh", "marseille", "melbourne", "memphis", "montreal", "
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
27
|
+
"marrakesh", "marseille", "melbourne", "memphis", "montreal", "munich",
|
|
28
|
+
"nagoya", "nantes", "napier", "nashville", "orlando", "osaka",
|
|
29
|
+
"ottawa", "palermo", "panama", "phuket", "pisa", "poznan",
|
|
30
|
+
"quebec", "reykjavik", "rotterdam", "sapporo", "sevilla", "shanghai",
|
|
31
|
+
"stockholm", "suzhou", "swansea", "bayfield", "tallinn", "tangier",
|
|
32
|
+
"thimphu", "toronto", "toulouse", "trieste", "valencia", "vancouver",
|
|
33
|
+
"verona", "warsaw", "winnipeg", "wroclaw", "zagreb", "aarhus",
|
|
34
|
+
"abidjan", "adelaide", "alger", "annaba", "ankara", "antalya",
|
|
35
|
+
"arezzo", "asuncion", "avignon", "baltimore", "banjul", "belem",
|
|
36
|
+
"bologna", "bremen", "cancun", "caracas", "cartagena", "catania",
|
|
37
|
+
"charlotte", "chennai", "chiangmai", "cleveland", "cordoba", "curitiba",
|
|
38
|
+
"cusco", "dallas", "dundee", "espoo", "fez", "freetown",
|
|
39
|
+
"fukuoka", "funchal", "gothenburg", "guayaquil", "bayport", "halifax",
|
|
40
|
+
"hamilton", "honolulu", "ibadan", "innsbruck", "izmir", "jaipur",
|
|
41
|
+
"kampala", "kansas", "kathmandu", "kingston", "kinshasa", "koblenz",
|
|
42
|
+
"kortrijk", "lahti", "lausanne", "leeds", "leuven", "liege",
|
|
43
|
+
"liverpool", "ljubljana", "lodz", "luxor", "bayview", "madison",
|
|
44
|
+
"malmo", "manchester", "mandalay", "maputo", "mendoza", "monterrey",
|
|
45
|
+
"montevideo", "noumea", "nuremberg", "okinawa", "omaha", "padua",
|
|
46
|
+
"penang", "portland", "pretoria", "rabat", "raleigh", "rennes",
|
|
47
|
+
"richmond", "salzburg", "samarkand", "santander", "santiago", "sendai",
|
|
48
|
+
"singapore", "skagen", "stavanger", "stuttgart", "surabaya", "suva",
|
|
49
|
+
"tampere", "taranto", "tarragona", "tiruchirappalli", "trondheim", "utrecht",
|
|
50
|
+
"valletta", "victoria", "vigo", "bergenfield", "bellevue", "bloomington",
|
|
51
|
+
"boulder", "bozeman", "bradford", "brighton", "brookline", "cambridge",
|
|
52
|
+
"carmel", "carson", "cedarpark", "chandler", "chico", "claremont",
|
|
53
|
+
"clearwater", "concord", "corvallis", "dayton", "decatur", "denton",
|
|
54
|
+
"duluth", "durham", "eugene", "everett", "fairbanks", "fairfield",
|
|
55
|
+
"flagstaff", "fremont", "fresno", "frisco", "gainesville", "garland",
|
|
56
|
+
"gilbert", "grandrapids", "greensboro", "greenville", "hartford", "hayward",
|
|
57
|
+
"henderson", "holland", "irvine", "ithaca", "lancaster", "lansing",
|
|
58
|
+
"lincoln", "lowell", "madisonville", "marion", "mesa", "miamibeach",
|
|
59
|
+
"midland", "milford", "mobile", "modesto", "monterey", "moreno",
|
|
60
|
+
"naperville", "newark", "newhaven", "newport", "norfolk", "norman",
|
|
61
|
+
"oakland", "oceanside", "olympia", "orleans", "pasadena", "peoria",
|
|
62
|
+
"plano", "pocatello", "pueblo", "redmond", "riverside", "rochester",
|
|
63
|
+
"rockford", "roseville", "sacramento", "savannah", "scottsdale", "somerville",
|
|
64
|
+
"spokane", "springfield", "stockton", "tacoma", "tempe", "torrance",
|
|
65
|
+
"tuscaloosa", "waco", "waterloo", "westport", "wichita", "wilmington",
|
|
66
|
+
"worcester", "yonkers", "york", "abilene", "akron", "annapolis",
|
|
67
|
+
"appleton", "arlington", "ashland", "atherton", "auburn", "bakersfield",
|
|
68
|
+
"bayonne", "benicia", "berkeley", "billings", "bloomfield", "bluffton",
|
|
69
|
+
"boca", "bradenton", "brentwood", "burlington", "camden", "canton",
|
|
70
|
+
"carlisle", "cheyenne", "chicopee", "clifton", "columbia", "columbus",
|
|
71
|
+
"conway", "cranston", "davis", "daytona", "deland", "dentonville",
|
|
72
|
+
"desmoines", "elgin", "elizabeth", "elkhart", "elmira", "erie",
|
|
73
|
+
"eureka", "evansville", "everglades", "fallsburg", "fayetteville", "flint",
|
|
74
|
+
"florissant", "fortwayne", "frederick", "fredericksburg", "gastonia", "georgetown",
|
|
75
|
+
"glendale", "grandforks", "greenbay", "haverhill", "highpoint", "hollywood",
|
|
76
|
+
"huntington", "huntsville", "independence", "jackson", "jacksonville", "joliet",
|
|
77
|
+
"kenosha", "kettering", "knoxville", "laredo", "lawrence", "lexington",
|
|
78
|
+
"livermore", "longmont", "lubbock", "macon", "malibu", "medford",
|
|
79
|
+
"merced", "mesquite", "missoula", "moline", "murfreesboro", "napa",
|
|
80
|
+
"newton", "niagara", "norwalk", "ocala", "ogden", "ontario",
|
|
81
|
+
"orange", "oshkosh", "owensboro", "palmcoast", "pensacola", "pomona",
|
|
82
|
+
"providence", "provo", "quincy", "racine", "redding", "renton",
|
|
83
|
+
"roanoke", "rockville", "roswell", "roundrock", "salinas", "sanjose",
|
|
84
|
+
"sanmateo", "santaana", "santafe", "santarosa", "sarasota", "schaumburg",
|
|
85
|
+
"shreveport", "siouxcity", "southbend", "stcloud", "stillwater", "sunnyvale",
|
|
86
|
+
"syracuse", "baywood",
|
|
54
87
|
];
|
|
55
|
-
|
|
88
|
+
// Common words (A-Za-z only, no diacritics). Shared across all implementations.
|
|
56
89
|
export const COMMON = [
|
|
57
90
|
"river", "stone", "ember", "frost", "harbor", "willow",
|
|
58
91
|
"copper", "marble", "anchor", "lantern", "cedar", "falcon",
|
|
@@ -104,4 +137,38 @@ export const COMMON = [
|
|
|
104
137
|
"flag", "fog", "fox", "gardenia", "gate", "glow",
|
|
105
138
|
"grass", "grovewood", "harborstone", "hilltop", "honeycomb", "island",
|
|
106
139
|
"kestrelwing", "lake", "leafwing", "marigold", "moonstone", "morning",
|
|
140
|
+
"acacia", "alpine", "amulet", "apple", "apricot", "arcade",
|
|
141
|
+
"arcadia", "archer", "argent", "armor", "asters", "aster",
|
|
142
|
+
"aurora", "awning", "badger", "bamboo", "barley", "basil",
|
|
143
|
+
"basket", "bayberry", "beech", "bellflower", "berry", "billet",
|
|
144
|
+
"biscuit", "blackbird", "bluebell", "bluejay", "bonnet", "bough",
|
|
145
|
+
"braid", "bread", "brick", "bridle", "brocade", "buckthorn",
|
|
146
|
+
"burrow", "buttercup", "cabochon", "campion", "canary", "caraway",
|
|
147
|
+
"catkin", "celeriac", "cello", "chanter", "chanticleer", "chestnut",
|
|
148
|
+
"citadel", "clementine", "cloverfield", "cobble", "codex", "columbine",
|
|
149
|
+
"corduroy", "cornflower", "courier", "coventry", "cove", "cowbell",
|
|
150
|
+
"crocus", "curlew", "cypress", "damask", "daffodil", "dandelion",
|
|
151
|
+
"dewdrop", "distaff", "driftwood", "eider", "elder", "elderberry",
|
|
152
|
+
"elfin", "emerald", "enamel", "equinox", "faience", "feather",
|
|
153
|
+
"fennel", "fiddle", "finch", "fir", "firwood", "flax",
|
|
154
|
+
"floret", "flute", "freesia", "frostline", "gable", "galax",
|
|
155
|
+
"garland", "gentian", "ginger", "gingham", "glenwood", "gosling",
|
|
156
|
+
"grain", "grebe", "halcyon", "hazelnut", "headland", "heliotrope",
|
|
157
|
+
"holly", "holystone", "honeydew", "hornbeam", "hyacinth", "inkwood",
|
|
158
|
+
"iris", "ironwood", "jasmine", "jennet", "jonquil", "kettle",
|
|
159
|
+
"kingsley", "laburnum", "lace", "ladle", "larkspur", "lavender",
|
|
160
|
+
"leather", "ledger", "lemongrass", "linnet", "lodestar", "loquat",
|
|
161
|
+
"lyre", "magnolia", "mandolin", "maple", "mariner", "marmot",
|
|
162
|
+
"mayflower", "meadowrun", "merlin", "mica", "milkweed", "millet",
|
|
163
|
+
"minnow", "mint", "mirabelle", "moonbeam", "moonrise", "moorland",
|
|
164
|
+
"mulberry", "nimbus", "nuthatch", "oatfield", "olivewood", "onyx",
|
|
165
|
+
"oriole", "oxbow", "pansy", "parchment", "partridge", "pear",
|
|
166
|
+
"pearwood", "pelican", "pepper", "peridot", "pewter", "pheasant",
|
|
167
|
+
"pimpernel", "pipit", "pistachio", "poplar", "porcelain", "primrose",
|
|
168
|
+
"quail", "quince", "quincewood", "rainbird", "rainstone", "reedbed",
|
|
169
|
+
"reedling", "rook", "rosemary", "rowan", "saddle", "saffron",
|
|
170
|
+
"sandalwood", "satin", "sawgrass", "scallop", "seafoam", "seedling",
|
|
171
|
+
"selkie", "shepherd", "shoal", "silk", "silverbell", "skylight",
|
|
172
|
+
"snowdrop", "songbird", "sorrel", "spindlewood", "spindleberry", "sprucewood",
|
|
173
|
+
"starling", "stonecrop",
|
|
107
174
|
];
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// this_file: src/index.ts
|
|
2
2
|
|
|
3
|
-
import { joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
3
|
+
import { activeRotationMask, joinClean, mangle, mulberry32 } from "./mangle.js";
|
|
4
4
|
import { COMMON, GEO } from "./wordlist.js";
|
|
5
5
|
|
|
6
6
|
export interface NamzyOptions {
|
|
@@ -28,8 +28,8 @@ export async function generate(opts?: NamzyOptions): Promise<string> {
|
|
|
28
28
|
const [first, second] = rng() < 0.5 ? [w1, w2] : [w2, w1];
|
|
29
29
|
|
|
30
30
|
const fused = joinClean(first, second);
|
|
31
|
-
return capitalize(mangle(fused));
|
|
31
|
+
return capitalize(mangle(fused, activeRotationMask(rng)));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export { COMMON, GEO } from "./wordlist.js";
|
|
35
|
-
export { joinClean, mangle, mulberry32 };
|
|
35
|
+
export { activeRotationMask, joinClean, mangle, mulberry32 };
|
package/src/mangle.ts
CHANGED
|
@@ -11,17 +11,53 @@ export function mulberry32(seed: number): () => number {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
c: "q", f: "v", k: "c", q: "k",
|
|
16
|
-
s: "z", z: "s", v: "f", w: "u",
|
|
17
|
-
};
|
|
14
|
+
type RotationRule = readonly [from: string, to: string];
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
export const ROTATION_RULES: readonly RotationRule[] = [
|
|
17
|
+
["c", "q"],
|
|
18
|
+
["f", "v"],
|
|
19
|
+
["k", "c"],
|
|
20
|
+
["q", "k"],
|
|
21
|
+
["s", "z"],
|
|
22
|
+
["z", "s"],
|
|
23
|
+
["v", "f"],
|
|
24
|
+
["w", "u"],
|
|
25
|
+
["b", "p"],
|
|
26
|
+
["p", "b"],
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const ALL_ROTATIONS = (1 << ROTATION_RULES.length) - 1;
|
|
30
|
+
|
|
31
|
+
function rotationFor(lower: string, activeMask: number): string | undefined {
|
|
32
|
+
for (let i = 0; i < ROTATION_RULES.length; i++) {
|
|
33
|
+
if ((activeMask & (1 << i)) === 0) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const [from, to] = ROTATION_RULES[i];
|
|
37
|
+
if (lower === from) {
|
|
38
|
+
return to;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Choose 1..10 active consonant-rotation rules from the seeded RNG. */
|
|
45
|
+
export function activeRotationMask(rng: () => number): number {
|
|
46
|
+
const order = ROTATION_RULES.map((_, i) => i);
|
|
47
|
+
const activeCount = 1 + Math.floor(rng() * ROTATION_RULES.length);
|
|
48
|
+
for (let i = 0; i < activeCount; i++) {
|
|
49
|
+
const swap = i + Math.floor(rng() * (order.length - i));
|
|
50
|
+
[order[i], order[swap]] = [order[swap], order[i]];
|
|
51
|
+
}
|
|
52
|
+
return order.slice(0, activeCount).reduce((mask, i) => mask | (1 << i), 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Consonant rotation. Case-preserving. Defaults to all rules for direct helper use. */
|
|
56
|
+
export function mangle(s: string, activeMask = ALL_ROTATIONS): string {
|
|
21
57
|
let out = "";
|
|
22
58
|
for (const ch of s) {
|
|
23
59
|
const lower = ch.toLowerCase();
|
|
24
|
-
const repl =
|
|
60
|
+
const repl = rotationFor(lower, activeMask);
|
|
25
61
|
if (repl === undefined) {
|
|
26
62
|
out += ch;
|
|
27
63
|
} else {
|
|
@@ -39,7 +75,7 @@ const VOWELS = new Set(["a", "e", "i", "o", "u", "y"]);
|
|
|
39
75
|
* or while the seam is vowel-vowel. Max two trims.
|
|
40
76
|
*/
|
|
41
77
|
export function joinClean(a: string, b: string): string {
|
|
42
|
-
|
|
78
|
+
const head = a;
|
|
43
79
|
let tail = b;
|
|
44
80
|
for (let i = 0; i < 2 && head.length > 0 && tail.length > 0; i++) {
|
|
45
81
|
const last = head[head.length - 1].toLowerCase();
|
package/src/wordlist.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
/** Geographic names (A-Za-z only, no diacritics). Shared across all implementations. */
|
|
1
|
+
// Geographic names (A-Za-z only, no diacritics). Shared across all implementations.
|
|
4
2
|
export const GEO: string[] = [
|
|
5
3
|
"tokyo", "paris", "oslo", "berlin", "lagos", "lima",
|
|
6
4
|
"boston", "vienna", "cairo", "kyoto", "dubai", "seoul",
|
|
7
5
|
"milan", "tunis", "perth", "genoa", "porto", "bruges",
|
|
8
|
-
"ghent", "brest", "
|
|
9
|
-
"basel", "natal", "recife", "darwin", "hobart", "
|
|
6
|
+
"ghent", "brest", "ashford", "sofia", "riga", "lyon",
|
|
7
|
+
"basel", "natal", "recife", "darwin", "hobart", "ashbury",
|
|
10
8
|
"varna", "split", "kotor", "tirana", "skopje", "bitola",
|
|
11
9
|
"plovdiv", "gabrovo", "ruse", "delhi", "rome", "athens",
|
|
12
10
|
"nairobi", "bali", "havana", "lisbon", "bogota", "dakar",
|
|
@@ -18,43 +16,77 @@ export const GEO: string[] = [
|
|
|
18
16
|
"tucson", "reno", "boise", "fargo", "tulsa", "tampa",
|
|
19
17
|
"miami", "salem", "dover", "trenton", "helena", "juneau",
|
|
20
18
|
"topeka", "albany", "amsterdam", "antwerp", "arusha", "aspen",
|
|
21
|
-
"atlanta", "auckland", "
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"jerusalem", "karachi", "krakow", "kuwait", "leipzig", "lille",
|
|
19
|
+
"atlanta", "auckland", "baku", "bangkok", "barcelona", "ashgrove",
|
|
20
|
+
"ashfield", "bergen", "bilbao", "bordeaux", "braga", "brisbane",
|
|
21
|
+
"bristol", "brussels", "bucharest", "budapest", "calgary", "canberra",
|
|
22
|
+
"cardiff", "casablanca", "chicago", "cologne", "colombo", "copenhagen",
|
|
23
|
+
"cork", "dresden", "durban", "edinburgh", "florence", "frankfurt",
|
|
24
|
+
"gdansk", "glasgow", "granada", "guangzhou", "hamburg", "hanoi",
|
|
25
|
+
"helsinki", "houston", "jakarta", "krakow", "leipzig", "lille",
|
|
29
26
|
"london", "luanda", "lucerne", "madrid", "malaga", "manila",
|
|
30
|
-
"marrakesh", "marseille", "melbourne", "memphis", "montreal", "
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
27
|
+
"marrakesh", "marseille", "melbourne", "memphis", "montreal", "munich",
|
|
28
|
+
"nagoya", "nantes", "napier", "nashville", "orlando", "osaka",
|
|
29
|
+
"ottawa", "palermo", "panama", "phuket", "pisa", "poznan",
|
|
30
|
+
"quebec", "reykjavik", "rotterdam", "sapporo", "sevilla", "shanghai",
|
|
31
|
+
"stockholm", "suzhou", "swansea", "bayfield", "tallinn", "tangier",
|
|
32
|
+
"thimphu", "toronto", "toulouse", "trieste", "valencia", "vancouver",
|
|
33
|
+
"verona", "warsaw", "winnipeg", "wroclaw", "zagreb", "aarhus",
|
|
34
|
+
"abidjan", "adelaide", "alger", "annaba", "ankara", "antalya",
|
|
35
|
+
"arezzo", "asuncion", "avignon", "baltimore", "banjul", "belem",
|
|
36
|
+
"bologna", "bremen", "cancun", "caracas", "cartagena", "catania",
|
|
37
|
+
"charlotte", "chennai", "chiangmai", "cleveland", "cordoba", "curitiba",
|
|
38
|
+
"cusco", "dallas", "dundee", "espoo", "fez", "freetown",
|
|
39
|
+
"fukuoka", "funchal", "gothenburg", "guayaquil", "bayport", "halifax",
|
|
40
|
+
"hamilton", "honolulu", "ibadan", "innsbruck", "izmir", "jaipur",
|
|
41
|
+
"kampala", "kansas", "kathmandu", "kingston", "kinshasa", "koblenz",
|
|
42
|
+
"kortrijk", "lahti", "lausanne", "leeds", "leuven", "liege",
|
|
43
|
+
"liverpool", "ljubljana", "lodz", "luxor", "bayview", "madison",
|
|
44
|
+
"malmo", "manchester", "mandalay", "maputo", "mendoza", "monterrey",
|
|
45
|
+
"montevideo", "noumea", "nuremberg", "okinawa", "omaha", "padua",
|
|
46
|
+
"penang", "portland", "pretoria", "rabat", "raleigh", "rennes",
|
|
47
|
+
"richmond", "salzburg", "samarkand", "santander", "santiago", "sendai",
|
|
48
|
+
"singapore", "skagen", "stavanger", "stuttgart", "surabaya", "suva",
|
|
49
|
+
"tampere", "taranto", "tarragona", "tiruchirappalli", "trondheim", "utrecht",
|
|
50
|
+
"valletta", "victoria", "vigo", "bergenfield", "bellevue", "bloomington",
|
|
51
|
+
"boulder", "bozeman", "bradford", "brighton", "brookline", "cambridge",
|
|
52
|
+
"carmel", "carson", "cedarpark", "chandler", "chico", "claremont",
|
|
53
|
+
"clearwater", "concord", "corvallis", "dayton", "decatur", "denton",
|
|
54
|
+
"duluth", "durham", "eugene", "everett", "fairbanks", "fairfield",
|
|
55
|
+
"flagstaff", "fremont", "fresno", "frisco", "gainesville", "garland",
|
|
56
|
+
"gilbert", "grandrapids", "greensboro", "greenville", "hartford", "hayward",
|
|
57
|
+
"henderson", "holland", "irvine", "ithaca", "lancaster", "lansing",
|
|
58
|
+
"lincoln", "lowell", "madisonville", "marion", "mesa", "miamibeach",
|
|
59
|
+
"midland", "milford", "mobile", "modesto", "monterey", "moreno",
|
|
60
|
+
"naperville", "newark", "newhaven", "newport", "norfolk", "norman",
|
|
61
|
+
"oakland", "oceanside", "olympia", "orleans", "pasadena", "peoria",
|
|
62
|
+
"plano", "pocatello", "pueblo", "redmond", "riverside", "rochester",
|
|
63
|
+
"rockford", "roseville", "sacramento", "savannah", "scottsdale", "somerville",
|
|
64
|
+
"spokane", "springfield", "stockton", "tacoma", "tempe", "torrance",
|
|
65
|
+
"tuscaloosa", "waco", "waterloo", "westport", "wichita", "wilmington",
|
|
66
|
+
"worcester", "yonkers", "york", "abilene", "akron", "annapolis",
|
|
67
|
+
"appleton", "arlington", "ashland", "atherton", "auburn", "bakersfield",
|
|
68
|
+
"bayonne", "benicia", "berkeley", "billings", "bloomfield", "bluffton",
|
|
69
|
+
"boca", "bradenton", "brentwood", "burlington", "camden", "canton",
|
|
70
|
+
"carlisle", "cheyenne", "chicopee", "clifton", "columbia", "columbus",
|
|
71
|
+
"conway", "cranston", "davis", "daytona", "deland", "dentonville",
|
|
72
|
+
"desmoines", "elgin", "elizabeth", "elkhart", "elmira", "erie",
|
|
73
|
+
"eureka", "evansville", "everglades", "fallsburg", "fayetteville", "flint",
|
|
74
|
+
"florissant", "fortwayne", "frederick", "fredericksburg", "gastonia", "georgetown",
|
|
75
|
+
"glendale", "grandforks", "greenbay", "haverhill", "highpoint", "hollywood",
|
|
76
|
+
"huntington", "huntsville", "independence", "jackson", "jacksonville", "joliet",
|
|
77
|
+
"kenosha", "kettering", "knoxville", "laredo", "lawrence", "lexington",
|
|
78
|
+
"livermore", "longmont", "lubbock", "macon", "malibu", "medford",
|
|
79
|
+
"merced", "mesquite", "missoula", "moline", "murfreesboro", "napa",
|
|
80
|
+
"newton", "niagara", "norwalk", "ocala", "ogden", "ontario",
|
|
81
|
+
"orange", "oshkosh", "owensboro", "palmcoast", "pensacola", "pomona",
|
|
82
|
+
"providence", "provo", "quincy", "racine", "redding", "renton",
|
|
83
|
+
"roanoke", "rockville", "roswell", "roundrock", "salinas", "sanjose",
|
|
84
|
+
"sanmateo", "santaana", "santafe", "santarosa", "sarasota", "schaumburg",
|
|
85
|
+
"shreveport", "siouxcity", "southbend", "stcloud", "stillwater", "sunnyvale",
|
|
86
|
+
"syracuse", "baywood",
|
|
55
87
|
];
|
|
56
88
|
|
|
57
|
-
|
|
89
|
+
// Common words (A-Za-z only, no diacritics). Shared across all implementations.
|
|
58
90
|
export const COMMON: string[] = [
|
|
59
91
|
"river", "stone", "ember", "frost", "harbor", "willow",
|
|
60
92
|
"copper", "marble", "anchor", "lantern", "cedar", "falcon",
|
|
@@ -106,4 +138,38 @@ export const COMMON: string[] = [
|
|
|
106
138
|
"flag", "fog", "fox", "gardenia", "gate", "glow",
|
|
107
139
|
"grass", "grovewood", "harborstone", "hilltop", "honeycomb", "island",
|
|
108
140
|
"kestrelwing", "lake", "leafwing", "marigold", "moonstone", "morning",
|
|
141
|
+
"acacia", "alpine", "amulet", "apple", "apricot", "arcade",
|
|
142
|
+
"arcadia", "archer", "argent", "armor", "asters", "aster",
|
|
143
|
+
"aurora", "awning", "badger", "bamboo", "barley", "basil",
|
|
144
|
+
"basket", "bayberry", "beech", "bellflower", "berry", "billet",
|
|
145
|
+
"biscuit", "blackbird", "bluebell", "bluejay", "bonnet", "bough",
|
|
146
|
+
"braid", "bread", "brick", "bridle", "brocade", "buckthorn",
|
|
147
|
+
"burrow", "buttercup", "cabochon", "campion", "canary", "caraway",
|
|
148
|
+
"catkin", "celeriac", "cello", "chanter", "chanticleer", "chestnut",
|
|
149
|
+
"citadel", "clementine", "cloverfield", "cobble", "codex", "columbine",
|
|
150
|
+
"corduroy", "cornflower", "courier", "coventry", "cove", "cowbell",
|
|
151
|
+
"crocus", "curlew", "cypress", "damask", "daffodil", "dandelion",
|
|
152
|
+
"dewdrop", "distaff", "driftwood", "eider", "elder", "elderberry",
|
|
153
|
+
"elfin", "emerald", "enamel", "equinox", "faience", "feather",
|
|
154
|
+
"fennel", "fiddle", "finch", "fir", "firwood", "flax",
|
|
155
|
+
"floret", "flute", "freesia", "frostline", "gable", "galax",
|
|
156
|
+
"garland", "gentian", "ginger", "gingham", "glenwood", "gosling",
|
|
157
|
+
"grain", "grebe", "halcyon", "hazelnut", "headland", "heliotrope",
|
|
158
|
+
"holly", "holystone", "honeydew", "hornbeam", "hyacinth", "inkwood",
|
|
159
|
+
"iris", "ironwood", "jasmine", "jennet", "jonquil", "kettle",
|
|
160
|
+
"kingsley", "laburnum", "lace", "ladle", "larkspur", "lavender",
|
|
161
|
+
"leather", "ledger", "lemongrass", "linnet", "lodestar", "loquat",
|
|
162
|
+
"lyre", "magnolia", "mandolin", "maple", "mariner", "marmot",
|
|
163
|
+
"mayflower", "meadowrun", "merlin", "mica", "milkweed", "millet",
|
|
164
|
+
"minnow", "mint", "mirabelle", "moonbeam", "moonrise", "moorland",
|
|
165
|
+
"mulberry", "nimbus", "nuthatch", "oatfield", "olivewood", "onyx",
|
|
166
|
+
"oriole", "oxbow", "pansy", "parchment", "partridge", "pear",
|
|
167
|
+
"pearwood", "pelican", "pepper", "peridot", "pewter", "pheasant",
|
|
168
|
+
"pimpernel", "pipit", "pistachio", "poplar", "porcelain", "primrose",
|
|
169
|
+
"quail", "quince", "quincewood", "rainbird", "rainstone", "reedbed",
|
|
170
|
+
"reedling", "rook", "rosemary", "rowan", "saddle", "saffron",
|
|
171
|
+
"sandalwood", "satin", "sawgrass", "scallop", "seafoam", "seedling",
|
|
172
|
+
"selkie", "shepherd", "shoal", "silk", "silverbell", "skylight",
|
|
173
|
+
"snowdrop", "songbird", "sorrel", "spindlewood", "spindleberry", "sprucewood",
|
|
174
|
+
"starling", "stonecrop",
|
|
109
175
|
];
|