loredata 0.1.0 → 0.3.0
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 +72 -21
- package/data/avengers/addresses.json +27 -0
- package/data/avengers/characters.json +178 -0
- package/data/avengers/meta.json +13 -0
- package/data/better-call-saul/addresses.json +37 -0
- package/data/better-call-saul/characters.json +156 -0
- package/data/better-call-saul/meta.json +13 -0
- package/data/big-bang-theory/addresses.json +31 -0
- package/data/big-bang-theory/characters.json +121 -0
- package/data/big-bang-theory/meta.json +13 -0
- package/data/breaking-bad/characters.json +49 -13
- package/data/breaking-bad/meta.json +10 -1
- package/data/fast-and-furious/characters.json +39 -13
- package/data/fast-and-furious/meta.json +15 -1
- package/data/friends/characters.json +138 -22
- package/data/friends/meta.json +13 -1
- package/data/game-of-thrones/characters.json +61 -16
- package/data/game-of-thrones/meta.json +10 -1
- package/data/guardians-of-the-galaxy/addresses.json +17 -0
- package/data/guardians-of-the-galaxy/characters.json +124 -0
- package/data/guardians-of-the-galaxy/meta.json +13 -0
- package/data/harry-potter/characters.json +37 -7
- package/data/harry-potter/meta.json +10 -1
- package/data/house-md/characters.json +79 -25
- package/data/house-md/meta.json +13 -1
- package/data/lost/characters.json +144 -36
- package/data/lost/meta.json +13 -1
- package/data/matrix/characters.json +133 -34
- package/data/matrix/meta.json +18 -1
- package/data/peaky-blinders/characters.json +44 -11
- package/data/peaky-blinders/meta.json +13 -1
- package/data/prison-break/addresses.json +24 -0
- package/data/prison-break/characters.json +116 -0
- package/data/prison-break/meta.json +13 -0
- package/data/sherlock/characters.json +116 -27
- package/data/sherlock/meta.json +13 -1
- package/data/simpsons/addresses.json +21 -0
- package/data/simpsons/characters.json +219 -0
- package/data/simpsons/meta.json +13 -0
- package/data/sopranos/addresses.json +37 -0
- package/data/sopranos/characters.json +184 -0
- package/data/sopranos/meta.json +13 -0
- package/data/south-park/addresses.json +31 -0
- package/data/south-park/characters.json +230 -0
- package/data/south-park/meta.json +13 -0
- package/data/spider-man/addresses.json +31 -0
- package/data/spider-man/characters.json +134 -0
- package/data/spider-man/meta.json +13 -0
- package/data/star-wars/addresses.json +19 -0
- package/data/star-wars/characters.json +153 -0
- package/data/star-wars/meta.json +13 -0
- package/data/supernatural/addresses.json +25 -0
- package/data/supernatural/characters.json +113 -0
- package/data/supernatural/meta.json +13 -0
- package/data/the-office/characters.json +84 -29
- package/data/the-office/meta.json +10 -1
- package/data/the-walking-dead/addresses.json +25 -0
- package/data/the-walking-dead/characters.json +114 -0
- package/data/the-walking-dead/meta.json +13 -0
- package/data/westworld/addresses.json +19 -0
- package/data/westworld/characters.json +108 -0
- package/data/westworld/meta.json +13 -0
- package/data/x-men/addresses.json +24 -0
- package/data/x-men/characters.json +158 -0
- package/data/x-men/meta.json +18 -0
- package/dist/browser.cjs +114 -69
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +7 -3
- package/dist/browser.d.ts +7 -3
- package/dist/browser.js +110 -69
- package/dist/browser.js.map +1 -1
- package/dist/cli/cli.cjs +131 -70
- package/dist/cli/cli.cjs.map +1 -1
- package/dist/cli/cli.js +132 -71
- package/dist/cli/cli.js.map +1 -1
- package/dist/index.cjs +132 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.js +132 -69
- package/dist/index.js.map +1 -1
- package/dist/{universe-store-DJrm7bP7.d.cts → universe-store-CWhCn3U6.d.cts} +31 -19
- package/dist/{universe-store-DJrm7bP7.d.ts → universe-store-CWhCn3U6.d.ts} +31 -19
- package/package.json +12 -4
- package/data/breaking-bad/domains.json +0 -6
- package/data/fast-and-furious/domains.json +0 -6
- package/data/friends/domains.json +0 -6
- package/data/game-of-thrones/domains.json +0 -6
- package/data/harry-potter/domains.json +0 -6
- package/data/house-md/domains.json +0 -6
- package/data/lost/domains.json +0 -6
- package/data/matrix/domains.json +0 -6
- package/data/peaky-blinders/domains.json +0 -6
- package/data/sherlock/domains.json +0 -6
- package/data/the-office/domains.json +0 -6
package/dist/browser.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser.ts","../src/generators/random.ts","../src/generators/email.ts","../src/generators/phone.ts","../src/generators/password.ts","../src/engine/person-factory.ts","../src/engine/universe-store.ts","../src/universes/browser-loader.ts"],"sourcesContent":["import { PersonFactory } from '@/engine/person-factory';\nimport { UniverseStore } from '@/engine/universe-store';\n\nimport type { Person, UniverseData } from '@/types';\n\nexport { UniverseStore };\nexport { loadUniverse, loadUniverses, loadAllUniverses, getAvailableIds } from '@/universes/browser-loader';\n\nexport function personFromData(universe: UniverseData, seed?: number): Person {\n\treturn PersonFactory.build(universe, seed);\n}\n\nexport type { Person, UniverseInfo } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n","/**\n * Seeded pseudo-random number generator (mulberry32).\n * Returns a function that produces values in [0, 1).\n */\nexport function createRng(seed?: number): () => number {\n\tif (seed === undefined) {\n\t\treturn Math.random;\n\t}\n\n\tlet s = seed;\n\n\treturn function rng(): number {\n\t\ts += 0x6d2b79f5;\n\t\tlet z = s;\n\t\tz = Math.imul(z ^ (z >>> 15), z | 1);\n\t\tz ^= z + Math.imul(z ^ (z >>> 7), z | 61);\n\n\t\treturn ((z ^ (z >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\nexport function pickRandom<T>(array: T[], rng: () => number): T {\n\tconst index = Math.floor(rng() * array.length);\n\n\treturn array[index];\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class EmailGenerator {\n\tstatic generate(firstName: string, lastName: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\t\tconst first = firstName.toLowerCase();\n\t\tconst last = lastName.toLowerCase();\n\n\t\treturn `${first}.${last}@${domain}`;\n\t}\n\n\tstatic generateFromUsername(username: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PhoneGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {\n\t\t\treturn pickRandom(domains.phoneEasterEggs, rng);\n\t\t}\n\n\t\tconst prefix = pickRandom(domains.phonePrefixes, rng);\n\t\tconst suffix = this.randomDigits(7, rng);\n\n\t\treturn `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;\n\t}\n\n\tprivate static randomDigits(count: number, rng: () => number): string {\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult += Math.floor(rng() * 10).toString();\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PasswordGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {\n\t\t\treturn pickRandom(domains.passwordEasterEggs, rng);\n\t\t}\n\n\t\treturn this.randomPassword(12, rng);\n\t}\n\n\tprivate static randomPassword(length: number, rng: () => number): string {\n\t\tconst chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$';\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars[Math.floor(rng() * chars.length)];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator, PhoneGenerator, PasswordGenerator } from '@/generators';\n\nimport type { Person, UniverseData, CharacterData } from '@/types';\n\nexport class PersonFactory {\n\tstatic build(universe: UniverseData, seed?: number): Person {\n\t\tconst rng = createRng(seed);\n\n\t\tconst character = pickRandom(universe.characters, rng);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildByCharacterId(characterId: string, universe: UniverseData, seed?: number): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tprivate static buildFromCharacter(character: CharacterData, universe: UniverseData, rng: () => number): Person {\n\t\tconst address = character.address ?? pickRandom(universe.addresses, rng);\n\n\t\tconst username = pickRandom(character.usernames, rng);\n\n\t\tconst domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;\n\n\t\tconst email = EmailGenerator.generateFromUsername(username, domains, rng);\n\t\tconst phone = PhoneGenerator.generate(universe.domains, rng);\n\t\tconst password = PasswordGenerator.generate(universe.domains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\n\t\tconst avatarName = encodeURIComponent(`${character.firstName} ${character.lastName}`);\n\t\tconst avatar = `https://ui-avatars.com/api/?name=${avatarName}&background=random`;\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\tpassword,\n\t\t\tphone,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\tavatar\n\t\t};\n\n\t\treturn person;\n\t}\n}\n","import { createRng } from '@/generators';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { UniverseData, Person, CharacterEntry, CharacterQuery } from '@/types';\n\nexport class UniverseStore {\n\tprivate universes: UniverseData[];\n\tprivate characterIndex: CharacterEntry[];\n\n\tconstructor(universes: UniverseData[]) {\n\t\tthis.universes = universes;\n\t\tthis.characterIndex = this.buildIndex(universes);\n\t}\n\n\tget index(): CharacterEntry[] {\n\t\treturn this.characterIndex;\n\t}\n\n\tgetInterests(universeIds?: string[]): string[] {\n\t\tconst entries =\n\t\t\tuniverseIds && universeIds.length > 0\n\t\t\t\t? this.characterIndex.filter((e) => universeIds.includes(e.universeId))\n\t\t\t\t: this.characterIndex;\n\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const entry of entries) {\n\t\t\tfor (const interest of entry.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(interestSet).sort();\n\n\t\treturn result;\n\t}\n\n\tgetUniverses(): { id: string; name: string; characterCount: number }[] {\n\t\tconst result = this.universes.map((u) => ({\n\t\t\tid: u.id,\n\t\t\tname: u.name,\n\t\t\tcharacterCount: u.characters.length\n\t\t}));\n\n\t\treturn result;\n\t}\n\n\tfindCharacters(query: CharacterQuery): CharacterEntry[] {\n\t\tlet entries = this.characterIndex;\n\n\t\tif (query.universes && query.universes.length > 0) {\n\t\t\tentries = entries.filter((e) => query.universes!.includes(e.universeId));\n\t\t}\n\n\t\tif (query.name && query.name.trim().length > 0) {\n\t\t\tconst needle = query.name.toLowerCase();\n\n\t\t\tentries = entries.filter((e) => {\n\t\t\t\tconst fullName = `${e.firstName} ${e.lastName}`.toLowerCase();\n\n\t\t\t\treturn fullName.includes(needle);\n\t\t\t});\n\t\t}\n\n\t\tif (query.interests && query.interests.length > 0) {\n\t\t\tconst mode = query.interestsMode ?? 'or';\n\n\t\t\tif (mode === 'and') {\n\t\t\t\tentries = entries.filter((e) => query.interests!.every((interest) => e.interests.includes(interest)));\n\t\t\t} else {\n\t\t\t\tentries = entries.filter((e) => query.interests!.some((interest) => e.interests.includes(interest)));\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpersonByCharacterId(characterId: string, seed?: number): Person {\n\t\tconst entry = this.characterIndex.find((e) => e.characterId === characterId);\n\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in store`);\n\t\t}\n\n\t\tconst universe = this.universes.find((u) => u.id === entry.universeId);\n\n\t\tif (!universe) {\n\t\t\tthrow new Error(`Universe \"${entry.universeId}\" not found in store`);\n\t\t}\n\n\t\treturn PersonFactory.buildByCharacterId(characterId, universe, seed);\n\t}\n\n\tgeneratePersonas(query: CharacterQuery, count: number, seed?: number): Person[] {\n\t\tconst matching = this.findCharacters(query);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\t\tconst actualCount = Math.min(count, matching.length);\n\n\t\tconst shuffled = [...matching].sort(() => rng() - 0.5);\n\t\tconst selected = shuffled.slice(0, actualCount);\n\t\tconst personas: Person[] = [];\n\n\t\tfor (let i = 0; i < selected.length; i++) {\n\t\t\tconst entry = selected[i];\n\t\t\tconst universe = this.universes.find((u) => u.id === entry.universeId)!;\n\t\t\tconst personSeed = seed !== undefined ? seed + i : undefined;\n\n\t\t\tpersonas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));\n\t\t}\n\n\t\treturn personas;\n\t}\n\n\tprivate buildIndex(universes: UniverseData[]): CharacterEntry[] {\n\t\tconst index: CharacterEntry[] = [];\n\n\t\tfor (const universe of universes) {\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tconst entry: CharacterEntry = {\n\t\t\t\t\tcharacterId: character.id,\n\t\t\t\t\tuniverseId: universe.id,\n\t\t\t\t\tuniverseName: universe.name,\n\t\t\t\t\tfirstName: character.firstName,\n\t\t\t\t\tlastName: character.lastName,\n\t\t\t\t\tinterests: character.interests,\n\t\t\t\t\tprofession: character.profession\n\t\t\t\t};\n\n\t\t\t\tindex.push(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t}\n}\n","import type { UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\n\ninterface MetaJson {\n\tid: string;\n\tname: string;\n}\n\nconst metaModules = import.meta.glob('../data/*/meta.json', { eager: false });\nconst characterModules = import.meta.glob('../data/*/characters.json', { eager: false });\nconst addressModules = import.meta.glob('../data/*/addresses.json', { eager: false });\nconst domainModules = import.meta.glob('../data/*/domains.json', { eager: false });\n\nfunction extractId(path: string): string {\n\tconst parts = path.split('/');\n\n\treturn parts[parts.length - 2];\n}\n\nexport function getAvailableIds(): string[] {\n\treturn Object.keys(metaModules).map(extractId);\n}\n\nexport async function loadUniverse(id: string): Promise<UniverseData> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst charactersPath = `../data/${id}/characters.json`;\n\tconst addressesPath = `../data/${id}/addresses.json`;\n\tconst domainsPath = `../data/${id}/domains.json`;\n\n\tconst metaLoader = metaModules[metaPath];\n\tconst charactersLoader = characterModules[charactersPath];\n\tconst addressesLoader = addressModules[addressesPath];\n\tconst domainsLoader = domainModules[domainsPath];\n\n\tif (!metaLoader || !charactersLoader || !addressesLoader || !domainsLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst [metaModule, charactersModule, addressesModule, domainsModule] = await Promise.all([\n\t\tmetaLoader(),\n\t\tcharactersLoader(),\n\t\taddressesLoader(),\n\t\tdomainsLoader()\n\t]);\n\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\tconst characters = (charactersModule as { default: CharacterData[] }).default;\n\tconst addresses = (addressesModule as { default: AddressData[] }).default;\n\tconst domains = (domainsModule as { default: DomainsData }).default;\n\n\tconst universeData: UniverseData = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tcharacters,\n\t\taddresses,\n\t\tdomains\n\t};\n\n\treturn universeData;\n}\n\nexport async function loadUniverses(ids: string[]): Promise<UniverseData[]> {\n\tconst result = await Promise.all(ids.map((id) => loadUniverse(id)));\n\n\treturn result;\n}\n\nexport async function loadAllUniverses(): Promise<UniverseData[]> {\n\tconst ids = getAvailableIds();\n\n\treturn loadUniverses(ids);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/browser.ts","../src/generators/random.ts","../src/generators/email.ts","../src/engine/person-factory.ts","../src/engine/universe-store.ts","../src/universes/browser-loader.ts"],"sourcesContent":["import { PersonFactory } from '@/engine/person-factory';\nimport { UniverseStore } from '@/engine/universe-store';\n\nimport type { Person, UniverseData } from '@/types';\n\nexport { UniverseStore };\nexport {\n\tloadUniverse,\n\tloadUniverses,\n\tloadAllUniverses,\n\tloadUniverseMeta,\n\tgetManifest,\n\tgetAllInterests,\n\tgetAllLocations,\n\tgetAvailableIds\n} from '@/universes/browser-loader';\n\nexport function personFromData(universe: UniverseData, seed?: number): Person {\n\treturn PersonFactory.build(universe, seed);\n}\n\nexport type { Person, UniverseMeta } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n","/**\n * Seeded pseudo-random number generator (mulberry32).\n * Returns a function that produces values in [0, 1).\n */\nexport function createRng(seed?: number): () => number {\n\tif (seed === undefined) {\n\t\treturn Math.random;\n\t}\n\n\tlet s = seed;\n\n\treturn function rng(): number {\n\t\ts += 0x6d2b79f5;\n\t\tlet z = s;\n\t\tz = Math.imul(z ^ (z >>> 15), z | 1);\n\t\tz ^= z + Math.imul(z ^ (z >>> 7), z | 61);\n\n\t\treturn ((z ^ (z >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\nexport function pickRandom<T>(array: T[], rng: () => number): T {\n\tconst index = Math.floor(rng() * array.length);\n\n\treturn array[index];\n}\n","import { pickRandom } from './random';\n\nexport class EmailGenerator {\n\tstatic generateFromUsername(username: string, emailDomains: string[], rng: () => number): string {\n\t\tconst domain = pickRandom(emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator } from '@/generators';\n\nimport type { Person, UniverseData, CharacterData } from '@/types';\n\nexport class PersonFactory {\n\tstatic build(universe: UniverseData, seed?: number): Person {\n\t\tconst rng = createRng(seed);\n\n\t\tconst character = pickRandom(universe.characters, rng);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildByCharacterId(characterId: string, universe: UniverseData, seed?: number): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildCanonical(characterId: string, universe: UniverseData): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst rng = createRng(0);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = character.quotes[0];\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\n\t}\n\n\tprivate static buildFromCharacter(character: CharacterData, universe: UniverseData, rng: () => number): Person {\n\t\tconst address = character.address ?? pickRandom(universe.addresses, rng);\n\t\tconst username = pickRandom(character.usernames, rng);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\n\t}\n}\n","import { createRng } from '@/generators';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { UniverseData, UniverseMeta, Person, CharacterEntry, CharacterQuery } from '@/types';\n\nexport class UniverseStore {\n\tprivate universes: UniverseData[];\n\tprivate characterIndex: CharacterEntry[];\n\n\tconstructor(universes: UniverseData[]) {\n\t\tthis.universes = universes;\n\t\tthis.characterIndex = this.buildIndex(universes);\n\t}\n\n\tget index(): CharacterEntry[] {\n\t\treturn this.characterIndex;\n\t}\n\n\tgetInterests(universeIds?: string[]): string[] {\n\t\tconst entries =\n\t\t\tuniverseIds && universeIds.length > 0\n\t\t\t\t? this.characterIndex.filter((e) => universeIds.includes(e.universeId))\n\t\t\t\t: this.characterIndex;\n\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const entry of entries) {\n\t\t\tfor (const interest of entry.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(interestSet).sort();\n\n\t\treturn result;\n\t}\n\n\tgetUniverses(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tfindCharacters(query: CharacterQuery): CharacterEntry[] {\n\t\tlet entries = this.characterIndex;\n\n\t\tif (query.universes && query.universes.length > 0) {\n\t\t\tentries = entries.filter((e) => query.universes!.includes(e.universeId));\n\t\t}\n\n\t\tif (query.name && query.name.trim().length > 0) {\n\t\t\tconst needle = query.name.toLowerCase();\n\n\t\t\tentries = entries.filter((e) => {\n\t\t\t\tconst fullName = `${e.firstName} ${e.lastName}`.toLowerCase();\n\n\t\t\t\treturn fullName.includes(needle);\n\t\t\t});\n\t\t}\n\n\t\tif (query.interests && query.interests.length > 0) {\n\t\t\tconst mode = query.interestsMode ?? 'or';\n\n\t\t\tif (mode === 'and') {\n\t\t\t\tentries = entries.filter((e) => query.interests!.every((interest) => e.interests.includes(interest)));\n\t\t\t} else {\n\t\t\t\tentries = entries.filter((e) => query.interests!.some((interest) => e.interests.includes(interest)));\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpersonByCharacterId(characterId: string, seed?: number): Person {\n\t\tconst entry = this.characterIndex.find((e) => e.characterId === characterId);\n\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in store`);\n\t\t}\n\n\t\tconst universe = this.universes.find((u) => u.id === entry.universeId);\n\n\t\tif (!universe) {\n\t\t\tthrow new Error(`Universe \"${entry.universeId}\" not found in store`);\n\t\t}\n\n\t\treturn PersonFactory.buildByCharacterId(characterId, universe, seed);\n\t}\n\n\tgeneratePersonas(query: CharacterQuery, count: number, seed?: number): Person[] {\n\t\tconst matching = this.findCharacters(query);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\t\tconst actualCount = Math.min(count, matching.length);\n\n\t\tconst shuffled = [...matching].sort(() => rng() - 0.5);\n\t\tconst selected = shuffled.slice(0, actualCount);\n\t\tconst personas: Person[] = [];\n\n\t\tfor (let i = 0; i < selected.length; i++) {\n\t\t\tconst entry = selected[i];\n\t\t\tconst universe = this.universes.find((u) => u.id === entry.universeId)!;\n\t\t\tconst personSeed = seed !== undefined ? seed + i : undefined;\n\n\t\t\tpersonas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));\n\t\t}\n\n\t\treturn personas;\n\t}\n\n\tprivate buildIndex(universes: UniverseData[]): CharacterEntry[] {\n\t\tconst index: CharacterEntry[] = [];\n\n\t\tfor (const universe of universes) {\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tconst entry: CharacterEntry = {\n\t\t\t\t\tcharacterId: character.id,\n\t\t\t\t\tuniverseId: universe.id,\n\t\t\t\t\tuniverseName: universe.name,\n\t\t\t\t\tfirstName: character.firstName,\n\t\t\t\t\tlastName: character.lastName,\n\t\t\t\t\tinterests: character.interests,\n\t\t\t\t\tprofession: character.profession\n\t\t\t\t};\n\n\t\t\t\tindex.push(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t}\n}\n","import type { UniverseData, UniverseMeta, CharacterData, AddressData, LocationEntry } from '@/types';\n\ninterface MetaJson {\n\tid: string;\n\tname: string;\n\tgenre: string[];\n\tdescription: string;\n}\n\nconst metaModules = import.meta.glob('../data/*/meta.json', { eager: false });\nconst characterModules = import.meta.glob('../data/*/characters.json', { eager: false });\nconst addressModules = import.meta.glob('../data/*/addresses.json', { eager: false });\n\nfunction extractId(path: string): string {\n\tconst parts = path.split('/');\n\n\treturn parts[parts.length - 2];\n}\n\nexport function getAvailableIds(): string[] {\n\treturn Object.keys(metaModules).map(extractId);\n}\n\nexport async function loadUniverseMeta(id: string): Promise<UniverseMeta> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst metaLoader = metaModules[metaPath];\n\n\tif (!metaLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst metaModule = await metaLoader();\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\n\tconst result: UniverseMeta = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tgenre: meta.genre,\n\t\tdescription: meta.description\n\t};\n\n\treturn result;\n}\n\nexport async function getManifest(): Promise<UniverseMeta[]> {\n\tconst ids = getAvailableIds();\n\tconst result = await Promise.all(ids.map((id) => loadUniverseMeta(id)));\n\n\treturn result;\n}\n\nexport async function loadUniverse(id: string): Promise<UniverseData> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst charactersPath = `../data/${id}/characters.json`;\n\tconst addressesPath = `../data/${id}/addresses.json`;\n\n\tconst metaLoader = metaModules[metaPath];\n\tconst charactersLoader = characterModules[charactersPath];\n\tconst addressesLoader = addressModules[addressesPath];\n\n\tif (!metaLoader || !charactersLoader || !addressesLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst [metaModule, charactersModule, addressesModule] = await Promise.all([\n\t\tmetaLoader(),\n\t\tcharactersLoader(),\n\t\taddressesLoader()\n\t]);\n\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\tconst characters = (charactersModule as { default: CharacterData[] }).default;\n\tconst addresses = (addressesModule as { default: AddressData[] }).default;\n\n\tconst universeData: UniverseData = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tgenre: meta.genre,\n\t\tdescription: meta.description,\n\t\tcharacters,\n\t\taddresses\n\t};\n\n\treturn universeData;\n}\n\nexport async function loadUniverses(ids: string[]): Promise<UniverseData[]> {\n\tconst result = await Promise.all(ids.map((id) => loadUniverse(id)));\n\n\treturn result;\n}\n\nexport async function loadAllUniverses(): Promise<UniverseData[]> {\n\tconst ids = getAvailableIds();\n\n\treturn loadUniverses(ids);\n}\n\nexport async function getAllInterests(): Promise<string[]> {\n\tconst universes = await loadAllUniverses();\n\tconst interestSet = new Set<string>();\n\n\tfor (const universe of universes) {\n\t\tfor (const character of universe.characters) {\n\t\t\tfor (const interest of character.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst result = Array.from(interestSet).sort();\n\n\treturn result;\n}\n\nexport async function getAllLocations(): Promise<LocationEntry[]> {\n\tconst universes = await loadAllUniverses();\n\tconst seen = new Map<string, LocationEntry>();\n\n\tfor (const universe of universes) {\n\t\tfor (const address of universe.addresses) {\n\t\t\tif (address.city && !seen.has(`city:${address.city}`)) {\n\t\t\t\tseen.set(`city:${address.city}`, { name: address.city, type: 'city' });\n\t\t\t}\n\n\t\t\tif (address.state && !seen.has(`state:${address.state}`)) {\n\t\t\t\tseen.set(`state:${address.state}`, { name: address.state, type: 'state' });\n\t\t\t}\n\n\t\t\tif (address.country && !seen.has(`country:${address.country}`)) {\n\t\t\t\tseen.set(`country:${address.country}`, { name: address.country, type: 'country' });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n"],"mappings":"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","names":[]}
|
package/dist/browser.d.cts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { U as UniverseData, P as Person } from './universe-store-
|
|
2
|
-
export { A as Address,
|
|
1
|
+
import { L as LocationEntry, U as UniverseMeta, a as UniverseData, P as Person } from './universe-store-CWhCn3U6.cjs';
|
|
2
|
+
export { A as Address, b as AddressData, C as CharacterData, c as CharacterEntry, d as CharacterQuery, e as UniverseStore } from './universe-store-CWhCn3U6.cjs';
|
|
3
3
|
|
|
4
4
|
declare function getAvailableIds(): string[];
|
|
5
|
+
declare function loadUniverseMeta(id: string): Promise<UniverseMeta>;
|
|
6
|
+
declare function getManifest(): Promise<UniverseMeta[]>;
|
|
5
7
|
declare function loadUniverse(id: string): Promise<UniverseData>;
|
|
6
8
|
declare function loadUniverses(ids: string[]): Promise<UniverseData[]>;
|
|
7
9
|
declare function loadAllUniverses(): Promise<UniverseData[]>;
|
|
10
|
+
declare function getAllInterests(): Promise<string[]>;
|
|
11
|
+
declare function getAllLocations(): Promise<LocationEntry[]>;
|
|
8
12
|
|
|
9
13
|
declare function personFromData(universe: UniverseData, seed?: number): Person;
|
|
10
14
|
|
|
11
|
-
export { Person, UniverseData, getAvailableIds, loadAllUniverses, loadUniverse, loadUniverses, personFromData };
|
|
15
|
+
export { Person, UniverseData, UniverseMeta, getAllInterests, getAllLocations, getAvailableIds, getManifest, loadAllUniverses, loadUniverse, loadUniverseMeta, loadUniverses, personFromData };
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { U as UniverseData, P as Person } from './universe-store-
|
|
2
|
-
export { A as Address,
|
|
1
|
+
import { L as LocationEntry, U as UniverseMeta, a as UniverseData, P as Person } from './universe-store-CWhCn3U6.js';
|
|
2
|
+
export { A as Address, b as AddressData, C as CharacterData, c as CharacterEntry, d as CharacterQuery, e as UniverseStore } from './universe-store-CWhCn3U6.js';
|
|
3
3
|
|
|
4
4
|
declare function getAvailableIds(): string[];
|
|
5
|
+
declare function loadUniverseMeta(id: string): Promise<UniverseMeta>;
|
|
6
|
+
declare function getManifest(): Promise<UniverseMeta[]>;
|
|
5
7
|
declare function loadUniverse(id: string): Promise<UniverseData>;
|
|
6
8
|
declare function loadUniverses(ids: string[]): Promise<UniverseData[]>;
|
|
7
9
|
declare function loadAllUniverses(): Promise<UniverseData[]>;
|
|
10
|
+
declare function getAllInterests(): Promise<string[]>;
|
|
11
|
+
declare function getAllLocations(): Promise<LocationEntry[]>;
|
|
8
12
|
|
|
9
13
|
declare function personFromData(universe: UniverseData, seed?: number): Person;
|
|
10
14
|
|
|
11
|
-
export { Person, UniverseData, getAvailableIds, loadAllUniverses, loadUniverse, loadUniverses, personFromData };
|
|
15
|
+
export { Person, UniverseData, UniverseMeta, getAllInterests, getAllLocations, getAvailableIds, getManifest, loadAllUniverses, loadUniverse, loadUniverseMeta, loadUniverses, personFromData };
|
package/dist/browser.js
CHANGED
|
@@ -19,55 +19,12 @@ function pickRandom(array, rng) {
|
|
|
19
19
|
|
|
20
20
|
// src/generators/email.ts
|
|
21
21
|
var EmailGenerator = class {
|
|
22
|
-
static
|
|
23
|
-
const domain = pickRandom(
|
|
24
|
-
const first = firstName.toLowerCase();
|
|
25
|
-
const last = lastName.toLowerCase();
|
|
26
|
-
return `${first}.${last}@${domain}`;
|
|
27
|
-
}
|
|
28
|
-
static generateFromUsername(username, domains, rng) {
|
|
29
|
-
const domain = pickRandom(domains.emailDomains, rng);
|
|
22
|
+
static generateFromUsername(username, emailDomains, rng) {
|
|
23
|
+
const domain = pickRandom(emailDomains, rng);
|
|
30
24
|
return `${username}@${domain}`;
|
|
31
25
|
}
|
|
32
26
|
};
|
|
33
27
|
|
|
34
|
-
// src/generators/phone.ts
|
|
35
|
-
var PhoneGenerator = class {
|
|
36
|
-
static generate(domains, rng) {
|
|
37
|
-
if (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {
|
|
38
|
-
return pickRandom(domains.phoneEasterEggs, rng);
|
|
39
|
-
}
|
|
40
|
-
const prefix = pickRandom(domains.phonePrefixes, rng);
|
|
41
|
-
const suffix = this.randomDigits(7, rng);
|
|
42
|
-
return `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;
|
|
43
|
-
}
|
|
44
|
-
static randomDigits(count, rng) {
|
|
45
|
-
let result = "";
|
|
46
|
-
for (let i = 0; i < count; i++) {
|
|
47
|
-
result += Math.floor(rng() * 10).toString();
|
|
48
|
-
}
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// src/generators/password.ts
|
|
54
|
-
var PasswordGenerator = class {
|
|
55
|
-
static generate(domains, rng) {
|
|
56
|
-
if (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {
|
|
57
|
-
return pickRandom(domains.passwordEasterEggs, rng);
|
|
58
|
-
}
|
|
59
|
-
return this.randomPassword(12, rng);
|
|
60
|
-
}
|
|
61
|
-
static randomPassword(length, rng) {
|
|
62
|
-
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$";
|
|
63
|
-
let result = "";
|
|
64
|
-
for (let i = 0; i < length; i++) {
|
|
65
|
-
result += chars[Math.floor(rng() * chars.length)];
|
|
66
|
-
}
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
28
|
// src/engine/person-factory.ts
|
|
72
29
|
var PersonFactory = class {
|
|
73
30
|
static build(universe, seed) {
|
|
@@ -83,16 +40,45 @@ var PersonFactory = class {
|
|
|
83
40
|
const rng = createRng(seed);
|
|
84
41
|
return this.buildFromCharacter(character, universe, rng);
|
|
85
42
|
}
|
|
43
|
+
static buildCanonical(characterId, universe) {
|
|
44
|
+
const character = universe.characters.find((c) => c.id === characterId);
|
|
45
|
+
if (!character) {
|
|
46
|
+
throw new Error(`Character "${characterId}" not found in universe "${universe.id}"`);
|
|
47
|
+
}
|
|
48
|
+
const address = character.address ?? universe.addresses[0];
|
|
49
|
+
const username = character.usernames[0];
|
|
50
|
+
const rng = createRng(0);
|
|
51
|
+
const email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);
|
|
52
|
+
const quote = character.quotes[0];
|
|
53
|
+
const person = {
|
|
54
|
+
id: crypto.randomUUID(),
|
|
55
|
+
characterId: character.id,
|
|
56
|
+
firstName: character.firstName,
|
|
57
|
+
lastName: character.lastName,
|
|
58
|
+
username,
|
|
59
|
+
email,
|
|
60
|
+
address: {
|
|
61
|
+
street: address.street,
|
|
62
|
+
city: address.city,
|
|
63
|
+
state: address.state ?? "",
|
|
64
|
+
zip: address.zip ?? "",
|
|
65
|
+
country: address.country
|
|
66
|
+
},
|
|
67
|
+
profession: character.profession,
|
|
68
|
+
interests: character.interests,
|
|
69
|
+
quote,
|
|
70
|
+
universe: universe.id,
|
|
71
|
+
universeName: universe.name,
|
|
72
|
+
...character.symbol ? { symbol: character.symbol } : {},
|
|
73
|
+
...character.color ? { color: character.color } : {}
|
|
74
|
+
};
|
|
75
|
+
return person;
|
|
76
|
+
}
|
|
86
77
|
static buildFromCharacter(character, universe, rng) {
|
|
87
78
|
const address = character.address ?? pickRandom(universe.addresses, rng);
|
|
88
79
|
const username = pickRandom(character.usernames, rng);
|
|
89
|
-
const
|
|
90
|
-
const email = EmailGenerator.generateFromUsername(username, domains, rng);
|
|
91
|
-
const phone = PhoneGenerator.generate(universe.domains, rng);
|
|
92
|
-
const password = PasswordGenerator.generate(universe.domains, rng);
|
|
80
|
+
const email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);
|
|
93
81
|
const quote = pickRandom(character.quotes, rng);
|
|
94
|
-
const avatarName = encodeURIComponent(`${character.firstName} ${character.lastName}`);
|
|
95
|
-
const avatar = `https://ui-avatars.com/api/?name=${avatarName}&background=random`;
|
|
96
82
|
const person = {
|
|
97
83
|
id: crypto.randomUUID(),
|
|
98
84
|
characterId: character.id,
|
|
@@ -100,8 +86,6 @@ var PersonFactory = class {
|
|
|
100
86
|
lastName: character.lastName,
|
|
101
87
|
username,
|
|
102
88
|
email,
|
|
103
|
-
password,
|
|
104
|
-
phone,
|
|
105
89
|
address: {
|
|
106
90
|
street: address.street,
|
|
107
91
|
city: address.city,
|
|
@@ -114,7 +98,8 @@ var PersonFactory = class {
|
|
|
114
98
|
quote,
|
|
115
99
|
universe: universe.id,
|
|
116
100
|
universeName: universe.name,
|
|
117
|
-
|
|
101
|
+
...character.symbol ? { symbol: character.symbol } : {},
|
|
102
|
+
...character.color ? { color: character.color } : {}
|
|
118
103
|
};
|
|
119
104
|
return person;
|
|
120
105
|
}
|
|
@@ -143,11 +128,15 @@ var UniverseStore = class {
|
|
|
143
128
|
return result;
|
|
144
129
|
}
|
|
145
130
|
getUniverses() {
|
|
146
|
-
const result = this.universes.map((u) =>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
131
|
+
const result = this.universes.map((u) => {
|
|
132
|
+
const meta = {
|
|
133
|
+
id: u.id,
|
|
134
|
+
name: u.name,
|
|
135
|
+
genre: u.genre,
|
|
136
|
+
description: u.description
|
|
137
|
+
};
|
|
138
|
+
return meta;
|
|
139
|
+
});
|
|
151
140
|
return result;
|
|
152
141
|
}
|
|
153
142
|
findCharacters(query) {
|
|
@@ -225,7 +214,6 @@ var UniverseStore = class {
|
|
|
225
214
|
var metaModules = import.meta.glob("../data/*/meta.json", { eager: false });
|
|
226
215
|
var characterModules = import.meta.glob("../data/*/characters.json", { eager: false });
|
|
227
216
|
var addressModules = import.meta.glob("../data/*/addresses.json", { eager: false });
|
|
228
|
-
var domainModules = import.meta.glob("../data/*/domains.json", { eager: false });
|
|
229
217
|
function extractId(path) {
|
|
230
218
|
const parts = path.split("/");
|
|
231
219
|
return parts[parts.length - 2];
|
|
@@ -233,34 +221,52 @@ function extractId(path) {
|
|
|
233
221
|
function getAvailableIds() {
|
|
234
222
|
return Object.keys(metaModules).map(extractId);
|
|
235
223
|
}
|
|
224
|
+
async function loadUniverseMeta(id) {
|
|
225
|
+
const metaPath = `../data/${id}/meta.json`;
|
|
226
|
+
const metaLoader = metaModules[metaPath];
|
|
227
|
+
if (!metaLoader) {
|
|
228
|
+
throw new Error(`Universe "${id}" not found`);
|
|
229
|
+
}
|
|
230
|
+
const metaModule = await metaLoader();
|
|
231
|
+
const meta = metaModule.default;
|
|
232
|
+
const result = {
|
|
233
|
+
id: meta.id,
|
|
234
|
+
name: meta.name,
|
|
235
|
+
genre: meta.genre,
|
|
236
|
+
description: meta.description
|
|
237
|
+
};
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
async function getManifest() {
|
|
241
|
+
const ids = getAvailableIds();
|
|
242
|
+
const result = await Promise.all(ids.map((id) => loadUniverseMeta(id)));
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
236
245
|
async function loadUniverse(id) {
|
|
237
246
|
const metaPath = `../data/${id}/meta.json`;
|
|
238
247
|
const charactersPath = `../data/${id}/characters.json`;
|
|
239
248
|
const addressesPath = `../data/${id}/addresses.json`;
|
|
240
|
-
const domainsPath = `../data/${id}/domains.json`;
|
|
241
249
|
const metaLoader = metaModules[metaPath];
|
|
242
250
|
const charactersLoader = characterModules[charactersPath];
|
|
243
251
|
const addressesLoader = addressModules[addressesPath];
|
|
244
|
-
|
|
245
|
-
if (!metaLoader || !charactersLoader || !addressesLoader || !domainsLoader) {
|
|
252
|
+
if (!metaLoader || !charactersLoader || !addressesLoader) {
|
|
246
253
|
throw new Error(`Universe "${id}" not found`);
|
|
247
254
|
}
|
|
248
|
-
const [metaModule, charactersModule, addressesModule
|
|
255
|
+
const [metaModule, charactersModule, addressesModule] = await Promise.all([
|
|
249
256
|
metaLoader(),
|
|
250
257
|
charactersLoader(),
|
|
251
|
-
addressesLoader()
|
|
252
|
-
domainsLoader()
|
|
258
|
+
addressesLoader()
|
|
253
259
|
]);
|
|
254
260
|
const meta = metaModule.default;
|
|
255
261
|
const characters = charactersModule.default;
|
|
256
262
|
const addresses = addressesModule.default;
|
|
257
|
-
const domains = domainsModule.default;
|
|
258
263
|
const universeData = {
|
|
259
264
|
id: meta.id,
|
|
260
265
|
name: meta.name,
|
|
266
|
+
genre: meta.genre,
|
|
267
|
+
description: meta.description,
|
|
261
268
|
characters,
|
|
262
|
-
addresses
|
|
263
|
-
domains
|
|
269
|
+
addresses
|
|
264
270
|
};
|
|
265
271
|
return universeData;
|
|
266
272
|
}
|
|
@@ -272,6 +278,37 @@ async function loadAllUniverses() {
|
|
|
272
278
|
const ids = getAvailableIds();
|
|
273
279
|
return loadUniverses(ids);
|
|
274
280
|
}
|
|
281
|
+
async function getAllInterests() {
|
|
282
|
+
const universes = await loadAllUniverses();
|
|
283
|
+
const interestSet = /* @__PURE__ */ new Set();
|
|
284
|
+
for (const universe of universes) {
|
|
285
|
+
for (const character of universe.characters) {
|
|
286
|
+
for (const interest of character.interests) {
|
|
287
|
+
interestSet.add(interest);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const result = Array.from(interestSet).sort();
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
async function getAllLocations() {
|
|
295
|
+
const universes = await loadAllUniverses();
|
|
296
|
+
const seen = /* @__PURE__ */ new Map();
|
|
297
|
+
for (const universe of universes) {
|
|
298
|
+
for (const address of universe.addresses) {
|
|
299
|
+
if (address.city && !seen.has(`city:${address.city}`)) {
|
|
300
|
+
seen.set(`city:${address.city}`, { name: address.city, type: "city" });
|
|
301
|
+
}
|
|
302
|
+
if (address.state && !seen.has(`state:${address.state}`)) {
|
|
303
|
+
seen.set(`state:${address.state}`, { name: address.state, type: "state" });
|
|
304
|
+
}
|
|
305
|
+
if (address.country && !seen.has(`country:${address.country}`)) {
|
|
306
|
+
seen.set(`country:${address.country}`, { name: address.country, type: "country" });
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
311
|
+
}
|
|
275
312
|
|
|
276
313
|
// src/browser.ts
|
|
277
314
|
function personFromData(universe, seed) {
|
|
@@ -279,9 +316,13 @@ function personFromData(universe, seed) {
|
|
|
279
316
|
}
|
|
280
317
|
export {
|
|
281
318
|
UniverseStore,
|
|
319
|
+
getAllInterests,
|
|
320
|
+
getAllLocations,
|
|
282
321
|
getAvailableIds,
|
|
322
|
+
getManifest,
|
|
283
323
|
loadAllUniverses,
|
|
284
324
|
loadUniverse,
|
|
325
|
+
loadUniverseMeta,
|
|
285
326
|
loadUniverses,
|
|
286
327
|
personFromData
|
|
287
328
|
};
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generators/random.ts","../src/generators/email.ts","../src/generators/phone.ts","../src/generators/password.ts","../src/engine/person-factory.ts","../src/engine/universe-store.ts","../src/universes/browser-loader.ts","../src/browser.ts"],"sourcesContent":["/**\n * Seeded pseudo-random number generator (mulberry32).\n * Returns a function that produces values in [0, 1).\n */\nexport function createRng(seed?: number): () => number {\n\tif (seed === undefined) {\n\t\treturn Math.random;\n\t}\n\n\tlet s = seed;\n\n\treturn function rng(): number {\n\t\ts += 0x6d2b79f5;\n\t\tlet z = s;\n\t\tz = Math.imul(z ^ (z >>> 15), z | 1);\n\t\tz ^= z + Math.imul(z ^ (z >>> 7), z | 61);\n\n\t\treturn ((z ^ (z >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\nexport function pickRandom<T>(array: T[], rng: () => number): T {\n\tconst index = Math.floor(rng() * array.length);\n\n\treturn array[index];\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class EmailGenerator {\n\tstatic generate(firstName: string, lastName: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\t\tconst first = firstName.toLowerCase();\n\t\tconst last = lastName.toLowerCase();\n\n\t\treturn `${first}.${last}@${domain}`;\n\t}\n\n\tstatic generateFromUsername(username: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PhoneGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {\n\t\t\treturn pickRandom(domains.phoneEasterEggs, rng);\n\t\t}\n\n\t\tconst prefix = pickRandom(domains.phonePrefixes, rng);\n\t\tconst suffix = this.randomDigits(7, rng);\n\n\t\treturn `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;\n\t}\n\n\tprivate static randomDigits(count: number, rng: () => number): string {\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult += Math.floor(rng() * 10).toString();\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PasswordGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {\n\t\t\treturn pickRandom(domains.passwordEasterEggs, rng);\n\t\t}\n\n\t\treturn this.randomPassword(12, rng);\n\t}\n\n\tprivate static randomPassword(length: number, rng: () => number): string {\n\t\tconst chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$';\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars[Math.floor(rng() * chars.length)];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator, PhoneGenerator, PasswordGenerator } from '@/generators';\n\nimport type { Person, UniverseData, CharacterData } from '@/types';\n\nexport class PersonFactory {\n\tstatic build(universe: UniverseData, seed?: number): Person {\n\t\tconst rng = createRng(seed);\n\n\t\tconst character = pickRandom(universe.characters, rng);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildByCharacterId(characterId: string, universe: UniverseData, seed?: number): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tprivate static buildFromCharacter(character: CharacterData, universe: UniverseData, rng: () => number): Person {\n\t\tconst address = character.address ?? pickRandom(universe.addresses, rng);\n\n\t\tconst username = pickRandom(character.usernames, rng);\n\n\t\tconst domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;\n\n\t\tconst email = EmailGenerator.generateFromUsername(username, domains, rng);\n\t\tconst phone = PhoneGenerator.generate(universe.domains, rng);\n\t\tconst password = PasswordGenerator.generate(universe.domains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\n\t\tconst avatarName = encodeURIComponent(`${character.firstName} ${character.lastName}`);\n\t\tconst avatar = `https://ui-avatars.com/api/?name=${avatarName}&background=random`;\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\tpassword,\n\t\t\tphone,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\tavatar\n\t\t};\n\n\t\treturn person;\n\t}\n}\n","import { createRng } from '@/generators';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { UniverseData, Person, CharacterEntry, CharacterQuery } from '@/types';\n\nexport class UniverseStore {\n\tprivate universes: UniverseData[];\n\tprivate characterIndex: CharacterEntry[];\n\n\tconstructor(universes: UniverseData[]) {\n\t\tthis.universes = universes;\n\t\tthis.characterIndex = this.buildIndex(universes);\n\t}\n\n\tget index(): CharacterEntry[] {\n\t\treturn this.characterIndex;\n\t}\n\n\tgetInterests(universeIds?: string[]): string[] {\n\t\tconst entries =\n\t\t\tuniverseIds && universeIds.length > 0\n\t\t\t\t? this.characterIndex.filter((e) => universeIds.includes(e.universeId))\n\t\t\t\t: this.characterIndex;\n\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const entry of entries) {\n\t\t\tfor (const interest of entry.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(interestSet).sort();\n\n\t\treturn result;\n\t}\n\n\tgetUniverses(): { id: string; name: string; characterCount: number }[] {\n\t\tconst result = this.universes.map((u) => ({\n\t\t\tid: u.id,\n\t\t\tname: u.name,\n\t\t\tcharacterCount: u.characters.length\n\t\t}));\n\n\t\treturn result;\n\t}\n\n\tfindCharacters(query: CharacterQuery): CharacterEntry[] {\n\t\tlet entries = this.characterIndex;\n\n\t\tif (query.universes && query.universes.length > 0) {\n\t\t\tentries = entries.filter((e) => query.universes!.includes(e.universeId));\n\t\t}\n\n\t\tif (query.name && query.name.trim().length > 0) {\n\t\t\tconst needle = query.name.toLowerCase();\n\n\t\t\tentries = entries.filter((e) => {\n\t\t\t\tconst fullName = `${e.firstName} ${e.lastName}`.toLowerCase();\n\n\t\t\t\treturn fullName.includes(needle);\n\t\t\t});\n\t\t}\n\n\t\tif (query.interests && query.interests.length > 0) {\n\t\t\tconst mode = query.interestsMode ?? 'or';\n\n\t\t\tif (mode === 'and') {\n\t\t\t\tentries = entries.filter((e) => query.interests!.every((interest) => e.interests.includes(interest)));\n\t\t\t} else {\n\t\t\t\tentries = entries.filter((e) => query.interests!.some((interest) => e.interests.includes(interest)));\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpersonByCharacterId(characterId: string, seed?: number): Person {\n\t\tconst entry = this.characterIndex.find((e) => e.characterId === characterId);\n\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in store`);\n\t\t}\n\n\t\tconst universe = this.universes.find((u) => u.id === entry.universeId);\n\n\t\tif (!universe) {\n\t\t\tthrow new Error(`Universe \"${entry.universeId}\" not found in store`);\n\t\t}\n\n\t\treturn PersonFactory.buildByCharacterId(characterId, universe, seed);\n\t}\n\n\tgeneratePersonas(query: CharacterQuery, count: number, seed?: number): Person[] {\n\t\tconst matching = this.findCharacters(query);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\t\tconst actualCount = Math.min(count, matching.length);\n\n\t\tconst shuffled = [...matching].sort(() => rng() - 0.5);\n\t\tconst selected = shuffled.slice(0, actualCount);\n\t\tconst personas: Person[] = [];\n\n\t\tfor (let i = 0; i < selected.length; i++) {\n\t\t\tconst entry = selected[i];\n\t\t\tconst universe = this.universes.find((u) => u.id === entry.universeId)!;\n\t\t\tconst personSeed = seed !== undefined ? seed + i : undefined;\n\n\t\t\tpersonas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));\n\t\t}\n\n\t\treturn personas;\n\t}\n\n\tprivate buildIndex(universes: UniverseData[]): CharacterEntry[] {\n\t\tconst index: CharacterEntry[] = [];\n\n\t\tfor (const universe of universes) {\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tconst entry: CharacterEntry = {\n\t\t\t\t\tcharacterId: character.id,\n\t\t\t\t\tuniverseId: universe.id,\n\t\t\t\t\tuniverseName: universe.name,\n\t\t\t\t\tfirstName: character.firstName,\n\t\t\t\t\tlastName: character.lastName,\n\t\t\t\t\tinterests: character.interests,\n\t\t\t\t\tprofession: character.profession\n\t\t\t\t};\n\n\t\t\t\tindex.push(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t}\n}\n","import type { UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\n\ninterface MetaJson {\n\tid: string;\n\tname: string;\n}\n\nconst metaModules = import.meta.glob('../data/*/meta.json', { eager: false });\nconst characterModules = import.meta.glob('../data/*/characters.json', { eager: false });\nconst addressModules = import.meta.glob('../data/*/addresses.json', { eager: false });\nconst domainModules = import.meta.glob('../data/*/domains.json', { eager: false });\n\nfunction extractId(path: string): string {\n\tconst parts = path.split('/');\n\n\treturn parts[parts.length - 2];\n}\n\nexport function getAvailableIds(): string[] {\n\treturn Object.keys(metaModules).map(extractId);\n}\n\nexport async function loadUniverse(id: string): Promise<UniverseData> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst charactersPath = `../data/${id}/characters.json`;\n\tconst addressesPath = `../data/${id}/addresses.json`;\n\tconst domainsPath = `../data/${id}/domains.json`;\n\n\tconst metaLoader = metaModules[metaPath];\n\tconst charactersLoader = characterModules[charactersPath];\n\tconst addressesLoader = addressModules[addressesPath];\n\tconst domainsLoader = domainModules[domainsPath];\n\n\tif (!metaLoader || !charactersLoader || !addressesLoader || !domainsLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst [metaModule, charactersModule, addressesModule, domainsModule] = await Promise.all([\n\t\tmetaLoader(),\n\t\tcharactersLoader(),\n\t\taddressesLoader(),\n\t\tdomainsLoader()\n\t]);\n\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\tconst characters = (charactersModule as { default: CharacterData[] }).default;\n\tconst addresses = (addressesModule as { default: AddressData[] }).default;\n\tconst domains = (domainsModule as { default: DomainsData }).default;\n\n\tconst universeData: UniverseData = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tcharacters,\n\t\taddresses,\n\t\tdomains\n\t};\n\n\treturn universeData;\n}\n\nexport async function loadUniverses(ids: string[]): Promise<UniverseData[]> {\n\tconst result = await Promise.all(ids.map((id) => loadUniverse(id)));\n\n\treturn result;\n}\n\nexport async function loadAllUniverses(): Promise<UniverseData[]> {\n\tconst ids = getAvailableIds();\n\n\treturn loadUniverses(ids);\n}\n","import { PersonFactory } from '@/engine/person-factory';\nimport { UniverseStore } from '@/engine/universe-store';\n\nimport type { Person, UniverseData } from '@/types';\n\nexport { UniverseStore };\nexport { loadUniverse, loadUniverses, loadAllUniverses, getAvailableIds } from '@/universes/browser-loader';\n\nexport function personFromData(universe: UniverseData, seed?: number): Person {\n\treturn PersonFactory.build(universe, seed);\n}\n\nexport type { Person, UniverseInfo } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/generators/random.ts","../src/generators/email.ts","../src/engine/person-factory.ts","../src/engine/universe-store.ts","../src/universes/browser-loader.ts","../src/browser.ts"],"sourcesContent":["/**\n * Seeded pseudo-random number generator (mulberry32).\n * Returns a function that produces values in [0, 1).\n */\nexport function createRng(seed?: number): () => number {\n\tif (seed === undefined) {\n\t\treturn Math.random;\n\t}\n\n\tlet s = seed;\n\n\treturn function rng(): number {\n\t\ts += 0x6d2b79f5;\n\t\tlet z = s;\n\t\tz = Math.imul(z ^ (z >>> 15), z | 1);\n\t\tz ^= z + Math.imul(z ^ (z >>> 7), z | 61);\n\n\t\treturn ((z ^ (z >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\nexport function pickRandom<T>(array: T[], rng: () => number): T {\n\tconst index = Math.floor(rng() * array.length);\n\n\treturn array[index];\n}\n","import { pickRandom } from './random';\n\nexport class EmailGenerator {\n\tstatic generateFromUsername(username: string, emailDomains: string[], rng: () => number): string {\n\t\tconst domain = pickRandom(emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator } from '@/generators';\n\nimport type { Person, UniverseData, CharacterData } from '@/types';\n\nexport class PersonFactory {\n\tstatic build(universe: UniverseData, seed?: number): Person {\n\t\tconst rng = createRng(seed);\n\n\t\tconst character = pickRandom(universe.characters, rng);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildByCharacterId(characterId: string, universe: UniverseData, seed?: number): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildCanonical(characterId: string, universe: UniverseData): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst rng = createRng(0);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = character.quotes[0];\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\n\t}\n\n\tprivate static buildFromCharacter(character: CharacterData, universe: UniverseData, rng: () => number): Person {\n\t\tconst address = character.address ?? pickRandom(universe.addresses, rng);\n\t\tconst username = pickRandom(character.usernames, rng);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\n\t}\n}\n","import { createRng } from '@/generators';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { UniverseData, UniverseMeta, Person, CharacterEntry, CharacterQuery } from '@/types';\n\nexport class UniverseStore {\n\tprivate universes: UniverseData[];\n\tprivate characterIndex: CharacterEntry[];\n\n\tconstructor(universes: UniverseData[]) {\n\t\tthis.universes = universes;\n\t\tthis.characterIndex = this.buildIndex(universes);\n\t}\n\n\tget index(): CharacterEntry[] {\n\t\treturn this.characterIndex;\n\t}\n\n\tgetInterests(universeIds?: string[]): string[] {\n\t\tconst entries =\n\t\t\tuniverseIds && universeIds.length > 0\n\t\t\t\t? this.characterIndex.filter((e) => universeIds.includes(e.universeId))\n\t\t\t\t: this.characterIndex;\n\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const entry of entries) {\n\t\t\tfor (const interest of entry.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(interestSet).sort();\n\n\t\treturn result;\n\t}\n\n\tgetUniverses(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tfindCharacters(query: CharacterQuery): CharacterEntry[] {\n\t\tlet entries = this.characterIndex;\n\n\t\tif (query.universes && query.universes.length > 0) {\n\t\t\tentries = entries.filter((e) => query.universes!.includes(e.universeId));\n\t\t}\n\n\t\tif (query.name && query.name.trim().length > 0) {\n\t\t\tconst needle = query.name.toLowerCase();\n\n\t\t\tentries = entries.filter((e) => {\n\t\t\t\tconst fullName = `${e.firstName} ${e.lastName}`.toLowerCase();\n\n\t\t\t\treturn fullName.includes(needle);\n\t\t\t});\n\t\t}\n\n\t\tif (query.interests && query.interests.length > 0) {\n\t\t\tconst mode = query.interestsMode ?? 'or';\n\n\t\t\tif (mode === 'and') {\n\t\t\t\tentries = entries.filter((e) => query.interests!.every((interest) => e.interests.includes(interest)));\n\t\t\t} else {\n\t\t\t\tentries = entries.filter((e) => query.interests!.some((interest) => e.interests.includes(interest)));\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpersonByCharacterId(characterId: string, seed?: number): Person {\n\t\tconst entry = this.characterIndex.find((e) => e.characterId === characterId);\n\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in store`);\n\t\t}\n\n\t\tconst universe = this.universes.find((u) => u.id === entry.universeId);\n\n\t\tif (!universe) {\n\t\t\tthrow new Error(`Universe \"${entry.universeId}\" not found in store`);\n\t\t}\n\n\t\treturn PersonFactory.buildByCharacterId(characterId, universe, seed);\n\t}\n\n\tgeneratePersonas(query: CharacterQuery, count: number, seed?: number): Person[] {\n\t\tconst matching = this.findCharacters(query);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\t\tconst actualCount = Math.min(count, matching.length);\n\n\t\tconst shuffled = [...matching].sort(() => rng() - 0.5);\n\t\tconst selected = shuffled.slice(0, actualCount);\n\t\tconst personas: Person[] = [];\n\n\t\tfor (let i = 0; i < selected.length; i++) {\n\t\t\tconst entry = selected[i];\n\t\t\tconst universe = this.universes.find((u) => u.id === entry.universeId)!;\n\t\t\tconst personSeed = seed !== undefined ? seed + i : undefined;\n\n\t\t\tpersonas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));\n\t\t}\n\n\t\treturn personas;\n\t}\n\n\tprivate buildIndex(universes: UniverseData[]): CharacterEntry[] {\n\t\tconst index: CharacterEntry[] = [];\n\n\t\tfor (const universe of universes) {\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tconst entry: CharacterEntry = {\n\t\t\t\t\tcharacterId: character.id,\n\t\t\t\t\tuniverseId: universe.id,\n\t\t\t\t\tuniverseName: universe.name,\n\t\t\t\t\tfirstName: character.firstName,\n\t\t\t\t\tlastName: character.lastName,\n\t\t\t\t\tinterests: character.interests,\n\t\t\t\t\tprofession: character.profession\n\t\t\t\t};\n\n\t\t\t\tindex.push(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t}\n}\n","import type { UniverseData, UniverseMeta, CharacterData, AddressData, LocationEntry } from '@/types';\n\ninterface MetaJson {\n\tid: string;\n\tname: string;\n\tgenre: string[];\n\tdescription: string;\n}\n\nconst metaModules = import.meta.glob('../data/*/meta.json', { eager: false });\nconst characterModules = import.meta.glob('../data/*/characters.json', { eager: false });\nconst addressModules = import.meta.glob('../data/*/addresses.json', { eager: false });\n\nfunction extractId(path: string): string {\n\tconst parts = path.split('/');\n\n\treturn parts[parts.length - 2];\n}\n\nexport function getAvailableIds(): string[] {\n\treturn Object.keys(metaModules).map(extractId);\n}\n\nexport async function loadUniverseMeta(id: string): Promise<UniverseMeta> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst metaLoader = metaModules[metaPath];\n\n\tif (!metaLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst metaModule = await metaLoader();\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\n\tconst result: UniverseMeta = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tgenre: meta.genre,\n\t\tdescription: meta.description\n\t};\n\n\treturn result;\n}\n\nexport async function getManifest(): Promise<UniverseMeta[]> {\n\tconst ids = getAvailableIds();\n\tconst result = await Promise.all(ids.map((id) => loadUniverseMeta(id)));\n\n\treturn result;\n}\n\nexport async function loadUniverse(id: string): Promise<UniverseData> {\n\tconst metaPath = `../data/${id}/meta.json`;\n\tconst charactersPath = `../data/${id}/characters.json`;\n\tconst addressesPath = `../data/${id}/addresses.json`;\n\n\tconst metaLoader = metaModules[metaPath];\n\tconst charactersLoader = characterModules[charactersPath];\n\tconst addressesLoader = addressModules[addressesPath];\n\n\tif (!metaLoader || !charactersLoader || !addressesLoader) {\n\t\tthrow new Error(`Universe \"${id}\" not found`);\n\t}\n\n\tconst [metaModule, charactersModule, addressesModule] = await Promise.all([\n\t\tmetaLoader(),\n\t\tcharactersLoader(),\n\t\taddressesLoader()\n\t]);\n\n\tconst meta = (metaModule as { default: MetaJson }).default;\n\tconst characters = (charactersModule as { default: CharacterData[] }).default;\n\tconst addresses = (addressesModule as { default: AddressData[] }).default;\n\n\tconst universeData: UniverseData = {\n\t\tid: meta.id,\n\t\tname: meta.name,\n\t\tgenre: meta.genre,\n\t\tdescription: meta.description,\n\t\tcharacters,\n\t\taddresses\n\t};\n\n\treturn universeData;\n}\n\nexport async function loadUniverses(ids: string[]): Promise<UniverseData[]> {\n\tconst result = await Promise.all(ids.map((id) => loadUniverse(id)));\n\n\treturn result;\n}\n\nexport async function loadAllUniverses(): Promise<UniverseData[]> {\n\tconst ids = getAvailableIds();\n\n\treturn loadUniverses(ids);\n}\n\nexport async function getAllInterests(): Promise<string[]> {\n\tconst universes = await loadAllUniverses();\n\tconst interestSet = new Set<string>();\n\n\tfor (const universe of universes) {\n\t\tfor (const character of universe.characters) {\n\t\t\tfor (const interest of character.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst result = Array.from(interestSet).sort();\n\n\treturn result;\n}\n\nexport async function getAllLocations(): Promise<LocationEntry[]> {\n\tconst universes = await loadAllUniverses();\n\tconst seen = new Map<string, LocationEntry>();\n\n\tfor (const universe of universes) {\n\t\tfor (const address of universe.addresses) {\n\t\t\tif (address.city && !seen.has(`city:${address.city}`)) {\n\t\t\t\tseen.set(`city:${address.city}`, { name: address.city, type: 'city' });\n\t\t\t}\n\n\t\t\tif (address.state && !seen.has(`state:${address.state}`)) {\n\t\t\t\tseen.set(`state:${address.state}`, { name: address.state, type: 'state' });\n\t\t\t}\n\n\t\t\tif (address.country && !seen.has(`country:${address.country}`)) {\n\t\t\t\tseen.set(`country:${address.country}`, { name: address.country, type: 'country' });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n","import { PersonFactory } from '@/engine/person-factory';\nimport { UniverseStore } from '@/engine/universe-store';\n\nimport type { Person, UniverseData } from '@/types';\n\nexport { UniverseStore };\nexport {\n\tloadUniverse,\n\tloadUniverses,\n\tloadAllUniverses,\n\tloadUniverseMeta,\n\tgetManifest,\n\tgetAllInterests,\n\tgetAllLocations,\n\tgetAvailableIds\n} from '@/universes/browser-loader';\n\nexport function personFromData(universe: UniverseData, seed?: number): Person {\n\treturn PersonFactory.build(universe, seed);\n}\n\nexport type { Person, UniverseMeta } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n"],"mappings":";AAIO,SAAS,UAAU,MAA6B;AACtD,MAAI,SAAS,QAAW;AACvB,WAAO,KAAK;AAAA,EACb;AAEA,MAAI,IAAI;AAER,SAAO,SAAS,MAAc;AAC7B,SAAK;AACL,QAAI,IAAI;AACR,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACnC,SAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;AAExC,aAAS,IAAK,MAAM,QAAS,KAAK;AAAA,EACnC;AACD;AAEO,SAAS,WAAc,OAAY,KAAsB;AAC/D,QAAM,QAAQ,KAAK,MAAM,IAAI,IAAI,MAAM,MAAM;AAE7C,SAAO,MAAM,KAAK;AACnB;;;ACvBO,IAAM,iBAAN,MAAqB;AAAA,EAC3B,OAAO,qBAAqB,UAAkB,cAAwB,KAA2B;AAChG,UAAM,SAAS,WAAW,cAAc,GAAG;AAE3C,WAAO,GAAG,QAAQ,IAAI,MAAM;AAAA,EAC7B;AACD;;;ACJO,IAAM,gBAAN,MAAoB;AAAA,EAC1B,OAAO,MAAM,UAAwB,MAAuB;AAC3D,UAAM,MAAM,UAAU,IAAI;AAE1B,UAAM,YAAY,WAAW,SAAS,YAAY,GAAG;AAErD,WAAO,KAAK,mBAAmB,WAAW,UAAU,GAAG;AAAA,EACxD;AAAA,EAEA,OAAO,mBAAmB,aAAqB,UAAwB,MAAuB;AAC7F,UAAM,YAAY,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,WAAW;AAEtE,QAAI,CAAC,WAAW;AACf,YAAM,IAAI,MAAM,cAAc,WAAW,4BAA4B,SAAS,EAAE,GAAG;AAAA,IACpF;AAEA,UAAM,MAAM,UAAU,IAAI;AAE1B,WAAO,KAAK,mBAAmB,WAAW,UAAU,GAAG;AAAA,EACxD;AAAA,EAEA,OAAO,eAAe,aAAqB,UAAgC;AAC1E,UAAM,YAAY,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,WAAW;AAEtE,QAAI,CAAC,WAAW;AACf,YAAM,IAAI,MAAM,cAAc,WAAW,4BAA4B,SAAS,EAAE,GAAG;AAAA,IACpF;AAEA,UAAM,UAAU,UAAU,WAAW,SAAS,UAAU,CAAC;AACzD,UAAM,WAAW,UAAU,UAAU,CAAC;AACtC,UAAM,MAAM,UAAU,CAAC;AACvB,UAAM,QAAQ,eAAe,qBAAqB,UAAU,UAAU,cAAc,GAAG;AACvF,UAAM,QAAQ,UAAU,OAAO,CAAC;AAEhC,UAAM,SAAiB;AAAA,MACtB,IAAI,OAAO,WAAW;AAAA,MACtB,aAAa,UAAU;AAAA,MACvB,WAAW,UAAU;AAAA,MACrB,UAAU,UAAU;AAAA,MACpB;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACR,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ,SAAS;AAAA,QACxB,KAAK,QAAQ,OAAO;AAAA,QACpB,SAAS,QAAQ;AAAA,MAClB;AAAA,MACA,YAAY,UAAU;AAAA,MACtB,WAAW,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,SAAS;AAAA,MACnB,cAAc,SAAS;AAAA,MACvB,GAAI,UAAU,SAAS,EAAE,QAAQ,UAAU,OAAO,IAAI,CAAC;AAAA,MACvD,GAAI,UAAU,QAAQ,EAAE,OAAO,UAAU,MAAM,IAAI,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,OAAe,mBAAmB,WAA0B,UAAwB,KAA2B;AAC9G,UAAM,UAAU,UAAU,WAAW,WAAW,SAAS,WAAW,GAAG;AACvE,UAAM,WAAW,WAAW,UAAU,WAAW,GAAG;AACpD,UAAM,QAAQ,eAAe,qBAAqB,UAAU,UAAU,cAAc,GAAG;AACvF,UAAM,QAAQ,WAAW,UAAU,QAAQ,GAAG;AAE9C,UAAM,SAAiB;AAAA,MACtB,IAAI,OAAO,WAAW;AAAA,MACtB,aAAa,UAAU;AAAA,MACvB,WAAW,UAAU;AAAA,MACrB,UAAU,UAAU;AAAA,MACpB;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACR,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ,SAAS;AAAA,QACxB,KAAK,QAAQ,OAAO;AAAA,QACpB,SAAS,QAAQ;AAAA,MAClB;AAAA,MACA,YAAY,UAAU;AAAA,MACtB,WAAW,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,SAAS;AAAA,MACnB,cAAc,SAAS;AAAA,MACvB,GAAI,UAAU,SAAS,EAAE,QAAQ,UAAU,OAAO,IAAI,CAAC;AAAA,MACvD,GAAI,UAAU,QAAQ,EAAE,OAAO,UAAU,MAAM,IAAI,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACR;AACD;;;ACzFO,IAAM,gBAAN,MAAoB;AAAA,EAClB;AAAA,EACA;AAAA,EAER,YAAY,WAA2B;AACtC,SAAK,YAAY;AACjB,SAAK,iBAAiB,KAAK,WAAW,SAAS;AAAA,EAChD;AAAA,EAEA,IAAI,QAA0B;AAC7B,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,aAAa,aAAkC;AAC9C,UAAM,UACL,eAAe,YAAY,SAAS,IACjC,KAAK,eAAe,OAAO,CAAC,MAAM,YAAY,SAAS,EAAE,UAAU,CAAC,IACpE,KAAK;AAET,UAAM,cAAc,oBAAI,IAAY;AAEpC,eAAW,SAAS,SAAS;AAC5B,iBAAW,YAAY,MAAM,WAAW;AACvC,oBAAY,IAAI,QAAQ;AAAA,MACzB;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,KAAK,WAAW,EAAE,KAAK;AAE5C,WAAO;AAAA,EACR;AAAA,EAEA,eAA+B;AAC9B,UAAM,SAAS,KAAK,UAAU,IAAI,CAAC,MAAM;AACxC,YAAM,OAAqB;AAAA,QAC1B,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,QACT,aAAa,EAAE;AAAA,MAChB;AAEA,aAAO;AAAA,IACR,CAAC;AAED,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,OAAyC;AACvD,QAAI,UAAU,KAAK;AAEnB,QAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;AAClD,gBAAU,QAAQ,OAAO,CAAC,MAAM,MAAM,UAAW,SAAS,EAAE,UAAU,CAAC;AAAA,IACxE;AAEA,QAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,EAAE,SAAS,GAAG;AAC/C,YAAM,SAAS,MAAM,KAAK,YAAY;AAEtC,gBAAU,QAAQ,OAAO,CAAC,MAAM;AAC/B,cAAM,WAAW,GAAG,EAAE,SAAS,IAAI,EAAE,QAAQ,GAAG,YAAY;AAE5D,eAAO,SAAS,SAAS,MAAM;AAAA,MAChC,CAAC;AAAA,IACF;AAEA,QAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;AAClD,YAAM,OAAO,MAAM,iBAAiB;AAEpC,UAAI,SAAS,OAAO;AACnB,kBAAU,QAAQ,OAAO,CAAC,MAAM,MAAM,UAAW,MAAM,CAAC,aAAa,EAAE,UAAU,SAAS,QAAQ,CAAC,CAAC;AAAA,MACrG,OAAO;AACN,kBAAU,QAAQ,OAAO,CAAC,MAAM,MAAM,UAAW,KAAK,CAAC,aAAa,EAAE,UAAU,SAAS,QAAQ,CAAC,CAAC;AAAA,MACpG;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,oBAAoB,aAAqB,MAAuB;AAC/D,UAAM,QAAQ,KAAK,eAAe,KAAK,CAAC,MAAM,EAAE,gBAAgB,WAAW;AAE3E,QAAI,CAAC,OAAO;AACX,YAAM,IAAI,MAAM,cAAc,WAAW,sBAAsB;AAAA,IAChE;AAEA,UAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,UAAU;AAErE,QAAI,CAAC,UAAU;AACd,YAAM,IAAI,MAAM,aAAa,MAAM,UAAU,sBAAsB;AAAA,IACpE;AAEA,WAAO,cAAc,mBAAmB,aAAa,UAAU,IAAI;AAAA,EACpE;AAAA,EAEA,iBAAiB,OAAuB,OAAe,MAAyB;AAC/E,UAAM,WAAW,KAAK,eAAe,KAAK;AAE1C,QAAI,SAAS,WAAW,GAAG;AAC1B,aAAO,CAAC;AAAA,IACT;AAEA,UAAM,MAAM,UAAU,IAAI;AAC1B,UAAM,cAAc,KAAK,IAAI,OAAO,SAAS,MAAM;AAEnD,UAAM,WAAW,CAAC,GAAG,QAAQ,EAAE,KAAK,MAAM,IAAI,IAAI,GAAG;AACrD,UAAM,WAAW,SAAS,MAAM,GAAG,WAAW;AAC9C,UAAM,WAAqB,CAAC;AAE5B,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,YAAM,QAAQ,SAAS,CAAC;AACxB,YAAM,WAAW,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,UAAU;AACrE,YAAM,aAAa,SAAS,SAAY,OAAO,IAAI;AAEnD,eAAS,KAAK,cAAc,mBAAmB,MAAM,aAAa,UAAU,UAAU,CAAC;AAAA,IACxF;AAEA,WAAO;AAAA,EACR;AAAA,EAEQ,WAAW,WAA6C;AAC/D,UAAM,QAA0B,CAAC;AAEjC,eAAW,YAAY,WAAW;AACjC,iBAAW,aAAa,SAAS,YAAY;AAC5C,cAAM,QAAwB;AAAA,UAC7B,aAAa,UAAU;AAAA,UACvB,YAAY,SAAS;AAAA,UACrB,cAAc,SAAS;AAAA,UACvB,WAAW,UAAU;AAAA,UACrB,UAAU,UAAU;AAAA,UACpB,WAAW,UAAU;AAAA,UACrB,YAAY,UAAU;AAAA,QACvB;AAEA,cAAM,KAAK,KAAK;AAAA,MACjB;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AACD;;;ACxIA,IAAM,cAAc,YAAY,KAAK,uBAAuB,EAAE,OAAO,MAAM,CAAC;AAC5E,IAAM,mBAAmB,YAAY,KAAK,6BAA6B,EAAE,OAAO,MAAM,CAAC;AACvF,IAAM,iBAAiB,YAAY,KAAK,4BAA4B,EAAE,OAAO,MAAM,CAAC;AAEpF,SAAS,UAAU,MAAsB;AACxC,QAAM,QAAQ,KAAK,MAAM,GAAG;AAE5B,SAAO,MAAM,MAAM,SAAS,CAAC;AAC9B;AAEO,SAAS,kBAA4B;AAC3C,SAAO,OAAO,KAAK,WAAW,EAAE,IAAI,SAAS;AAC9C;AAEA,eAAsB,iBAAiB,IAAmC;AACzE,QAAM,WAAW,WAAW,EAAE;AAC9B,QAAM,aAAa,YAAY,QAAQ;AAEvC,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,MAAM,aAAa,EAAE,aAAa;AAAA,EAC7C;AAEA,QAAM,aAAa,MAAM,WAAW;AACpC,QAAM,OAAQ,WAAqC;AAEnD,QAAM,SAAuB;AAAA,IAC5B,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,EACnB;AAEA,SAAO;AACR;AAEA,eAAsB,cAAuC;AAC5D,QAAM,MAAM,gBAAgB;AAC5B,QAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,IAAI,CAAC,OAAO,iBAAiB,EAAE,CAAC,CAAC;AAEtE,SAAO;AACR;AAEA,eAAsB,aAAa,IAAmC;AACrE,QAAM,WAAW,WAAW,EAAE;AAC9B,QAAM,iBAAiB,WAAW,EAAE;AACpC,QAAM,gBAAgB,WAAW,EAAE;AAEnC,QAAM,aAAa,YAAY,QAAQ;AACvC,QAAM,mBAAmB,iBAAiB,cAAc;AACxD,QAAM,kBAAkB,eAAe,aAAa;AAEpD,MAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,iBAAiB;AACzD,UAAM,IAAI,MAAM,aAAa,EAAE,aAAa;AAAA,EAC7C;AAEA,QAAM,CAAC,YAAY,kBAAkB,eAAe,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzE,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,EACjB,CAAC;AAED,QAAM,OAAQ,WAAqC;AACnD,QAAM,aAAc,iBAAkD;AACtE,QAAM,YAAa,gBAA+C;AAElE,QAAM,eAA6B;AAAA,IAClC,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,EACD;AAEA,SAAO;AACR;AAEA,eAAsB,cAAc,KAAwC;AAC3E,QAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,IAAI,CAAC,OAAO,aAAa,EAAE,CAAC,CAAC;AAElE,SAAO;AACR;AAEA,eAAsB,mBAA4C;AACjE,QAAM,MAAM,gBAAgB;AAE5B,SAAO,cAAc,GAAG;AACzB;AAEA,eAAsB,kBAAqC;AAC1D,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,cAAc,oBAAI,IAAY;AAEpC,aAAW,YAAY,WAAW;AACjC,eAAW,aAAa,SAAS,YAAY;AAC5C,iBAAW,YAAY,UAAU,WAAW;AAC3C,oBAAY,IAAI,QAAQ;AAAA,MACzB;AAAA,IACD;AAAA,EACD;AAEA,QAAM,SAAS,MAAM,KAAK,WAAW,EAAE,KAAK;AAE5C,SAAO;AACR;AAEA,eAAsB,kBAA4C;AACjE,QAAM,YAAY,MAAM,iBAAiB;AACzC,QAAM,OAAO,oBAAI,IAA2B;AAE5C,aAAW,YAAY,WAAW;AACjC,eAAW,WAAW,SAAS,WAAW;AACzC,UAAI,QAAQ,QAAQ,CAAC,KAAK,IAAI,QAAQ,QAAQ,IAAI,EAAE,GAAG;AACtD,aAAK,IAAI,QAAQ,QAAQ,IAAI,IAAI,EAAE,MAAM,QAAQ,MAAM,MAAM,OAAO,CAAC;AAAA,MACtE;AAEA,UAAI,QAAQ,SAAS,CAAC,KAAK,IAAI,SAAS,QAAQ,KAAK,EAAE,GAAG;AACzD,aAAK,IAAI,SAAS,QAAQ,KAAK,IAAI,EAAE,MAAM,QAAQ,OAAO,MAAM,QAAQ,CAAC;AAAA,MAC1E;AAEA,UAAI,QAAQ,WAAW,CAAC,KAAK,IAAI,WAAW,QAAQ,OAAO,EAAE,GAAG;AAC/D,aAAK,IAAI,WAAW,QAAQ,OAAO,IAAI,EAAE,MAAM,QAAQ,SAAS,MAAM,UAAU,CAAC;AAAA,MAClF;AAAA,IACD;AAAA,EACD;AAEA,SAAO,MAAM,KAAK,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC7E;;;ACvHO,SAAS,eAAe,UAAwB,MAAuB;AAC7E,SAAO,cAAc,MAAM,UAAU,IAAI;AAC1C;","names":[]}
|