@twardoch/namzy 0.1.0 → 1.0.11

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 CHANGED
@@ -1,71 +1,47 @@
1
1
  # namzy
2
2
 
3
- Generates fun, human-friendly project names. Seeded by timestamp so you get
4
- fresh names every run — but pass `--seed` for reproducibility.
3
+ Generates fun, human-friendly fused project names from a bundled local wordlist.
5
4
 
6
5
  ## Install
7
6
 
8
7
  ```sh
9
- npm install namzy
8
+ npm install @twardoch/namzy
10
9
  # or run without installing:
11
- npx namzy
10
+ npx @twardoch/namzy
12
11
  ```
13
12
 
14
13
  ## CLI
15
14
 
16
15
  ```sh
17
- # One word (default)
18
- namzy
19
-
20
- # PascalCase two-word name
21
- namzy --shape joined
22
-
23
- # Space-separated two words
24
- namzy --shape spaced
16
+ npx @twardoch/namzy
25
17
 
26
18
  # Generate 5 names
27
- namzy --count 5 --shape joined
28
-
29
- # Fetch words from the web (falls back to offline on failure)
30
- namzy --online --shape spaced
19
+ npx @twardoch/namzy --count 5
31
20
 
32
21
  # Help
33
- namzy --help
22
+ npx @twardoch/namzy --help
34
23
  ```
35
24
 
36
25
  ## Library
37
26
 
38
27
  ```ts
39
- import { generate } from "namzy";
28
+ import { generate } from "@twardoch/namzy";
40
29
 
41
- // Single word (default)
42
30
  const name = await generate();
43
31
 
44
- // Joined PascalCase
45
- const joined = await generate({ shape: "joined" });
46
-
47
- // Spaced, seeded for reproducibility
48
- const seeded = await generate({ shape: "spaced", seed: 42 });
49
-
50
- // Online mode (falls back to offline)
51
- const online = await generate({ online: true, shape: "joined" });
32
+ // Seeded for reproducibility
33
+ const seeded = await generate({ seed: 42 });
52
34
 
53
- console.log(name, joined, seeded, online);
35
+ console.log(name, seeded);
54
36
  ```
55
37
 
56
- ## Modes
38
+ ## Wordlist
57
39
 
58
- | Mode | Description |
59
- |------|-------------|
60
- | `--offline` | Uses bundled wordlist (default, always works) |
61
- | `--online` | Fetches from `random-word-api.herokuapp.com`, falls back offline |
40
+ Namzy uses the shared bundled wordlists of 300 geographic words and 300 common words. Each pair may be joined in either order, for 180,000 raw ordered pairings before seam cleanup and mangling.
62
41
 
63
42
  ## How it works
64
43
 
65
- Picks words from geographic names (Tokyo, Oslo, Cairo…) and evocative English
66
- words (ember, flint, willow…), then applies a small phonetic mangling pass
67
- (e.g. `s→z`, `ph→f`, `oo→u`) for a playful feel. Results are deterministic
68
- for a given seed.
44
+ Picks one geographic name and one evocative common word, joins them in either order, cleans awkward seams, and applies the consonant rotation `c→q · f→v · k→c · q→k · s→z · z→s · v→f · w→u`. Results are deterministic for a given seed.
69
45
 
70
46
  ## License
71
47
 
package/dist/cli.js CHANGED
@@ -8,18 +8,15 @@ Usage:
8
8
  namzy [options]
9
9
 
10
10
  Options:
11
- --online Fetch words from a public API (falls back to offline)
12
11
  --count <N> Number of names to generate (default: 1)
13
12
  --help Show this help
14
13
 
15
14
  Examples:
16
15
  namzy
17
16
  namzy --count 5
18
- namzy --online --count 3
19
17
  `.trimStart();
20
18
  function parseArgs(argv) {
21
19
  const args = argv.slice(2);
22
- const opts = {};
23
20
  let count = 1;
24
21
  for (let i = 0; i < args.length; i++) {
25
22
  const arg = args[i];
@@ -29,12 +26,9 @@ function parseArgs(argv) {
29
26
  process.stdout.write(HELP);
30
27
  process.exit(0);
31
28
  break;
32
- case "--online":
33
- opts.online = true;
34
- break;
35
29
  case "--count": {
36
30
  const n = parseInt(args[++i], 10);
37
- if (isNaN(n) || n < 1) {
31
+ if (Number.isNaN(n) || n < 1) {
38
32
  process.stderr.write(`--count must be a positive integer\n`);
39
33
  process.exit(1);
40
34
  }
@@ -46,14 +40,14 @@ function parseArgs(argv) {
46
40
  process.exit(1);
47
41
  }
48
42
  }
49
- return { opts, count };
43
+ return { count };
50
44
  }
51
45
  async function main() {
52
- const { opts, count } = parseArgs(process.argv);
46
+ const { count } = parseArgs(process.argv);
53
47
  const base = Date.now();
54
48
  for (let i = 0; i < count; i++) {
55
- const name = await generate({ ...opts, seed: base + i * 1337 });
56
- process.stdout.write(name + "\n");
49
+ const name = await generate({ seed: base + i * 1337 });
50
+ process.stdout.write(`${name}\n`);
57
51
  }
58
52
  }
59
53
  main().catch((err) => {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { mangle, mulberry32, joinClean } from "./mangle.js";
1
+ import { joinClean, mangle, mulberry32 } from "./mangle.js";
2
2
  export interface NamzyOptions {
3
- online?: boolean;
4
3
  seed?: number;
5
4
  }
6
5
  /**
@@ -8,5 +7,5 @@ export interface NamzyOptions {
8
7
  * Two raw words → junction-cleaned fusion → consonant rotation → capitalize.
9
8
  */
10
9
  export declare function generate(opts?: NamzyOptions): Promise<string>;
11
- export { mangle, joinClean, mulberry32 };
12
- export { GEO, COMMON } from "./wordlist.js";
10
+ export { COMMON, GEO } from "./wordlist.js";
11
+ export { joinClean, mangle, mulberry32 };
package/dist/index.js CHANGED
@@ -1,48 +1,24 @@
1
1
  // this_file: src/index.ts
2
- import { GEO, COMMON } from "./wordlist.js";
3
- import { mangle, mulberry32, joinClean } from "./mangle.js";
2
+ import { joinClean, mangle, mulberry32 } from "./mangle.js";
3
+ import { COMMON, GEO } from "./wordlist.js";
4
4
  function capitalize(s) {
5
5
  return s.charAt(0).toUpperCase() + s.slice(1);
6
6
  }
7
7
  function pick(arr, rng) {
8
8
  return arr[Math.floor(rng() * arr.length)];
9
9
  }
10
- async function fetchOnlineWords() {
11
- const url = `https://random-word-api.herokuapp.com/word?number=2&length=6`;
12
- const resp = await fetch(url);
13
- if (!resp.ok)
14
- throw new Error(`HTTP ${resp.status}`);
15
- const data = (await resp.json());
16
- if (!Array.isArray(data) || data.length < 2)
17
- throw new Error("Bad response");
18
- return data.slice(0, 2).map((w) => w.toLowerCase().replace(/[^a-z]/g, ""));
19
- }
20
10
  /**
21
11
  * Generate a single fused, mangled namzy name.
22
12
  * Two raw words → junction-cleaned fusion → consonant rotation → capitalize.
23
13
  */
24
14
  export async function generate(opts) {
25
- const online = opts?.online ?? false;
26
15
  const seed = opts?.seed ?? Date.now();
27
16
  const rng = mulberry32(seed);
28
- let w1;
29
- let w2;
30
- if (online) {
31
- try {
32
- const words = await fetchOnlineWords();
33
- [w1, w2] = words;
34
- }
35
- catch {
36
- w1 = pick(GEO, rng).toLowerCase();
37
- w2 = pick(COMMON, rng).toLowerCase();
38
- }
39
- }
40
- else {
41
- w1 = pick(GEO, rng).toLowerCase();
42
- w2 = pick(COMMON, rng).toLowerCase();
43
- }
44
- const fused = joinClean(w1, w2);
17
+ const w1 = pick(GEO, rng).toLowerCase();
18
+ const w2 = pick(COMMON, rng).toLowerCase();
19
+ const [first, second] = rng() < 0.5 ? [w1, w2] : [w2, w1];
20
+ const fused = joinClean(first, second);
45
21
  return capitalize(mangle(fused));
46
22
  }
47
- export { mangle, joinClean, mulberry32 };
48
- export { GEO, COMMON } from "./wordlist.js";
23
+ export { COMMON, GEO } from "./wordlist.js";
24
+ export { joinClean, mangle, mulberry32 };
@@ -1,4 +1,4 @@
1
- /** Geographic names (A-Za-z only, no diacritics) */
1
+ /** Geographic names (A-Za-z only, no diacritics). Shared across all implementations. */
2
2
  export declare const GEO: string[];
3
- /** Common evocative English words */
3
+ /** Common evocative English words. Shared across all implementations. */
4
4
  export declare const COMMON: string[];
package/dist/wordlist.js CHANGED
@@ -1,17 +1,107 @@
1
1
  // this_file: src/wordlist.ts
2
- /** Geographic names (A-Za-z only, no diacritics) */
2
+ /** Geographic names (A-Za-z only, no diacritics). Shared across all implementations. */
3
3
  export const GEO = [
4
- "tokyo", "paris", "oslo", "berlin", "lagos", "lima", "boston", "vienna",
5
- "cairo", "kyoto", "dubai", "seoul", "milan", "tunis", "perth", "genoa",
6
- "porto", "bruges", "ghent", "brest", "minsk", "sofia", "riga", "lyon",
7
- "basel", "natal", "recife", "darwin", "hobart", "odessa", "varna", "Split",
8
- "kotor", "tiran", "skopje", "bitola", "plovdiv", "gabrovo", "varna", "ruse",
4
+ "tokyo", "paris", "oslo", "berlin", "lagos", "lima",
5
+ "boston", "vienna", "cairo", "kyoto", "dubai", "seoul",
6
+ "milan", "tunis", "perth", "genoa", "porto", "bruges",
7
+ "ghent", "brest", "minsk", "sofia", "riga", "lyon",
8
+ "basel", "natal", "recife", "darwin", "hobart", "odessa",
9
+ "varna", "split", "kotor", "tirana", "skopje", "bitola",
10
+ "plovdiv", "gabrovo", "ruse", "delhi", "rome", "athens",
11
+ "nairobi", "bali", "havana", "lisbon", "bogota", "dakar",
12
+ "quito", "vilnius", "vaduz", "bern", "accra", "kigali",
13
+ "abuja", "bamako", "niamey", "lome", "prague", "dublin",
14
+ "naples", "tulum", "tbilisi", "yerevan", "astana", "lusaka",
15
+ "harare", "asmara", "manaus", "cuenca", "merida", "geneva",
16
+ "zurich", "venice", "sydney", "denver", "austin", "phoenix",
17
+ "tucson", "reno", "boise", "fargo", "tulsa", "tampa",
18
+ "miami", "salem", "dover", "trenton", "helena", "juneau",
19
+ "topeka", "albany", "amsterdam", "antwerp", "arusha", "aspen",
20
+ "atlanta", "auckland", "baghdad", "baku", "bangkok", "barcelona",
21
+ "beijing", "beirut", "belfast", "belgrade", "bergen", "bilbao",
22
+ "bordeaux", "braga", "brisbane", "bristol", "brussels", "bucharest",
23
+ "budapest", "calgary", "canberra", "cardiff", "casablanca", "chicago",
24
+ "cologne", "colombo", "copenhagen", "cork", "dresden", "durban",
25
+ "edinburgh", "florence", "frankfurt", "gdansk", "glasgow", "granada",
26
+ "guangzhou", "hamburg", "hanoi", "helsinki", "houston", "jakarta",
27
+ "jerusalem", "karachi", "krakow", "kuwait", "leipzig", "lille",
28
+ "london", "luanda", "lucerne", "madrid", "malaga", "manila",
29
+ "marrakesh", "marseille", "melbourne", "memphis", "montreal", "moscow",
30
+ "munich", "nagoya", "nantes", "napier", "nashville", "orlando",
31
+ "osaka", "ottawa", "palermo", "panama", "phuket", "pisa",
32
+ "poznan", "quebec", "reykjavik", "rotterdam", "sarajevo", "sapporo",
33
+ "sevilla", "shanghai", "stockholm", "suzhou", "swansea", "taipei",
34
+ "tallinn", "tangier", "tehran", "thimphu", "toronto", "toulouse",
35
+ "trieste", "valencia", "vancouver", "verona", "warsaw", "winnipeg",
36
+ "wroclaw", "zagreb", "aarhus", "abidjan", "adelaide", "alger",
37
+ "annaba", "ankara", "antalya", "arezzo", "asuncion", "avignon",
38
+ "baltimore", "banjul", "belem", "bologna", "bremen", "cancun",
39
+ "caracas", "cartagena", "catania", "charlotte", "chennai", "chiangmai",
40
+ "cleveland", "cordoba", "curitiba", "cusco", "dallas", "damascus",
41
+ "dundee", "espoo", "fez", "freetown", "fukuoka", "funchal",
42
+ "gothenburg", "guayaquil", "haifa", "halifax", "hamilton", "honolulu",
43
+ "ibadan", "innsbruck", "izmir", "jaipur", "jeddah", "kampala",
44
+ "kansas", "kashgar", "kathmandu", "khartoum", "kingston", "kinshasa",
45
+ "koblenz", "kortrijk", "lahti", "lausanne", "leeds", "leuven",
46
+ "liege", "liverpool", "ljubljana", "lodz", "luxor", "macao",
47
+ "madison", "malmo", "manchester", "mandalay", "maputo", "mendoza",
48
+ "monterrey", "montevideo", "nicosia", "noumea", "nuremberg", "okinawa",
49
+ "omaha", "padua", "penang", "peshawar", "portland", "pretoria",
50
+ "rabat", "raleigh", "rennes", "richmond", "salzburg", "samarkand",
51
+ "santander", "santiago", "sendai", "singapore", "skagen", "stavanger",
52
+ "stuttgart", "surabaya", "suva", "tampere", "taranto", "tarragona",
53
+ "tiruchirappalli", "trondheim", "utrecht", "valletta", "victoria", "vigo",
9
54
  ];
10
- /** Common evocative English words */
55
+ /** Common evocative English words. Shared across all implementations. */
11
56
  export const COMMON = [
12
- "river", "stone", "ember", "frost", "harbor", "willow", "copper", "marble",
13
- "anchor", "lantern", "cedar", "falcon", "coral", "dagger", "flint", "grove",
14
- "haven", "iron", "jasper", "kelp", "larch", "mast", "nettle", "oak",
15
- "pine", "quill", "reed", "sage", "thorn", "umber", "vale", "wren",
16
- "yarrow", "zenith", "amber", "birch", "cliff", "drift", "forge", "glade",
57
+ "river", "stone", "ember", "frost", "harbor", "willow",
58
+ "copper", "marble", "anchor", "lantern", "cedar", "falcon",
59
+ "coral", "dagger", "flint", "grove", "haven", "iron",
60
+ "jasper", "kelp", "larch", "mast", "nettle", "oak",
61
+ "pine", "quill", "reed", "sage", "thorn", "umber",
62
+ "vale", "wren", "yarrow", "zenith", "amber", "birch",
63
+ "cliff", "drift", "forge", "glade", "mesa", "canyon",
64
+ "basin", "fern", "gale", "peak", "ridge", "shore",
65
+ "tide", "bluff", "brook", "crest", "delta", "glen",
66
+ "helm", "inlet", "jetty", "knoll", "loft", "moor",
67
+ "notch", "orbit", "prism", "thunder", "silver", "meadow",
68
+ "basalt", "summit", "valley", "bridge", "beacon", "ranger",
69
+ "timber", "clover", "pebble", "ripple", "canopy", "chimney",
70
+ "cinder", "comet", "ferret", "glider", "jaguar", "kernel",
71
+ "lancer", "mortar", "nebula", "osprey", "patrol", "quartz",
72
+ "rafter", "sparrow", "granite", "hazel", "kindle", "laurel",
73
+ "mossy", "nimble", "ochre", "russet", "sable", "vapor",
74
+ "wicker", "cobalt", "dune", "hollow", "ivy", "juniper",
75
+ "linden", "mist", "oyster", "acorn", "anvil", "apron",
76
+ "arrow", "ash", "atlas", "autumn", "badge", "banner",
77
+ "beryl", "blossom", "boulder", "bramble", "brass", "breeze",
78
+ "briar", "bronze", "brooklet", "buckle", "burl", "cairn",
79
+ "candle", "canvas", "cavern", "chalk", "charm", "citrine",
80
+ "cloud", "cloverleaf", "cobaltcore", "compass", "copperleaf", "cradle",
81
+ "cricket", "crystal", "daisy", "dale", "dawn", "deerden",
82
+ "desert", "dew", "diamond", "dovetail", "dragonfly", "dream",
83
+ "drifter", "dunecrest", "dusk", "echo", "elm", "fernleaf",
84
+ "firefly", "fjord", "flame", "flower", "flume", "forest",
85
+ "foxglove", "garden", "garnet", "geode", "glacier", "glimmer",
86
+ "goldfinch", "gravel", "greenwood", "griffin", "harborlight", "hearth",
87
+ "heather", "heron", "hill", "honey", "horizon", "icicle",
88
+ "ivory", "jewel", "kestrel", "lagoon", "laurelwood", "leaf",
89
+ "lighthouse", "lilac", "lotus", "meadowlark", "moon", "moss",
90
+ "myrtle", "nectar", "nightingale", "obsidian", "olive", "opal",
91
+ "orchard", "otter", "pebblebrook", "petal", "plume", "prairie",
92
+ "rain", "raven", "redwood", "reef", "ribbon", "root",
93
+ "rose", "ruby", "sail", "salt", "sapphire", "scarlet",
94
+ "seabird", "sequoia", "shadow", "shale", "shell", "shimmer",
95
+ "skylark", "slate", "smoke", "snow", "sparrowhawk", "spindle",
96
+ "spirit", "spring", "spruce", "star", "starlight", "storm",
97
+ "stream", "sunbeam", "sunset", "sycamore", "talon", "thicket",
98
+ "thistle", "thunderhead", "tidepool", "topaz", "trail", "valleyfield",
99
+ "velvet", "violet", "walnut", "waterfall", "wave", "wind",
100
+ "winter", "wolfram", "woodland", "zephyr", "ashwood", "bell",
101
+ "bird", "bloom", "branch", "bright", "brookside", "camp",
102
+ "campfire", "castle", "chime", "clay", "cloudbank", "coast",
103
+ "copperwood", "creek", "crown", "emberfall", "field", "firestone",
104
+ "flag", "fog", "fox", "gardenia", "gate", "glow",
105
+ "grass", "grovewood", "harborstone", "hilltop", "honeycomb", "island",
106
+ "kestrelwing", "lake", "leafwing", "marigold", "moonstone", "morning",
17
107
  ];
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@twardoch/namzy",
3
- "version": "0.1.0",
3
+ "version": "1.0.11",
4
4
  "description": "Generates fun fused human-friendly project names",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "bin": {
10
- "namzy": "./dist/cli.js"
10
+ "namzy": "dist/cli.js"
11
11
  },
12
12
  "files": [
13
13
  "dist",
package/src/cli.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  // this_file: src/cli.ts
3
3
 
4
4
  import { generate } from "./index.js";
5
- import type { NamzyOptions } from "./index.js";
6
5
 
7
6
  const HELP = `
8
7
  namzy — generate fun fused project names
@@ -11,19 +10,16 @@ Usage:
11
10
  namzy [options]
12
11
 
13
12
  Options:
14
- --online Fetch words from a public API (falls back to offline)
15
13
  --count <N> Number of names to generate (default: 1)
16
14
  --help Show this help
17
15
 
18
16
  Examples:
19
17
  namzy
20
18
  namzy --count 5
21
- namzy --online --count 3
22
19
  `.trimStart();
23
20
 
24
- function parseArgs(argv: string[]): { opts: NamzyOptions; count: number } {
21
+ function parseArgs(argv: string[]): { count: number } {
25
22
  const args = argv.slice(2);
26
- const opts: NamzyOptions = {};
27
23
  let count = 1;
28
24
 
29
25
  for (let i = 0; i < args.length; i++) {
@@ -34,12 +30,9 @@ function parseArgs(argv: string[]): { opts: NamzyOptions; count: number } {
34
30
  process.stdout.write(HELP);
35
31
  process.exit(0);
36
32
  break;
37
- case "--online":
38
- opts.online = true;
39
- break;
40
33
  case "--count": {
41
34
  const n = parseInt(args[++i], 10);
42
- if (isNaN(n) || n < 1) {
35
+ if (Number.isNaN(n) || n < 1) {
43
36
  process.stderr.write(`--count must be a positive integer\n`);
44
37
  process.exit(1);
45
38
  }
@@ -51,15 +44,15 @@ function parseArgs(argv: string[]): { opts: NamzyOptions; count: number } {
51
44
  process.exit(1);
52
45
  }
53
46
  }
54
- return { opts, count };
47
+ return { count };
55
48
  }
56
49
 
57
50
  async function main(): Promise<void> {
58
- const { opts, count } = parseArgs(process.argv);
51
+ const { count } = parseArgs(process.argv);
59
52
  const base = Date.now();
60
53
  for (let i = 0; i < count; i++) {
61
- const name = await generate({ ...opts, seed: base + i * 1337 });
62
- process.stdout.write(name + "\n");
54
+ const name = await generate({ seed: base + i * 1337 });
55
+ process.stdout.write(`${name}\n`);
63
56
  }
64
57
  }
65
58
 
package/src/index.ts CHANGED
@@ -1,28 +1,18 @@
1
1
  // this_file: src/index.ts
2
2
 
3
- import { GEO, COMMON } from "./wordlist.js";
4
- import { mangle, mulberry32, joinClean } from "./mangle.js";
3
+ import { joinClean, mangle, mulberry32 } from "./mangle.js";
4
+ import { COMMON, GEO } from "./wordlist.js";
5
5
 
6
6
  export interface NamzyOptions {
7
- online?: boolean;
8
- seed?: number;
7
+ seed?: number;
9
8
  }
10
9
 
11
10
  function capitalize(s: string): string {
12
- return s.charAt(0).toUpperCase() + s.slice(1);
11
+ return s.charAt(0).toUpperCase() + s.slice(1);
13
12
  }
14
13
 
15
14
  function pick<T>(arr: T[], rng: () => number): T {
16
- return arr[Math.floor(rng() * arr.length)];
17
- }
18
-
19
- async function fetchOnlineWords(): Promise<string[]> {
20
- const url = `https://random-word-api.herokuapp.com/word?number=2&length=6`;
21
- const resp = await fetch(url);
22
- if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
23
- const data = (await resp.json()) as string[];
24
- if (!Array.isArray(data) || data.length < 2) throw new Error("Bad response");
25
- return data.slice(0, 2).map((w) => w.toLowerCase().replace(/[^a-z]/g, ""));
15
+ return arr[Math.floor(rng() * arr.length)];
26
16
  }
27
17
 
28
18
  /**
@@ -30,29 +20,16 @@ async function fetchOnlineWords(): Promise<string[]> {
30
20
  * Two raw words → junction-cleaned fusion → consonant rotation → capitalize.
31
21
  */
32
22
  export async function generate(opts?: NamzyOptions): Promise<string> {
33
- const online = opts?.online ?? false;
34
- const seed = opts?.seed ?? Date.now();
35
- const rng = mulberry32(seed);
36
-
37
- let w1: string;
38
- let w2: string;
39
-
40
- if (online) {
41
- try {
42
- const words = await fetchOnlineWords();
43
- [w1, w2] = words;
44
- } catch {
45
- w1 = pick(GEO, rng).toLowerCase();
46
- w2 = pick(COMMON, rng).toLowerCase();
47
- }
48
- } else {
49
- w1 = pick(GEO, rng).toLowerCase();
50
- w2 = pick(COMMON, rng).toLowerCase();
51
- }
52
-
53
- const fused = joinClean(w1, w2);
54
- return capitalize(mangle(fused));
23
+ const seed = opts?.seed ?? Date.now();
24
+ const rng = mulberry32(seed);
25
+
26
+ const w1 = pick(GEO, rng).toLowerCase();
27
+ const w2 = pick(COMMON, rng).toLowerCase();
28
+ const [first, second] = rng() < 0.5 ? [w1, w2] : [w2, w1];
29
+
30
+ const fused = joinClean(first, second);
31
+ return capitalize(mangle(fused));
55
32
  }
56
33
 
57
- export { mangle, joinClean, mulberry32 };
58
- export { GEO, COMMON } from "./wordlist.js";
34
+ export { COMMON, GEO } from "./wordlist.js";
35
+ export { joinClean, mangle, mulberry32 };
package/src/wordlist.ts CHANGED
@@ -1,19 +1,109 @@
1
1
  // this_file: src/wordlist.ts
2
2
 
3
- /** Geographic names (A-Za-z only, no diacritics) */
3
+ /** Geographic names (A-Za-z only, no diacritics). Shared across all implementations. */
4
4
  export const GEO: string[] = [
5
- "tokyo", "paris", "oslo", "berlin", "lagos", "lima", "boston", "vienna",
6
- "cairo", "kyoto", "dubai", "seoul", "milan", "tunis", "perth", "genoa",
7
- "porto", "bruges", "ghent", "brest", "minsk", "sofia", "riga", "lyon",
8
- "basel", "natal", "recife", "darwin", "hobart", "odessa", "varna", "Split",
9
- "kotor", "tiran", "skopje", "bitola", "plovdiv", "gabrovo", "varna", "ruse",
5
+ "tokyo", "paris", "oslo", "berlin", "lagos", "lima",
6
+ "boston", "vienna", "cairo", "kyoto", "dubai", "seoul",
7
+ "milan", "tunis", "perth", "genoa", "porto", "bruges",
8
+ "ghent", "brest", "minsk", "sofia", "riga", "lyon",
9
+ "basel", "natal", "recife", "darwin", "hobart", "odessa",
10
+ "varna", "split", "kotor", "tirana", "skopje", "bitola",
11
+ "plovdiv", "gabrovo", "ruse", "delhi", "rome", "athens",
12
+ "nairobi", "bali", "havana", "lisbon", "bogota", "dakar",
13
+ "quito", "vilnius", "vaduz", "bern", "accra", "kigali",
14
+ "abuja", "bamako", "niamey", "lome", "prague", "dublin",
15
+ "naples", "tulum", "tbilisi", "yerevan", "astana", "lusaka",
16
+ "harare", "asmara", "manaus", "cuenca", "merida", "geneva",
17
+ "zurich", "venice", "sydney", "denver", "austin", "phoenix",
18
+ "tucson", "reno", "boise", "fargo", "tulsa", "tampa",
19
+ "miami", "salem", "dover", "trenton", "helena", "juneau",
20
+ "topeka", "albany", "amsterdam", "antwerp", "arusha", "aspen",
21
+ "atlanta", "auckland", "baghdad", "baku", "bangkok", "barcelona",
22
+ "beijing", "beirut", "belfast", "belgrade", "bergen", "bilbao",
23
+ "bordeaux", "braga", "brisbane", "bristol", "brussels", "bucharest",
24
+ "budapest", "calgary", "canberra", "cardiff", "casablanca", "chicago",
25
+ "cologne", "colombo", "copenhagen", "cork", "dresden", "durban",
26
+ "edinburgh", "florence", "frankfurt", "gdansk", "glasgow", "granada",
27
+ "guangzhou", "hamburg", "hanoi", "helsinki", "houston", "jakarta",
28
+ "jerusalem", "karachi", "krakow", "kuwait", "leipzig", "lille",
29
+ "london", "luanda", "lucerne", "madrid", "malaga", "manila",
30
+ "marrakesh", "marseille", "melbourne", "memphis", "montreal", "moscow",
31
+ "munich", "nagoya", "nantes", "napier", "nashville", "orlando",
32
+ "osaka", "ottawa", "palermo", "panama", "phuket", "pisa",
33
+ "poznan", "quebec", "reykjavik", "rotterdam", "sarajevo", "sapporo",
34
+ "sevilla", "shanghai", "stockholm", "suzhou", "swansea", "taipei",
35
+ "tallinn", "tangier", "tehran", "thimphu", "toronto", "toulouse",
36
+ "trieste", "valencia", "vancouver", "verona", "warsaw", "winnipeg",
37
+ "wroclaw", "zagreb", "aarhus", "abidjan", "adelaide", "alger",
38
+ "annaba", "ankara", "antalya", "arezzo", "asuncion", "avignon",
39
+ "baltimore", "banjul", "belem", "bologna", "bremen", "cancun",
40
+ "caracas", "cartagena", "catania", "charlotte", "chennai", "chiangmai",
41
+ "cleveland", "cordoba", "curitiba", "cusco", "dallas", "damascus",
42
+ "dundee", "espoo", "fez", "freetown", "fukuoka", "funchal",
43
+ "gothenburg", "guayaquil", "haifa", "halifax", "hamilton", "honolulu",
44
+ "ibadan", "innsbruck", "izmir", "jaipur", "jeddah", "kampala",
45
+ "kansas", "kashgar", "kathmandu", "khartoum", "kingston", "kinshasa",
46
+ "koblenz", "kortrijk", "lahti", "lausanne", "leeds", "leuven",
47
+ "liege", "liverpool", "ljubljana", "lodz", "luxor", "macao",
48
+ "madison", "malmo", "manchester", "mandalay", "maputo", "mendoza",
49
+ "monterrey", "montevideo", "nicosia", "noumea", "nuremberg", "okinawa",
50
+ "omaha", "padua", "penang", "peshawar", "portland", "pretoria",
51
+ "rabat", "raleigh", "rennes", "richmond", "salzburg", "samarkand",
52
+ "santander", "santiago", "sendai", "singapore", "skagen", "stavanger",
53
+ "stuttgart", "surabaya", "suva", "tampere", "taranto", "tarragona",
54
+ "tiruchirappalli", "trondheim", "utrecht", "valletta", "victoria", "vigo",
10
55
  ];
11
56
 
12
- /** Common evocative English words */
57
+ /** Common evocative English words. Shared across all implementations. */
13
58
  export const COMMON: string[] = [
14
- "river", "stone", "ember", "frost", "harbor", "willow", "copper", "marble",
15
- "anchor", "lantern", "cedar", "falcon", "coral", "dagger", "flint", "grove",
16
- "haven", "iron", "jasper", "kelp", "larch", "mast", "nettle", "oak",
17
- "pine", "quill", "reed", "sage", "thorn", "umber", "vale", "wren",
18
- "yarrow", "zenith", "amber", "birch", "cliff", "drift", "forge", "glade",
59
+ "river", "stone", "ember", "frost", "harbor", "willow",
60
+ "copper", "marble", "anchor", "lantern", "cedar", "falcon",
61
+ "coral", "dagger", "flint", "grove", "haven", "iron",
62
+ "jasper", "kelp", "larch", "mast", "nettle", "oak",
63
+ "pine", "quill", "reed", "sage", "thorn", "umber",
64
+ "vale", "wren", "yarrow", "zenith", "amber", "birch",
65
+ "cliff", "drift", "forge", "glade", "mesa", "canyon",
66
+ "basin", "fern", "gale", "peak", "ridge", "shore",
67
+ "tide", "bluff", "brook", "crest", "delta", "glen",
68
+ "helm", "inlet", "jetty", "knoll", "loft", "moor",
69
+ "notch", "orbit", "prism", "thunder", "silver", "meadow",
70
+ "basalt", "summit", "valley", "bridge", "beacon", "ranger",
71
+ "timber", "clover", "pebble", "ripple", "canopy", "chimney",
72
+ "cinder", "comet", "ferret", "glider", "jaguar", "kernel",
73
+ "lancer", "mortar", "nebula", "osprey", "patrol", "quartz",
74
+ "rafter", "sparrow", "granite", "hazel", "kindle", "laurel",
75
+ "mossy", "nimble", "ochre", "russet", "sable", "vapor",
76
+ "wicker", "cobalt", "dune", "hollow", "ivy", "juniper",
77
+ "linden", "mist", "oyster", "acorn", "anvil", "apron",
78
+ "arrow", "ash", "atlas", "autumn", "badge", "banner",
79
+ "beryl", "blossom", "boulder", "bramble", "brass", "breeze",
80
+ "briar", "bronze", "brooklet", "buckle", "burl", "cairn",
81
+ "candle", "canvas", "cavern", "chalk", "charm", "citrine",
82
+ "cloud", "cloverleaf", "cobaltcore", "compass", "copperleaf", "cradle",
83
+ "cricket", "crystal", "daisy", "dale", "dawn", "deerden",
84
+ "desert", "dew", "diamond", "dovetail", "dragonfly", "dream",
85
+ "drifter", "dunecrest", "dusk", "echo", "elm", "fernleaf",
86
+ "firefly", "fjord", "flame", "flower", "flume", "forest",
87
+ "foxglove", "garden", "garnet", "geode", "glacier", "glimmer",
88
+ "goldfinch", "gravel", "greenwood", "griffin", "harborlight", "hearth",
89
+ "heather", "heron", "hill", "honey", "horizon", "icicle",
90
+ "ivory", "jewel", "kestrel", "lagoon", "laurelwood", "leaf",
91
+ "lighthouse", "lilac", "lotus", "meadowlark", "moon", "moss",
92
+ "myrtle", "nectar", "nightingale", "obsidian", "olive", "opal",
93
+ "orchard", "otter", "pebblebrook", "petal", "plume", "prairie",
94
+ "rain", "raven", "redwood", "reef", "ribbon", "root",
95
+ "rose", "ruby", "sail", "salt", "sapphire", "scarlet",
96
+ "seabird", "sequoia", "shadow", "shale", "shell", "shimmer",
97
+ "skylark", "slate", "smoke", "snow", "sparrowhawk", "spindle",
98
+ "spirit", "spring", "spruce", "star", "starlight", "storm",
99
+ "stream", "sunbeam", "sunset", "sycamore", "talon", "thicket",
100
+ "thistle", "thunderhead", "tidepool", "topaz", "trail", "valleyfield",
101
+ "velvet", "violet", "walnut", "waterfall", "wave", "wind",
102
+ "winter", "wolfram", "woodland", "zephyr", "ashwood", "bell",
103
+ "bird", "bloom", "branch", "bright", "brookside", "camp",
104
+ "campfire", "castle", "chime", "clay", "cloudbank", "coast",
105
+ "copperwood", "creek", "crown", "emberfall", "field", "firestone",
106
+ "flag", "fog", "fox", "gardenia", "gate", "glow",
107
+ "grass", "grovewood", "harborstone", "hilltop", "honeycomb", "island",
108
+ "kestrelwing", "lake", "leafwing", "marigold", "moonstone", "morning",
19
109
  ];