osu-play 1.0.7 → 1.2.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 +93 -39
- package/dist/cli.cjs +1579 -0
- package/dist/cli.cjs.map +25 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1569 -0
- package/dist/cli.js.map +25 -0
- package/dist/core/cli/main.d.ts +20 -0
- package/dist/core/lazer/compat.d.ts +24 -0
- package/dist/core/lazer/mod.d.ts +10 -0
- package/dist/core/lazer/schema/beatmap.d.ts +35 -0
- package/dist/core/lazer/schema/beatmapMetadata.d.ts +16 -0
- package/dist/core/lazer/schema/beatmapSet.d.ts +18 -0
- package/{src/realm/schema/mod.ts → dist/core/lazer/schema/mod.d.ts} +0 -1
- package/dist/core/lazer/schema/realmFile.d.ts +6 -0
- package/dist/core/lazer/schema/realmNamedFileUsage.d.ts +9 -0
- package/dist/core/lazer/schema/realmUser.d.ts +9 -0
- package/dist/core/player/mod.d.ts +3 -0
- package/dist/core/player/mpv.d.ts +37 -0
- package/dist/core/player/session.d.ts +45 -0
- package/dist/core/player/types.d.ts +46 -0
- package/dist/core/playlist/mod.d.ts +28 -0
- package/dist/core/tui/player-screen.d.ts +26 -0
- package/dist/core/utils/mod.d.ts +16 -0
- package/dist/index.cjs +529 -0
- package/dist/index.cjs.map +21 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +512 -0
- package/dist/index.js.map +21 -0
- package/package.json +54 -25
- package/bin/osu-play.js +0 -7
- package/index.ts +0 -1
- package/src/cli/main.ts +0 -156
- package/src/mod.ts +0 -2
- package/src/realm/mod.ts +0 -54
- package/src/realm/schema/beatmap.ts +0 -85
- package/src/realm/schema/beatmapMetadata.ts +0 -33
- package/src/realm/schema/beatmapSet.ts +0 -36
- package/src/realm/schema/realmFile.ts +0 -15
- package/src/realm/schema/realmNamedFileUsage.ts +0 -19
- package/src/realm/schema/realmUser.ts +0 -21
- package/src/utils/mod.ts +0 -77
- package/tsconfig.json +0 -109
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core/utils/mod.ts", "../src/core/lazer/compat.ts", "../src/core/lazer/schema/beatmap.ts", "../src/core/lazer/schema/beatmapMetadata.ts", "../src/core/lazer/schema/beatmapSet.ts", "../src/core/lazer/schema/realmFile.ts", "../src/core/lazer/schema/realmUser.ts", "../src/core/lazer/schema/realmNamedFileUsage.ts", "../src/core/lazer/schema/mod.ts", "../src/core/lazer/mod.ts", "../src/core/cli/main.ts", "../src/core/playlist/mod.ts", "../src/core/player/mpv.ts", "../src/core/player/session.ts", "../src/core/tui/player-screen.ts", "../src/cli.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport function getDataDir(): string | undefined {\n switch (process.platform) {\n case \"linux\":\n case \"openbsd\":\n case \"freebsd\": {\n const xdg = process.env.XDG_DATA_HOME;\n if (xdg) return xdg;\n\n const home = process.env.HOME;\n if (home) return path.join(home, \".local\", \"share\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env.HOME;\n if (home) return path.join(home, \"Library\", \"Application Support\");\n break;\n }\n\n case \"win32\":\n return process.env.LOCALAPPDATA ?? undefined;\n }\n\n return undefined;\n}\n\nexport function getConfigDir(): string | undefined {\n switch (process.platform) {\n case \"openbsd\":\n case \"freebsd\":\n case \"linux\": {\n const xdg = process.env.XDG_CONFIG_HOME;\n if (xdg) return xdg;\n\n const home = process.env.HOME;\n if (home) return path.join(home, \".config\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env.HOME;\n if (home) return path.join(home, \"Library\", \"Preferences\");\n break;\n }\n\n case \"win32\":\n return process.env.APPDATA ?? undefined;\n }\n\n return undefined;\n}\n\nexport function getDefaultOsuDataDir() {\n return path.join(getDataDir() ?? \".\", \"osu\");\n}\n\nexport function getDefaultConfigPath(appName: string = \"osu-play\") {\n return path.join(getConfigDir() ?? \".\", appName);\n}\n\nexport function hashedFilePath(\n hash: string,\n osuDataDir: string = getDefaultOsuDataDir(),\n) {\n return path.join(\n osuDataDir,\n \"files\",\n hash.slice(0, 1),\n hash.slice(0, 2),\n hash,\n );\n}\n\ntype RealmPathOptions = {\n osuDataDir?: string;\n};\n\n/**\n * Returns osu!lazer's live Realm DB path directly.\n * The legacy `appConfigDir` positional argument is accepted for backwards\n * compatibility but no longer used.\n */\nexport function getRealmDBPath(options?: RealmPathOptions): string | null;\nexport function getRealmDBPath(\n legacyAppConfigDir: string,\n options?: RealmPathOptions,\n): string | null;\nexport function getRealmDBPath(\n legacyAppConfigDirOrOptions: string | RealmPathOptions = {},\n maybeOptions: RealmPathOptions = {},\n) {\n const options =\n typeof legacyAppConfigDirOrOptions === \"string\"\n ? maybeOptions\n : legacyAppConfigDirOrOptions;\n const osuDataDir = options.osuDataDir ?? getDefaultOsuDataDir();\n const osuDBPath = path.join(osuDataDir, \"client.realm\");\n\n if (!existsSync(osuDBPath)) {\n console.log(`[getRealmDBPath]: ${osuDBPath} not found`);\n return null;\n }\n\n return osuDBPath;\n}\n",
|
|
6
|
+
"type SchemaPropertyLike = {\n type?: string;\n objectType?: string;\n};\n\ntype SchemaEntryLike = {\n name: string;\n properties: Record<string, SchemaPropertyLike>;\n};\n\ntype RequiredSchemaShape = Record<\n string,\n Record<string, { type?: string; objectType?: string }>\n>;\n\nexport type LazerSchemaCompatibilityIssue = {\n objectName: string;\n propertyName: string;\n expected: string;\n actual: string;\n};\n\nexport type LazerSchemaCompatibilityReport = {\n compatible: boolean;\n version: number;\n missingObjects: string[];\n issues: LazerSchemaCompatibilityIssue[];\n};\n\nexport const LAST_STATIC_LAZER_SCHEMA_VERSION = 46;\n\nconst REQUIRED_PLAYLIST_SCHEMA: RequiredSchemaShape = {\n BeatmapSet: {\n Beatmaps: { type: \"list\", objectType: \"Beatmap\" },\n Files: { type: \"list\", objectType: \"RealmNamedFileUsage\" },\n },\n Beatmap: {\n Metadata: { type: \"object\", objectType: \"BeatmapMetadata\" },\n },\n BeatmapMetadata: {\n AudioFile: { type: \"string\" },\n Title: { type: \"string\" },\n Artist: { type: \"string\" },\n TitleUnicode: { type: \"string\" },\n ArtistUnicode: { type: \"string\" },\n },\n RealmNamedFileUsage: {\n File: { type: \"object\", objectType: \"File\" },\n Filename: { type: \"string\" },\n },\n File: {\n Hash: { type: \"string\" },\n },\n};\n\nfunction describeRequirement(requirement: { type?: string; objectType?: string }) {\n if (requirement.type === \"object\" || requirement.type === \"list\") {\n return `${requirement.type}:${requirement.objectType ?? \"unknown\"}`;\n }\n\n return requirement.type ?? \"unknown\";\n}\n\nfunction describeProperty(property: SchemaPropertyLike | undefined) {\n if (!property?.type) {\n return \"missing\";\n }\n\n if (property.type === \"object\" || property.type === \"list\") {\n return `${property.type}:${property.objectType ?? \"unknown\"}`;\n }\n\n return property.type;\n}\n\nexport function inspectLazerSchemaEntries(\n schemaEntries: SchemaEntryLike[],\n version: number,\n): LazerSchemaCompatibilityReport {\n const schemaByName = new Map(schemaEntries.map((entry) => [entry.name, entry]));\n const missingObjects: string[] = [];\n const issues: LazerSchemaCompatibilityIssue[] = [];\n\n for (const [objectName, requirements] of Object.entries(REQUIRED_PLAYLIST_SCHEMA)) {\n const schemaEntry = schemaByName.get(objectName);\n if (!schemaEntry) {\n missingObjects.push(objectName);\n continue;\n }\n\n for (const [propertyName, requirement] of Object.entries(requirements)) {\n const property = schemaEntry.properties[propertyName];\n const typeMatches = !requirement.type || property?.type === requirement.type;\n const objectTypeMatches =\n !requirement.objectType || property?.objectType === requirement.objectType;\n\n if (!typeMatches || !objectTypeMatches) {\n issues.push({\n objectName,\n propertyName,\n expected: describeRequirement(requirement),\n actual: describeProperty(property),\n });\n }\n }\n }\n\n return {\n compatible: missingObjects.length === 0 && issues.length === 0,\n version,\n missingObjects,\n issues,\n };\n}\n\nexport function formatLazerSchemaCompatibilityError(\n report: LazerSchemaCompatibilityReport,\n) {\n const details = [\n `Detected osu!lazer schema version ${report.version}, but the playlist reader is missing fields it needs.`,\n ];\n\n if (report.missingObjects.length > 0) {\n details.push(`Missing objects: ${report.missingObjects.join(\", \")}`);\n }\n\n if (report.issues.length > 0) {\n details.push(\n `Mismatched properties: ${report.issues\n .map(\n (issue) =>\n `${issue.objectName}.${issue.propertyName} expected ${issue.expected}, got ${issue.actual}`,\n )\n .join(\"; \")}`,\n );\n }\n\n details.push(\n \"This app now reflects the live lazer schema and only depends on a small playlist-safe subset, so version bumps are fine until those required fields change.\",\n );\n\n return details.join(\"\\n\");\n}\n",
|
|
7
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { BeatmapMetadata } from \"./beatmapMetadata.js\";\n\nexport class Beatmap extends Realm.Object<Beatmap> {\n ID!: string;\n DifficultyName?: string;\n Metadata!: BeatmapMetadata;\n BeatmapSet!: any;\n Status!: number;\n OnlineID!: number;\n Length!: number;\n BPM!: number;\n Hash?: string;\n StarRating!: number;\n MD5Hash?: string;\n OnlineMD5Hash?: string;\n LastLocalUpdate?: Date;\n LastOnlineUpdate?: Date;\n Hidden!: boolean;\n AudioLeadIn!: number;\n StackLeniency!: number;\n SpecialStyle!: boolean;\n LetterboxInBreaks!: boolean;\n WidescreenStoryboard!: boolean;\n EpilepsyWarning!: boolean;\n SamplesMatchPlaybackRate!: boolean;\n LastPlayed?: Date;\n DistanceSpacing!: number;\n BeatDivisor!: number;\n GridSize!: number;\n TimelineZoom!: number;\n EditorTimestamp?: number;\n CountdownOffset!: number;\n\n static schema: ObjectSchema = {\n name: \"Beatmap\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n DifficultyName: { type: \"string\", default: \"\", optional: true },\n Metadata: {\n type: \"object\",\n objectType: \"BeatmapMetadata\",\n default: null,\n },\n BeatmapSet: { type: \"object\", objectType: \"BeatmapSet\", default: null },\n Status: { type: \"int\", default: -3 },\n OnlineID: { type: \"int\", default: -1 },\n Length: { type: \"double\", default: 0 },\n BPM: { type: \"double\", default: 0 },\n Hash: { type: \"string\", default: \"\", optional: true },\n StarRating: { type: \"double\", default: -1 },\n MD5Hash: { type: \"string\", default: \"\", optional: true },\n OnlineMD5Hash: { type: \"string\", default: \"\", optional: true },\n LastLocalUpdate: { type: \"date\", optional: true },\n LastOnlineUpdate: { type: \"date\", optional: true },\n Hidden: { type: \"bool\", default: false },\n AudioLeadIn: { type: \"double\", default: 0 },\n StackLeniency: { type: \"float\", default: 0.7 },\n SpecialStyle: { type: \"bool\", default: false },\n LetterboxInBreaks: { type: \"bool\", default: false },\n WidescreenStoryboard: { type: \"bool\", default: false },\n EpilepsyWarning: { type: \"bool\", default: false },\n SamplesMatchPlaybackRate: { type: \"bool\", default: false },\n LastPlayed: { type: \"date\", optional: true },\n DistanceSpacing: { type: \"double\", default: 0 },\n BeatDivisor: { type: \"int\", default: 0 },\n GridSize: { type: \"int\", default: 0 },\n TimelineZoom: { type: \"double\", default: 0 },\n EditorTimestamp: { type: \"double\", optional: true },\n CountdownOffset: { type: \"int\", default: 0 },\n },\n };\n}\n",
|
|
8
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmUser } from \"./realmUser.js\";\n\nexport class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {\n Title?: string;\n TitleUnicode?: string;\n Artist?: string;\n ArtistUnicode?: string;\n Author?: RealmUser;\n Source?: string;\n Tags?: string;\n PreviewTime?: number;\n AudioFile?: string;\n BackgroundFile?: string;\n\n static schema: ObjectSchema = {\n name: \"BeatmapMetadata\",\n properties: {\n Title: { type: \"string\", default: \"\", optional: true },\n TitleUnicode: { type: \"string\", default: \"\", optional: true },\n Artist: { type: \"string\", default: \"\", optional: true },\n ArtistUnicode: { type: \"string\", default: \"\", optional: true },\n Author: { type: \"object\", objectType: \"RealmUser\", default: null },\n Source: { type: \"string\", default: \"\", optional: true },\n Tags: { type: \"string\", default: \"\", optional: true },\n PreviewTime: { type: \"int\", default: 0 },\n AudioFile: { type: \"string\", default: \"\", optional: true },\n BackgroundFile: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n",
|
|
9
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { Beatmap } from \"./beatmap.js\";\nimport { RealmNamedFileUsage } from \"./realmNamedFileUsage.js\";\n\nexport class BeatmapSet extends Realm.Object<BeatmapSet> {\n ID!: string;\n OnlineID!: number;\n DateAdded!: Date;\n DateSubmitted?: Date;\n DateRanked?: Date;\n Beatmaps!: Realm.List<Beatmap>;\n Files!: Realm.List<RealmNamedFileUsage>;\n Status!: number;\n DeletePending!: boolean;\n Hash?: string;\n Protected!: boolean;\n\n static schema: ObjectSchema = {\n name: \"BeatmapSet\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n OnlineID: { type: \"int\", default: -1 },\n DateAdded: { type: \"date\" },\n DateSubmitted: { type: \"date\", optional: true },\n DateRanked: { type: \"date\", optional: true },\n Beatmaps: { type: \"list\", objectType: \"Beatmap\", default: [] },\n Files: { type: \"list\", objectType: \"RealmNamedFileUsage\", default: [] },\n Status: { type: \"int\", default: -3 },\n DeletePending: { type: \"bool\", default: false },\n Hash: { type: \"string\", default: \"\", optional: true },\n Protected: { type: \"bool\", default: false },\n },\n };\n}\n",
|
|
10
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmFile extends Realm.Object<RealmFile> {\n Hash?: string;\n\n static schema: ObjectSchema = {\n name: \"File\",\n primaryKey: \"Hash\",\n properties: {\n Hash: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n",
|
|
11
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmUser extends Realm.Object<RealmUser> {\n OnlineID!: number;\n Username?: string;\n CountryCode?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmUser\",\n embedded: true,\n properties: {\n OnlineID: { type: \"int\", default: 1 },\n Username: { type: \"string\", default: \"\", optional: true },\n CountryCode: { type: \"string\", optional: true },\n },\n };\n}\n\n",
|
|
12
|
+
"import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmFile } from \"./realmFile.js\";\n\nexport class RealmNamedFileUsage extends Realm.Object<RealmNamedFileUsage> {\n File!: RealmFile;\n Filename?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmNamedFileUsage\",\n embedded: true,\n properties: {\n File: \"File\",\n Filename: { type: \"string\", optional: true },\n },\n };\n}\n",
|
|
13
|
+
"export { Beatmap } from \"./beatmap.js\";\nexport { BeatmapMetadata } from \"./beatmapMetadata.js\";\nexport { BeatmapSet } from \"./beatmapSet.js\";\nexport { RealmFile } from \"./realmFile.js\";\nexport { RealmUser } from \"./realmUser.js\";\nexport { RealmNamedFileUsage } from \"./realmNamedFileUsage.js\";\n",
|
|
14
|
+
"import Realm from \"realm\";\nimport type { PlaylistBeatmapSet } from \"../playlist/mod.js\";\nimport type { BeatmapSet } from \"./schema/beatmapSet.js\";\nimport { inspectLazerSchemaEntries } from \"./compat.js\";\n\nexport {\n Beatmap,\n BeatmapMetadata,\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n RealmUser,\n} from \"./schema/mod.js\";\nexport {\n formatLazerSchemaCompatibilityError,\n inspectLazerSchemaEntries,\n LAST_STATIC_LAZER_SCHEMA_VERSION,\n} from \"./compat.js\";\nexport { hashedFilePath } from \"../utils/mod.js\";\n\ntype SchemaPropertyLike = {\n type?: string;\n objectType?: string;\n};\n\ntype SchemaEntryLike = {\n name: string;\n properties: Record<string, SchemaPropertyLike>;\n};\n\nexport function inspectLazerSchema(realm: Realm) {\n return inspectLazerSchemaEntries(\n realm.schema as unknown as SchemaEntryLike[],\n Realm.schemaVersion(realm.path),\n );\n}\n\nexport const getLazerDB = async (realmDBPath: string) => {\n return Realm.open({\n path: realmDBPath,\n readOnly: true,\n });\n};\n\nexport function getBeatmapSets(realm: Realm) {\n return realm.objects(\"BeatmapSet\") as unknown as Iterable<PlaylistBeatmapSet>;\n}\n\nexport const getNamedFileHash = (fileName: string, beatmapSet: BeatmapSet) => {\n const files = beatmapSet.Files;\n for (const file of files) {\n if (file.Filename == fileName) return file.File.Hash;\n }\n return undefined;\n};\n",
|
|
15
|
+
"import path from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\n\nimport { ProcessTerminal, TUI } from \"@mariozechner/pi-tui\";\nimport yargs from \"yargs/yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nimport { buildPlaylist } from \"../playlist/mod.js\";\nimport { MpvPlayerBackend, PlaylistPlayerSession } from \"../player/mod.js\";\nimport { PlaylistPlayerScreen } from \"../tui/player-screen.js\";\nimport { getDefaultOsuDataDir, getRealmDBPath } from \"../utils/mod.js\";\n\nfunction formatRealmLoadError(error: unknown) {\n return [\n \"Realm native bindings could not be loaded.\",\n `Current Node runtime: ${process.version}.`,\n \"To repair Realm bindings in this project, run `bun run repair:realm` (or `bun run setup` to reinstall dependencies).\",\n \"If you installed dependencies on Node 22, switch to Node 20 LTS and rerun the repair command.\",\n `Original error: ${error instanceof Error ? error.message : String(error)}`,\n ].join(\"\\n\");\n}\n\nasync function loadRealmDependencies() {\n try {\n const [{ default: Realm }, lazerModule] = await Promise.all([\n import(\"realm\"),\n import(\"../lazer/mod.js\"),\n ]);\n\n return {\n Realm,\n ...lazerModule,\n };\n } catch (error) {\n throw new Error(formatRealmLoadError(error), { cause: error });\n }\n}\n\nexport function getArgs() {\n return yargs(hideBin(process.argv))\n .scriptName(\"osu-play\")\n .usage(\n \"Play music from your osu!lazer beatmaps in a minimal terminal player\\nUsage: $0 [options]\",\n )\n .option(\"reload\", {\n type: \"boolean\",\n default: false,\n alias: \"r\",\n describe: \"Deprecated: ignored. osu-play now reads the live lazer database directly\",\n })\n .option(\"exportPlaylist\", {\n type: \"string\",\n describe: \"Export playlist to a file instead of launching the player\",\n })\n .option(\"osuDataDir\", {\n type: \"string\",\n default: getDefaultOsuDataDir(),\n alias: \"d\",\n describe: \"Osu!lazer data directory\",\n })\n .option(\"configDir\", {\n type: \"string\",\n alias: \"c\",\n describe: \"Deprecated: ignored. osu-play no longer copies the lazer database\",\n })\n .option(\"loop\", {\n type: \"boolean\",\n default: false,\n alias: \"l\",\n describe: \"Loop the playlist when playback reaches the end\",\n })\n .alias(\"help\", \"h\")\n .help()\n .parse();\n}\n\nasync function createPlaylist(osuDataDir: string) {\n const realmDBPath = getRealmDBPath({ osuDataDir });\n if (!realmDBPath) {\n throw new Error(\"Realm DB not found\");\n }\n\n const {\n Realm,\n formatLazerSchemaCompatibilityError,\n getBeatmapSets,\n getLazerDB,\n inspectLazerSchema,\n } = await loadRealmDependencies();\n\n Realm.flags.ALLOW_CLEAR_TEST_STATE = true;\n\n const realm = await getLazerDB(realmDBPath);\n\n try {\n const schemaReport = inspectLazerSchema(realm);\n if (!schemaReport.compatible) {\n throw new Error(formatLazerSchemaCompatibilityError(schemaReport));\n }\n\n return buildPlaylist(getBeatmapSets(realm), osuDataDir);\n } finally {\n realm.close();\n }\n}\n\nasync function runTuiPlayer(\n playlist: Awaited<ReturnType<typeof createPlaylist>>,\n loop: boolean,\n) {\n const backend = new MpvPlayerBackend();\n const session = new PlaylistPlayerSession(playlist, backend, { loop });\n const terminal = new ProcessTerminal();\n const tui = new TUI(terminal);\n const screen = new PlaylistPlayerScreen(session, () => terminal.rows);\n\n let started = false;\n\n const exitPromise = new Promise<void>((resolve) => {\n screen.onQuit = () => resolve();\n });\n\n const unsubscribe = session.subscribe((snapshot) => {\n screen.setSnapshot(snapshot);\n if (started) {\n tui.requestRender();\n }\n });\n\n try {\n await session.start();\n\n tui.addChild(screen);\n tui.setFocus(screen);\n tui.start();\n started = true;\n\n await exitPromise;\n } finally {\n unsubscribe();\n\n if (started) {\n await terminal.drainInput().catch(() => {});\n tui.stop();\n }\n\n await session.dispose();\n }\n}\n\nexport async function main() {\n const argv = await getArgs();\n\n if (argv.reload) {\n console.log(\n \"[INFO] `--reload` is deprecated and ignored because osu-play reads osu!lazer's live Realm DB directly.\",\n );\n }\n\n if (argv.configDir) {\n console.log(\n \"[INFO] `--configDir` is deprecated and ignored because osu-play no longer copies the Realm DB.\",\n );\n }\n\n const playlist = await createPlaylist(argv.osuDataDir);\n\n if (argv.exportPlaylist) {\n const playlistContents = playlist.map((track) => track.path).join(\"\\n\");\n writeFileSync(argv.exportPlaylist, playlistContents);\n console.log(\n `[INFO] Exported ${playlist.length} tracks to ${argv.exportPlaylist}.`,\n );\n console.log(\n `[INFO] Use something like \\`mpv --playlist=${path.resolve(argv.exportPlaylist)}\\` to play the playlist.`,\n );\n return;\n }\n\n await runTuiPlayer(playlist, argv.loop);\n}\n",
|
|
16
|
+
"import { hashedFilePath } from \"../utils/mod.js\";\n\nexport type PlaylistBeatmapMetadata = {\n AudioFile?: string | null;\n Title?: string | null;\n Artist?: string | null;\n TitleUnicode?: string | null;\n ArtistUnicode?: string | null;\n};\n\nexport type PlaylistBeatmap = {\n Metadata: PlaylistBeatmapMetadata;\n};\n\nexport type PlaylistFile = {\n Filename?: string | null;\n File?: {\n Hash?: string | null;\n } | null;\n};\n\nexport type PlaylistBeatmapSet = {\n Beatmaps: Iterable<PlaylistBeatmap>;\n Files: Iterable<PlaylistFile>;\n};\n\nexport type PlaylistTrack = {\n hash: string;\n path: string;\n title: string;\n};\n\nfunction uniqueParts(parts: Array<string | null | undefined>) {\n return [...new Set(parts.map((part) => part?.trim()).filter(Boolean))];\n}\n\nexport function formatTrackTitle(metadata: PlaylistBeatmapMetadata) {\n const title = uniqueParts([metadata.Title, metadata.TitleUnicode]).join(\" / \");\n const artist = uniqueParts([metadata.Artist, metadata.ArtistUnicode]).join(\" / \");\n\n return `${title || \"Unknown Title\"} - ${artist || \"Unknown Artist\"}`;\n}\n\nexport function getNamedFileHash(fileName: string, beatmapSet: PlaylistBeatmapSet) {\n for (const file of beatmapSet.Files) {\n if (file.Filename === fileName && file.File?.Hash) {\n return file.File.Hash;\n }\n }\n\n return undefined;\n}\n\nexport function buildPlaylist(\n beatmapSets: Iterable<PlaylistBeatmapSet>,\n osuDataDir: string,\n) {\n const seenHashes = new Set<string>();\n const playlist: PlaylistTrack[] = [];\n\n for (const beatmapSet of beatmapSets) {\n for (const beatmap of beatmapSet.Beatmaps) {\n const hash = getNamedFileHash(beatmap.Metadata.AudioFile ?? \"\", beatmapSet);\n if (!hash || seenHashes.has(hash)) {\n continue;\n }\n\n seenHashes.add(hash);\n playlist.push({\n hash,\n path: hashedFilePath(hash, osuDataDir),\n title: formatTrackTitle(beatmap.Metadata),\n });\n }\n }\n\n return playlist;\n}\n",
|
|
17
|
+
"import { spawn, type ChildProcess } from \"node:child_process\";\nimport { existsSync, rmSync } from \"node:fs\";\nimport net from \"node:net\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\n\nimport type {\n PlayerBackend,\n PlayerBackendEvent,\n PlayerBackendListener,\n PlayerBackendSnapshot,\n} from \"./types.js\";\n\ntype PendingCommand = {\n reject: (error: Error) => void;\n resolve: (value: unknown) => void;\n};\n\ntype MpvResponse = {\n data?: unknown;\n error?: string;\n event?: string;\n name?: string;\n reason?: string;\n request_id?: number;\n};\n\nfunction getErrorCode(error: unknown) {\n if (error && typeof error === \"object\" && \"code\" in error) {\n const { code } = error as NodeJS.ErrnoException;\n return typeof code === \"string\" ? code : null;\n }\n\n return null;\n}\n\nfunction isRetryableSocketError(error: unknown) {\n const code = getErrorCode(error);\n if (code) {\n return (\n code === \"ENOENT\"\n || code === \"ECONNREFUSED\"\n || code === \"EPERM\"\n || code === \"EACCES\"\n );\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return (\n message.includes(\"ENOENT\")\n || message.includes(\"ECONNREFUSED\")\n || message.includes(\"EPERM\")\n || message.includes(\"EACCES\")\n );\n}\n\nfunction createSocketPath() {\n const id = `osu-play-mpv-${process.pid}-${Date.now()}`;\n if (process.platform === \"win32\") {\n return `\\\\\\\\.\\\\pipe\\\\${id}`;\n }\n\n return path.join(os.tmpdir(), `${id}.sock`);\n}\n\nfunction isControlText(value: string) {\n return [...value].some((character) => {\n const code = character.charCodeAt(0);\n return code < 32 || code === 0x7f || (code >= 0x80 && code <= 0x9f);\n });\n}\n\nexport class MpvPlayerBackend implements PlayerBackend {\n readonly name = \"mpv\";\n\n private connectPromise: Promise<void> | null = null;\n\n private disposePromise: Promise<void> | null = null;\n\n private disposing = false;\n\n private readonly listeners = new Set<PlayerBackendListener>();\n\n private readonly pendingCommands = new Map<number, PendingCommand>();\n\n private idleActive = true;\n\n private process: ChildProcess | null = null;\n\n private requestId = 0;\n\n private responseBuffer = \"\";\n\n private snapshot: PlayerBackendSnapshot = {\n backendName: \"mpv\",\n currentPath: null,\n durationSeconds: null,\n errorMessage: null,\n status: \"stopped\",\n timePositionSeconds: null,\n };\n\n private socket: net.Socket | null = null;\n\n private readonly socketPath = createSocketPath();\n\n private stderrBuffer = \"\";\n\n getSnapshot() {\n return this.snapshot;\n }\n\n subscribe(listener: PlayerBackendListener) {\n this.listeners.add(listener);\n listener({\n snapshot: this.snapshot,\n type: \"state\",\n });\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n async start() {\n if (this.socket && !this.socket.destroyed) {\n return;\n }\n\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = this.startInternal();\n\n try {\n await this.connectPromise;\n } finally {\n this.connectPromise = null;\n }\n }\n\n async play(filePath: string) {\n await this.start();\n\n const previousSnapshot = this.snapshot;\n\n try {\n await this.sendCommand([\"loadfile\", filePath, \"replace\"]);\n await this.sendCommand([\"set_property\", \"pause\", false]);\n } catch (error) {\n this.snapshot = previousSnapshot;\n this.emit({\n snapshot: this.snapshot,\n type: \"state\",\n });\n throw error;\n }\n\n this.snapshot = {\n ...this.snapshot,\n currentPath: filePath,\n errorMessage: null,\n status: this.idleActive ? \"stopped\" : \"playing\",\n timePositionSeconds: this.snapshot.timePositionSeconds ?? 0,\n };\n this.emit({\n snapshot: this.snapshot,\n type: \"state\",\n });\n }\n\n async togglePause() {\n await this.start();\n await this.sendCommand([\"cycle\", \"pause\"]);\n }\n\n async seekBy(seconds: number) {\n await this.start();\n await this.sendCommand([\"seek\", seconds, \"relative\"]);\n }\n\n async stop() {\n if (!this.socket || this.socket.destroyed) {\n return;\n }\n\n await this.sendCommand([\"stop\"]);\n this.idleActive = true;\n this.snapshot = {\n ...this.snapshot,\n status: \"stopped\",\n timePositionSeconds: null,\n };\n this.emit({\n snapshot: this.snapshot,\n type: \"state\",\n });\n }\n\n async dispose() {\n if (this.disposePromise) {\n return this.disposePromise;\n }\n\n this.disposePromise = this.disposeInternal();\n\n try {\n await this.disposePromise;\n } finally {\n this.disposePromise = null;\n }\n }\n\n private emit(event: PlayerBackendEvent) {\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n private async startInternal() {\n this.cleanupSocketPath();\n this.disposing = false;\n this.stderrBuffer = \"\";\n\n const processHandle = spawn(\n \"mpv\",\n [\n \"--no-config\",\n \"--no-terminal\",\n \"--idle=yes\",\n \"--force-window=no\",\n \"--audio-display=no\",\n \"--really-quiet\",\n `--input-ipc-server=${this.socketPath}`,\n ],\n {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n },\n );\n\n this.process = processHandle;\n\n processHandle.stderr.setEncoding(\"utf8\");\n processHandle.stderr.on(\"data\", (chunk: string) => {\n this.stderrBuffer = `${this.stderrBuffer}${chunk}`.slice(-4000);\n });\n\n processHandle.once(\"error\", (error) => {\n this.handleError(error);\n });\n\n processHandle.once(\"exit\", (code, signal) => {\n if (this.disposing) {\n return;\n }\n\n const detail = this.stderrBuffer.trim();\n const suffix = detail ? `\\n${detail}` : \"\";\n this.handleError(\n new Error(\n `mpv exited unexpectedly with ${signal ? `signal ${signal}` : `code ${code}`}.${suffix}`,\n ),\n );\n });\n\n await this.connectSocket();\n await Promise.all([\n this.sendCommand([\"observe_property\", 1, \"pause\"]),\n this.sendCommand([\"observe_property\", 2, \"time-pos\"]),\n this.sendCommand([\"observe_property\", 3, \"duration\"]),\n this.sendCommand([\"observe_property\", 4, \"idle-active\"]),\n ]);\n }\n\n private async connectSocket() {\n const start = Date.now();\n const timeoutMs = 5000;\n\n while (Date.now() - start < timeoutMs) {\n if (!this.process || this.process.exitCode !== null) {\n throw new Error(this.formatStartupError(\"mpv exited before opening its IPC socket.\"));\n }\n\n try {\n await this.attachSocket();\n return;\n } catch (error) {\n if (!isRetryableSocketError(error)) {\n throw error;\n }\n }\n\n await delay(50);\n }\n\n throw new Error(this.formatStartupError(\"Timed out waiting for mpv IPC to become ready.\"));\n }\n\n private async attachSocket() {\n await new Promise<void>((resolve, reject) => {\n const socket = net.createConnection(this.socketPath);\n\n const onError = (error: Error) => {\n socket.destroy();\n reject(error);\n };\n\n socket.once(\"error\", onError);\n socket.once(\"connect\", () => {\n socket.removeListener(\"error\", onError);\n socket.setEncoding(\"utf8\");\n socket.on(\"data\", (chunk: string) => {\n this.handleSocketData(chunk);\n });\n socket.on(\"error\", (error) => {\n if (!this.disposing) {\n this.handleError(error);\n }\n });\n socket.on(\"close\", () => {\n if (!this.disposing) {\n this.handleError(new Error(\"mpv IPC socket closed unexpectedly.\"));\n }\n });\n this.socket = socket;\n resolve();\n });\n });\n }\n\n private async sendCommand(command: unknown[]) {\n const socket = this.socket;\n if (!socket || socket.destroyed) {\n throw new Error(\"mpv IPC socket is not connected.\");\n }\n\n const requestId = ++this.requestId;\n\n return new Promise<unknown>((resolve, reject) => {\n this.pendingCommands.set(requestId, { reject, resolve });\n\n socket.write(\n `${JSON.stringify({ command, request_id: requestId })}\\n`,\n (error) => {\n if (!error) {\n return;\n }\n\n this.pendingCommands.delete(requestId);\n reject(error);\n },\n );\n });\n }\n\n private handleSocketData(chunk: string) {\n this.responseBuffer += chunk;\n\n while (true) {\n const newlineIndex = this.responseBuffer.indexOf(\"\\n\");\n if (newlineIndex === -1) {\n return;\n }\n\n const line = this.responseBuffer.slice(0, newlineIndex).trim();\n this.responseBuffer = this.responseBuffer.slice(newlineIndex + 1);\n\n if (!line) {\n continue;\n }\n\n try {\n const response = JSON.parse(line) as MpvResponse;\n this.handleResponse(response);\n } catch (error) {\n this.handleError(\n new Error(\n `Failed to parse mpv IPC message: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n }\n }\n }\n\n private handleResponse(response: MpvResponse) {\n if (typeof response.request_id === \"number\") {\n const pending = this.pendingCommands.get(response.request_id);\n if (pending) {\n this.pendingCommands.delete(response.request_id);\n if (response.error && response.error !== \"success\") {\n pending.reject(new Error(`mpv command failed: ${response.error}`));\n } else {\n pending.resolve(response.data);\n }\n }\n return;\n }\n\n if (response.event === \"property-change\") {\n this.applyPropertyChange(response.name, response.data);\n return;\n }\n\n if (response.event === \"end-file\") {\n this.snapshot = {\n ...this.snapshot,\n status: \"stopped\",\n timePositionSeconds: this.snapshot.durationSeconds,\n };\n this.emit({\n snapshot: this.snapshot,\n type: \"state\",\n });\n this.emit({\n reason: response.reason ?? \"unknown\",\n type: \"ended\",\n });\n }\n }\n\n private applyPropertyChange(name: string | undefined, data: unknown) {\n switch (name) {\n case \"pause\":\n this.snapshot = {\n ...this.snapshot,\n status: data === true ? \"paused\" : this.idleActive ? \"stopped\" : \"playing\",\n };\n break;\n case \"time-pos\":\n this.snapshot = {\n ...this.snapshot,\n timePositionSeconds: typeof data === \"number\" ? data : null,\n };\n break;\n case \"duration\":\n this.snapshot = {\n ...this.snapshot,\n durationSeconds: typeof data === \"number\" ? data : null,\n };\n break;\n case \"idle-active\":\n this.idleActive = data === true;\n this.snapshot = {\n ...this.snapshot,\n status:\n data === true\n ? \"stopped\"\n : this.snapshot.status === \"paused\"\n ? \"paused\"\n : \"playing\",\n timePositionSeconds:\n data === true ? this.snapshot.durationSeconds : this.snapshot.timePositionSeconds,\n };\n break;\n default:\n return;\n }\n\n this.emit({\n snapshot: this.snapshot,\n type: \"state\",\n });\n }\n\n private handleError(error: unknown) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n\n this.snapshot = {\n ...this.snapshot,\n errorMessage: normalizedError.message,\n status: \"stopped\",\n };\n\n this.emit({\n error: normalizedError,\n type: \"error\",\n });\n\n for (const [requestId, pending] of this.pendingCommands) {\n this.pendingCommands.delete(requestId);\n pending.reject(normalizedError);\n }\n }\n\n private async disposeInternal() {\n this.disposing = true;\n\n if (this.socket && !this.socket.destroyed) {\n try {\n await this.sendCommand([\"quit\"]);\n } catch {\n // Ignore quit errors during shutdown.\n }\n }\n\n this.socket?.destroy();\n this.socket = null;\n\n const processHandle = this.process;\n this.process = null;\n if (processHandle && processHandle.exitCode === null) {\n processHandle.kill(\"SIGTERM\");\n await Promise.race([\n new Promise<void>((resolve) => {\n processHandle.once(\"exit\", () => resolve());\n }),\n delay(1000),\n ]);\n\n if (processHandle.exitCode === null) {\n processHandle.kill(\"SIGKILL\");\n }\n }\n\n this.cleanupSocketPath();\n }\n\n private cleanupSocketPath() {\n if (process.platform === \"win32\") {\n return;\n }\n\n if (existsSync(this.socketPath)) {\n rmSync(this.socketPath, { force: true });\n }\n }\n\n private formatStartupError(message: string) {\n const stderr = this.stderrBuffer.trim();\n const cleanStderr = stderr && !isControlText(stderr) ? `\\n${stderr}` : \"\";\n\n return [\n message,\n \"osu-play now expects `mpv` to be installed and available on PATH for TUI playback.\",\n cleanStderr,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n }\n}\n",
|
|
18
|
+
"import type { PlaylistTrack } from \"../playlist/mod.js\";\nimport type {\n PlayerBackend,\n PlayerBackendEvent,\n PlaylistPlayerListener,\n PlaylistPlayerSnapshot,\n} from \"./types.js\";\n\nfunction clampIndex(index: number, length: number) {\n if (length <= 0) {\n return 0;\n }\n\n return Math.max(0, Math.min(index, length - 1));\n}\n\nfunction wrapIndex(index: number, length: number) {\n if (length <= 0) {\n return 0;\n }\n\n return ((index % length) + length) % length;\n}\n\nfunction normalizeSearchText(text: string) {\n return text.trim().toLowerCase();\n}\n\nexport function findTrackIndexByQuery(\n playlist: PlaylistTrack[],\n query: string,\n) {\n const normalizedQuery = normalizeSearchText(query);\n if (!normalizedQuery) {\n return -1;\n }\n\n return playlist.findIndex((track) =>\n normalizeSearchText(track.title).includes(normalizedQuery),\n );\n}\n\ntype PlaylistPlayerSessionOptions = {\n loop?: boolean;\n};\n\nexport class PlaylistPlayerSession {\n private readonly listeners = new Set<PlaylistPlayerListener>();\n\n private currentIndex: number | null = null;\n\n private errorMessage: string | null = null;\n\n private loop: boolean;\n\n private readonly playlist: PlaylistTrack[];\n\n private searchQuery = \"\";\n\n private selectedIndex = 0;\n\n private readonly unsubscribeBackend: () => void;\n\n constructor(\n playlist: PlaylistTrack[],\n private readonly backend: PlayerBackend,\n options: PlaylistPlayerSessionOptions = {},\n ) {\n this.playlist = playlist;\n this.loop = options.loop ?? false;\n this.unsubscribeBackend = backend.subscribe((event) => {\n void this.handleBackendEvent(event);\n });\n }\n\n getSnapshot(): PlaylistPlayerSnapshot {\n const backendSnapshot = this.backend.getSnapshot();\n const currentTrack =\n this.currentIndex !== null ? this.playlist[this.currentIndex] ?? null : null;\n\n return {\n backendName: backendSnapshot.backendName,\n currentIndex: this.currentIndex,\n currentTrack,\n durationSeconds: backendSnapshot.durationSeconds,\n errorMessage: this.errorMessage ?? backendSnapshot.errorMessage,\n loop: this.loop,\n playlist: this.playlist,\n searchQuery: this.searchQuery,\n selectedIndex: this.selectedIndex,\n status: backendSnapshot.status,\n timePositionSeconds: backendSnapshot.timePositionSeconds,\n };\n }\n\n subscribe(listener: PlaylistPlayerListener) {\n this.listeners.add(listener);\n listener(this.getSnapshot());\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n async start() {\n await this.backend.start();\n this.emit();\n }\n\n async dispose() {\n this.unsubscribeBackend();\n await this.backend.dispose();\n }\n\n moveSelection(delta: number) {\n if (this.playlist.length === 0) {\n return;\n }\n\n this.selectedIndex = wrapIndex(\n this.selectedIndex + delta,\n this.playlist.length,\n );\n this.emit();\n }\n\n moveSelectionPage(delta: number, pageSize: number) {\n this.moveSelection(delta * Math.max(1, pageSize));\n }\n\n selectHome() {\n if (this.playlist.length === 0) {\n return;\n }\n\n this.selectedIndex = 0;\n this.emit();\n }\n\n selectEnd() {\n if (this.playlist.length === 0) {\n return;\n }\n\n this.selectedIndex = this.playlist.length - 1;\n this.emit();\n }\n\n setSelectionIndex(index: number) {\n if (this.playlist.length === 0) {\n return;\n }\n\n this.selectedIndex = clampIndex(index, this.playlist.length);\n this.emit();\n }\n\n toggleLoop() {\n this.loop = !this.loop;\n this.emit();\n }\n\n appendSearchQuery(text: string) {\n if (!text) {\n return;\n }\n\n this.searchQuery += text;\n this.syncSelectionToSearch();\n }\n\n deleteSearchCharacter() {\n if (!this.searchQuery) {\n return;\n }\n\n this.searchQuery = this.searchQuery.slice(0, -1);\n this.syncSelectionToSearch();\n }\n\n clearSearch() {\n if (!this.searchQuery) {\n return;\n }\n\n this.searchQuery = \"\";\n this.emit();\n }\n\n async playSelected() {\n await this.playIndex(this.selectedIndex);\n }\n\n async playNext() {\n const nextIndex = this.getAdjacentIndex(1);\n if (nextIndex === null) {\n return;\n }\n\n await this.playIndex(nextIndex);\n }\n\n async playPrevious() {\n const previousIndex = this.getAdjacentIndex(-1);\n if (previousIndex === null) {\n return;\n }\n\n await this.playIndex(previousIndex);\n }\n\n async togglePause() {\n if (this.playlist.length === 0) {\n return;\n }\n\n const { status } = this.backend.getSnapshot();\n if (status === \"stopped\") {\n const restartIndex = this.currentIndex ?? this.selectedIndex;\n await this.playIndex(restartIndex);\n return;\n }\n\n try {\n this.clearError();\n await this.backend.togglePause();\n } catch (error) {\n this.reportError(error);\n }\n }\n\n async seekBy(seconds: number) {\n if (seconds === 0) {\n return;\n }\n\n const { status } = this.backend.getSnapshot();\n if (status === \"stopped\") {\n return;\n }\n\n try {\n this.clearError();\n await this.backend.seekBy(seconds);\n } catch (error) {\n this.reportError(error);\n }\n }\n\n async stop() {\n try {\n this.clearError();\n await this.backend.stop();\n } catch (error) {\n this.reportError(error);\n }\n }\n\n reportError(error: unknown) {\n this.errorMessage =\n error instanceof Error ? error.message : String(error);\n this.emit();\n }\n\n private clearError() {\n if (this.errorMessage === null) {\n return;\n }\n\n this.errorMessage = null;\n }\n\n private emit() {\n const snapshot = this.getSnapshot();\n for (const listener of this.listeners) {\n listener(snapshot);\n }\n }\n\n private async playIndex(index: number) {\n const track = this.playlist[index];\n if (!track) {\n return;\n }\n\n const previousIndex = this.currentIndex;\n this.currentIndex = index;\n\n try {\n this.clearError();\n await this.backend.play(track.path);\n } catch (error) {\n this.currentIndex = previousIndex;\n this.reportError(error);\n return;\n }\n\n this.emit();\n }\n\n private getAdjacentIndex(delta: number) {\n if (this.playlist.length === 0) {\n return null;\n }\n\n const baseIndex = this.currentIndex ?? this.selectedIndex;\n const nextIndex = baseIndex + delta;\n\n if (nextIndex < 0) {\n return this.loop ? this.playlist.length - 1 : null;\n }\n\n if (nextIndex >= this.playlist.length) {\n return this.loop ? 0 : null;\n }\n\n return nextIndex;\n }\n\n private async handleBackendEvent(event: PlayerBackendEvent) {\n switch (event.type) {\n case \"state\":\n this.emit();\n return;\n case \"error\":\n this.reportError(event.error);\n return;\n case \"ended\":\n if (event.reason === \"eof\") {\n const nextIndex = this.getAdjacentIndex(1);\n if (nextIndex !== null) {\n await this.playIndex(nextIndex);\n return;\n }\n }\n\n this.emit();\n }\n }\n\n private syncSelectionToSearch() {\n const matchedIndex = findTrackIndexByQuery(this.playlist, this.searchQuery);\n if (matchedIndex !== -1) {\n this.selectedIndex = matchedIndex;\n }\n\n this.emit();\n }\n}\n",
|
|
19
|
+
"import {\n type Component,\n decodeKittyPrintable,\n Key,\n matchesKey,\n truncateToWidth,\n} from \"@mariozechner/pi-tui\";\n\nimport type { PlaylistPlayerSession } from \"../player/mod.js\";\nimport type { PlaylistPlayerSnapshot } from \"../player/types.js\";\n\nconst RESET = \"\\x1b[0m\";\nconst DIM = \"\\x1b[2m\";\nconst RED = \"\\x1b[31m\";\nconst CYAN = \"\\x1b[36m\";\nconst INVERSE = \"\\x1b[7m\";\n\nconst MIN_LIST_ROWS = 4;\nconst RESERVED_ROWS = 6;\nconst PAGE_SIZE = 10;\nconst PENDING_G_TIMEOUT_MS = 400;\nconst SEEK_SECONDS = 5;\n\nfunction style(text: string, code: string) {\n return `${code}${text}${RESET}`;\n}\n\nfunction padIndex(index: number, total: number) {\n const width = String(Math.max(total, 1)).length;\n return String(index + 1).padStart(width, \" \");\n}\n\nfunction formatSeconds(seconds: number | null) {\n if (seconds === null || Number.isNaN(seconds)) {\n return \"--:--\";\n }\n\n const rounded = Math.max(0, Math.floor(seconds));\n const minutes = Math.floor(rounded / 60);\n const remainingSeconds = rounded % 60;\n\n return `${String(minutes).padStart(2, \"0\")}:${String(remainingSeconds).padStart(2, \"0\")}`;\n}\n\nfunction decodePrintableText(data: string) {\n const kittyPrintable = decodeKittyPrintable(data);\n if (kittyPrintable !== undefined) {\n return kittyPrintable;\n }\n\n const hasControlChars = [...data].some((character) => {\n const code = character.charCodeAt(0);\n return code < 32 || code === 0x7f || (code >= 0x80 && code <= 0x9f);\n });\n\n return hasControlChars ? undefined : data;\n}\n\nexport function getVisibleTrackRange(\n selectedIndex: number,\n totalTracks: number,\n maxVisible: number,\n) {\n if (totalTracks <= 0 || maxVisible <= 0) {\n return { end: 0, start: 0 };\n }\n\n const clampedSelectedIndex = Math.max(\n 0,\n Math.min(selectedIndex, totalTracks - 1),\n );\n const start = Math.max(\n 0,\n Math.min(\n clampedSelectedIndex - Math.floor(maxVisible / 2),\n totalTracks - maxVisible,\n ),\n );\n\n return {\n end: Math.min(totalTracks, start + maxVisible),\n start,\n };\n}\n\nexport class PlaylistPlayerScreen implements Component {\n private pendingGoToTop = false;\n\n private pendingGoToTopTimer: ReturnType<typeof setTimeout> | null = null;\n\n private searchMode = false;\n\n private snapshot: PlaylistPlayerSnapshot;\n\n onQuit?: () => void;\n\n constructor(\n private readonly session: PlaylistPlayerSession,\n private readonly getViewportHeight: () => number,\n ) {\n this.snapshot = session.getSnapshot();\n }\n\n setSnapshot(snapshot: PlaylistPlayerSnapshot) {\n this.snapshot = snapshot;\n }\n\n invalidate() {\n // This screen renders from live snapshot state only.\n }\n\n handleInput(data: string) {\n if (this.searchMode) {\n this.handleSearchInput(data);\n return;\n }\n\n if (matchesKey(data, Key.slash)) {\n this.searchMode = true;\n return;\n }\n\n if (matchesKey(data, \"g\")) {\n if (this.pendingGoToTop) {\n this.clearPendingGoToTop();\n this.session.selectHome();\n } else {\n this.armPendingGoToTop();\n }\n return;\n }\n\n this.clearPendingGoToTop();\n\n if (matchesKey(data, Key.ctrl(\"c\")) || matchesKey(data, \"q\")) {\n this.onQuit?.();\n return;\n }\n\n if (matchesKey(data, Key.up) || matchesKey(data, \"k\")) {\n this.session.moveSelection(-1);\n return;\n }\n\n if (matchesKey(data, Key.down) || matchesKey(data, \"j\")) {\n this.session.moveSelection(1);\n return;\n }\n\n if (matchesKey(data, Key.left) || matchesKey(data, \"h\")) {\n void this.session.seekBy(-SEEK_SECONDS);\n return;\n }\n\n if (matchesKey(data, Key.right) || matchesKey(data, \"l\")) {\n void this.session.seekBy(SEEK_SECONDS);\n return;\n }\n\n if (\n matchesKey(data, Key.pageUp)\n || matchesKey(data, Key.ctrl(\"u\"))\n || matchesKey(data, Key.ctrl(\"b\"))\n ) {\n this.session.moveSelectionPage(-1, PAGE_SIZE);\n return;\n }\n\n if (\n matchesKey(data, Key.pageDown)\n || matchesKey(data, Key.ctrl(\"d\"))\n || matchesKey(data, Key.ctrl(\"f\"))\n ) {\n this.session.moveSelectionPage(1, PAGE_SIZE);\n return;\n }\n\n if (matchesKey(data, Key.home) || matchesKey(data, \"0\")) {\n this.session.selectHome();\n return;\n }\n\n if (matchesKey(data, Key.end) || matchesKey(data, Key.shift(\"g\"))) {\n this.session.selectEnd();\n return;\n }\n\n if (matchesKey(data, Key.shift(\"h\"))) {\n this.moveSelectionToVisibleAnchor(\"top\");\n return;\n }\n\n if (matchesKey(data, Key.shift(\"m\"))) {\n this.moveSelectionToVisibleAnchor(\"middle\");\n return;\n }\n\n if (matchesKey(data, Key.shift(\"l\"))) {\n this.moveSelectionToVisibleAnchor(\"bottom\");\n return;\n }\n\n if (matchesKey(data, Key.enter)) {\n void this.session.playSelected();\n return;\n }\n\n if (matchesKey(data, Key.space)) {\n void this.session.togglePause();\n return;\n }\n\n if (matchesKey(data, \"n\")) {\n void this.session.playNext();\n return;\n }\n\n if (matchesKey(data, \"p\")) {\n void this.session.playPrevious();\n return;\n }\n\n if (matchesKey(data, \"s\")) {\n void this.session.stop();\n return;\n }\n\n if (matchesKey(data, \"r\")) {\n this.session.toggleLoop();\n return;\n }\n\n if (matchesKey(data, Key.backspace)) {\n this.session.deleteSearchCharacter();\n return;\n }\n\n if (matchesKey(data, Key.escape)) {\n this.session.clearSearch();\n return;\n }\n }\n\n render(width: number) {\n const { playlist } = this.snapshot;\n const viewportHeight = Math.max(this.getViewportHeight(), RESERVED_ROWS);\n const listHeight = this.getListHeight(viewportHeight);\n const { start, end } = getVisibleTrackRange(\n this.snapshot.selectedIndex,\n playlist.length,\n listHeight,\n );\n\n const lines: string[] = [\n truncateToWidth(\n `osu-play | tracks ${playlist.length} | backend ${this.snapshot.backendName} | loop ${\n this.snapshot.loop ? \"on\" : \"off\"\n }`,\n width,\n ),\n truncateToWidth(\n style(\n `now ${this.snapshot.status}: ${\n this.snapshot.currentTrack?.title ?? \"nothing selected\"\n }`,\n CYAN,\n ),\n width,\n ),\n truncateToWidth(\n style(\n `${formatSeconds(this.snapshot.timePositionSeconds)} / ${formatSeconds(\n this.snapshot.durationSeconds,\n )} | selected ${this.snapshot.selectedIndex + 1}/${Math.max(\n playlist.length,\n 1,\n )}${\n this.snapshot.searchQuery\n ? ` | search \"${this.snapshot.searchQuery}\"${\n this.searchMode ? \" [input]\" : \"\"\n }`\n : this.searchMode\n ? \" | search [input]\"\n : \"\"\n }`,\n DIM,\n ),\n width,\n ),\n ];\n\n if (this.snapshot.errorMessage) {\n lines.push(\n truncateToWidth(\n style(`error: ${this.snapshot.errorMessage}`, RED),\n width,\n ),\n );\n } else {\n lines.push(\"\");\n }\n\n if (playlist.length === 0) {\n lines.push(\n truncateToWidth(\"No tracks were found in your osu!lazer library.\", width),\n );\n } else {\n for (let index = start; index < end; index += 1) {\n const track = playlist[index];\n if (!track) {\n continue;\n }\n\n const isCurrent = index === this.snapshot.currentIndex;\n const isSelected = index === this.snapshot.selectedIndex;\n const prefix = `${isSelected ? \">\" : \" \"} ${isCurrent ? \"*\" : \" \"} `;\n const line = `${prefix}${padIndex(index, playlist.length)}. ${track.title}`;\n lines.push(\n truncateToWidth(\n isSelected ? style(line, INVERSE) : line,\n width,\n ),\n );\n }\n }\n\n while (lines.length < viewportHeight - 1) {\n lines.push(\"\");\n }\n\n lines.push(\n truncateToWidth(\n style(\n this.searchMode\n ? \"/ search | type to jump | backspace edit | enter keep | esc leave\"\n : \"h/l seek | j/k wrap | gg/G bounds | C-u/C-d page | H/M/L viewport | n/p track | r loop | / search\",\n DIM,\n ),\n width,\n ),\n );\n\n return lines;\n }\n\n private armPendingGoToTop() {\n this.pendingGoToTop = true;\n this.pendingGoToTopTimer = setTimeout(() => {\n this.pendingGoToTop = false;\n this.pendingGoToTopTimer = null;\n }, PENDING_G_TIMEOUT_MS);\n }\n\n private clearPendingGoToTop() {\n if (this.pendingGoToTopTimer) {\n clearTimeout(this.pendingGoToTopTimer);\n this.pendingGoToTopTimer = null;\n }\n\n this.pendingGoToTop = false;\n }\n\n private handleSearchInput(data: string) {\n if (matchesKey(data, Key.ctrl(\"c\"))) {\n this.onQuit?.();\n return;\n }\n\n if (matchesKey(data, Key.enter)) {\n this.searchMode = false;\n return;\n }\n\n if (matchesKey(data, Key.escape)) {\n this.searchMode = false;\n return;\n }\n\n if (matchesKey(data, Key.backspace)) {\n this.session.deleteSearchCharacter();\n return;\n }\n\n if (matchesKey(data, Key.ctrl(\"u\"))) {\n this.session.clearSearch();\n return;\n }\n\n const printable = decodePrintableText(data);\n if (!printable || printable === \" \") {\n return;\n }\n\n this.session.appendSearchQuery(printable);\n }\n\n private getListHeight(viewportHeight: number) {\n return Math.max(MIN_LIST_ROWS, viewportHeight - RESERVED_ROWS);\n }\n\n private moveSelectionToVisibleAnchor(\n anchor: \"bottom\" | \"middle\" | \"top\",\n ) {\n if (this.snapshot.playlist.length === 0) {\n return;\n }\n\n const { start, end } = getVisibleTrackRange(\n this.snapshot.selectedIndex,\n this.snapshot.playlist.length,\n this.getListHeight(Math.max(this.getViewportHeight(), RESERVED_ROWS)),\n );\n const lastVisibleIndex = Math.max(start, end - 1);\n\n switch (anchor) {\n case \"top\":\n this.session.setSelectionIndex(start);\n return;\n case \"middle\":\n this.session.setSelectionIndex(\n start + Math.floor((lastVisibleIndex - start) / 2),\n );\n return;\n case \"bottom\":\n this.session.setSelectionIndex(lastVisibleIndex);\n }\n }\n}\n",
|
|
20
|
+
"#!/usr/bin/env node\nimport { main } from \"./core/cli/main.js\";\n\nmain()\n .then(() => {\n process.exit(0);\n })\n .catch((error: unknown) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n"
|
|
21
|
+
],
|
|
22
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,SAAS,UAAU,GAAuB;AAAA,EAC/C,QAAQ,QAAQ;AAAA,SACT;AAAA,SACA;AAAA,SACA,WAAW;AAAA,MACd,MAAM,MAAM,QAAQ,IAAI;AAAA,MACxB,IAAI;AAAA,QAAK,OAAO;AAAA,MAEhB,MAAM,OAAO,QAAQ,IAAI;AAAA,MACzB,IAAI;AAAA,QAAM,OAAO,yBAAK,KAAK,MAAM,UAAU,OAAO;AAAA,MAClD;AAAA,IACF;AAAA,SAEK,UAAU;AAAA,MACb,MAAM,OAAO,QAAQ,IAAI;AAAA,MACzB,IAAI;AAAA,QAAM,OAAO,yBAAK,KAAK,MAAM,WAAW,qBAAqB;AAAA,MACjE;AAAA,IACF;AAAA,SAEK;AAAA,MACH,OAAO,QAAQ,IAAI,gBAAgB;AAAA;AAAA,EAGvC;AAAA;AAGK,SAAS,YAAY,GAAuB;AAAA,EACjD,QAAQ,QAAQ;AAAA,SACT;AAAA,SACA;AAAA,SACA,SAAS;AAAA,MACZ,MAAM,MAAM,QAAQ,IAAI;AAAA,MACxB,IAAI;AAAA,QAAK,OAAO;AAAA,MAEhB,MAAM,OAAO,QAAQ,IAAI;AAAA,MACzB,IAAI;AAAA,QAAM,OAAO,yBAAK,KAAK,MAAM,SAAS;AAAA,MAC1C;AAAA,IACF;AAAA,SAEK,UAAU;AAAA,MACb,MAAM,OAAO,QAAQ,IAAI;AAAA,MACzB,IAAI;AAAA,QAAM,OAAO,yBAAK,KAAK,MAAM,WAAW,aAAa;AAAA,MACzD;AAAA,IACF;AAAA,SAEK;AAAA,MACH,OAAO,QAAQ,IAAI,WAAW;AAAA;AAAA,EAGlC;AAAA;AAGK,SAAS,oBAAoB,GAAG;AAAA,EACrC,OAAO,yBAAK,KAAK,WAAW,KAAK,KAAK,KAAK;AAAA;AAGtC,SAAS,oBAAoB,CAAC,UAAkB,YAAY;AAAA,EACjE,OAAO,yBAAK,KAAK,aAAa,KAAK,KAAK,OAAO;AAAA;AAG1C,SAAS,cAAc,CAC5B,MACA,aAAqB,qBAAqB,GAC1C;AAAA,EACA,OAAO,yBAAK,KACV,YACA,SACA,KAAK,MAAM,GAAG,CAAC,GACf,KAAK,MAAM,GAAG,CAAC,GACf,IACF;AAAA;AAiBK,SAAS,cAAc,CAC5B,8BAAyD,CAAC,GAC1D,eAAiC,CAAC,GAClC;AAAA,EACA,MAAM,UACJ,OAAO,gCAAgC,WACnC,eACA;AAAA,EACN,MAAM,aAAa,QAAQ,cAAc,qBAAqB;AAAA,EAC9D,MAAM,YAAY,yBAAK,KAAK,YAAY,cAAc;AAAA,EAEtD,IAAI,CAAC,0BAAW,SAAS,GAAG;AAAA,IAC1B,QAAQ,IAAI,qBAAqB,qBAAqB;AAAA,IACtD,OAAO;AAAA,EACT;AAAA,EAEA,OAAO;AAAA;AAAA,IA1GT,kBACA;AAAA;AAAA,EADA;AAAA,EACA;AAAA;;;ACsDA,SAAS,mBAAmB,CAAC,aAAqD;AAAA,EAChF,IAAI,YAAY,SAAS,YAAY,YAAY,SAAS,QAAQ;AAAA,IAChE,OAAO,GAAG,YAAY,QAAQ,YAAY,cAAc;AAAA,EAC1D;AAAA,EAEA,OAAO,YAAY,QAAQ;AAAA;AAG7B,SAAS,gBAAgB,CAAC,UAA0C;AAAA,EAClE,IAAI,CAAC,UAAU,MAAM;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAS,SAAS,YAAY,SAAS,SAAS,QAAQ;AAAA,IAC1D,OAAO,GAAG,SAAS,QAAQ,SAAS,cAAc;AAAA,EACpD;AAAA,EAEA,OAAO,SAAS;AAAA;AAGX,SAAS,yBAAyB,CACvC,eACA,SACgC;AAAA,EAChC,MAAM,eAAe,IAAI,IAAI,cAAc,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,EAC9E,MAAM,iBAA2B,CAAC;AAAA,EAClC,MAAM,SAA0C,CAAC;AAAA,EAEjD,YAAY,YAAY,iBAAiB,OAAO,QAAQ,wBAAwB,GAAG;AAAA,IACjF,MAAM,cAAc,aAAa,IAAI,UAAU;AAAA,IAC/C,IAAI,CAAC,aAAa;AAAA,MAChB,eAAe,KAAK,UAAU;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,YAAY,cAAc,gBAAgB,OAAO,QAAQ,YAAY,GAAG;AAAA,MACtE,MAAM,WAAW,YAAY,WAAW;AAAA,MACxC,MAAM,cAAc,CAAC,YAAY,QAAQ,UAAU,SAAS,YAAY;AAAA,MACxE,MAAM,oBACJ,CAAC,YAAY,cAAc,UAAU,eAAe,YAAY;AAAA,MAElE,IAAI,CAAC,eAAe,CAAC,mBAAmB;AAAA,QACtC,OAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA,UAAU,oBAAoB,WAAW;AAAA,UACzC,QAAQ,iBAAiB,QAAQ;AAAA,QACnC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,YAAY,eAAe,WAAW,KAAK,OAAO,WAAW;AAAA,IAC7D;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAGK,SAAS,mCAAmC,CACjD,QACA;AAAA,EACA,MAAM,UAAU;AAAA,IACd,qCAAqC,OAAO;AAAA,EAC9C;AAAA,EAEA,IAAI,OAAO,eAAe,SAAS,GAAG;AAAA,IACpC,QAAQ,KAAK,oBAAoB,OAAO,eAAe,KAAK,IAAI,GAAG;AAAA,EACrE;AAAA,EAEA,IAAI,OAAO,OAAO,SAAS,GAAG;AAAA,IAC5B,QAAQ,KACN,0BAA0B,OAAO,OAC9B,IACC,CAAC,UACC,GAAG,MAAM,cAAc,MAAM,yBAAyB,MAAM,iBAAiB,MAAM,QACvF,EACC,KAAK,IAAI,GACd;AAAA,EACF;AAAA,EAEA,QAAQ,KACN,6JACF;AAAA,EAEA,OAAO,QAAQ,KAAK;AAAA,CAAI;AAAA;AAAA,IAhHb,mCAAmC,IAE1C;AAAA;AAAA,6BAAgD;AAAA,IACpD,YAAY;AAAA,MACV,UAAU,EAAE,MAAM,QAAQ,YAAY,UAAU;AAAA,MAChD,OAAO,EAAE,MAAM,QAAQ,YAAY,sBAAsB;AAAA,IAC3D;AAAA,IACA,SAAS;AAAA,MACP,UAAU,EAAE,MAAM,UAAU,YAAY,kBAAkB;AAAA,IAC5D;AAAA,IACA,iBAAiB;AAAA,MACf,WAAW,EAAE,MAAM,SAAS;AAAA,MAC5B,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,QAAQ,EAAE,MAAM,SAAS;AAAA,MACzB,cAAc,EAAE,MAAM,SAAS;AAAA,MAC/B,eAAe,EAAE,MAAM,SAAS;AAAA,IAClC;AAAA,IACA,qBAAqB;AAAA,MACnB,MAAM,EAAE,MAAM,UAAU,YAAY,OAAO;AAAA,MAC3C,UAAU,EAAE,MAAM,SAAS;AAAA,IAC7B;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,EAAE,MAAM,SAAS;AAAA,IACzB;AAAA,EACF;AAAA;;;ICrDA,cAIa;AAAA;AAAA,EAJb;AAAA,EAIa,UAAN,MAAM,gBAAgB,qBAAM,OAAgB;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,WAEO,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,QACV,IAAI,EAAE,MAAM,QAAQ,SAAS,GAAG;AAAA,QAChC,gBAAgB,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QAC9D,UAAU;AAAA,UACR,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,SAAS;AAAA,QACX;AAAA,QACA,YAAY,EAAE,MAAM,UAAU,YAAY,cAAc,SAAS,KAAK;AAAA,QACtE,QAAQ,EAAE,MAAM,OAAO,SAAS,GAAG;AAAA,QACnC,UAAU,EAAE,MAAM,OAAO,SAAS,GAAG;AAAA,QACrC,QAAQ,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,QACrC,KAAK,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,QAClC,MAAM,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACpD,YAAY,EAAE,MAAM,UAAU,SAAS,GAAG;AAAA,QAC1C,SAAS,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACvD,eAAe,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QAC7D,iBAAiB,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,QAChD,kBAAkB,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,QACjD,QAAQ,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QACvC,aAAa,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,QAC1C,eAAe,EAAE,MAAM,SAAS,SAAS,IAAI;AAAA,QAC7C,cAAc,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QAC7C,mBAAmB,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QAClD,sBAAsB,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QACrD,iBAAiB,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QAChD,0BAA0B,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QACzD,YAAY,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,QAC3C,iBAAiB,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,QAC9C,aAAa,EAAE,MAAM,OAAO,SAAS,EAAE;AAAA,QACvC,UAAU,EAAE,MAAM,OAAO,SAAS,EAAE;AAAA,QACpC,cAAc,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,QAC3C,iBAAiB,EAAE,MAAM,UAAU,UAAU,KAAK;AAAA,QAClD,iBAAiB,EAAE,MAAM,OAAO,SAAS,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA;;;IC1EA,eAIa;AAAA;AAAA,EAJb;AAAA,EAIa,kBAAN,MAAM,wBAAwB,sBAAM,OAAwB;AAAA,IACjE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,WAEO,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACrD,cAAc,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QAC5D,QAAQ,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACtD,eAAe,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QAC7D,QAAQ,EAAE,MAAM,UAAU,YAAY,aAAa,SAAS,KAAK;AAAA,QACjE,QAAQ,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACtD,MAAM,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACpD,aAAa,EAAE,MAAM,OAAO,SAAS,EAAE;AAAA,QACvC,WAAW,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACzD,gBAAgB,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AAAA;;;IC/BA,eAKa;AAAA;AAAA,EALb;AAAA,EAKa,aAAN,MAAM,mBAAmB,sBAAM,OAAmB;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,WAEO,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,QACV,IAAI,EAAE,MAAM,QAAQ,SAAS,GAAG;AAAA,QAChC,UAAU,EAAE,MAAM,OAAO,SAAS,GAAG;AAAA,QACrC,WAAW,EAAE,MAAM,OAAO;AAAA,QAC1B,eAAe,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,QAC9C,YAAY,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,QAC3C,UAAU,EAAE,MAAM,QAAQ,YAAY,WAAW,SAAS,CAAC,EAAE;AAAA,QAC7D,OAAO,EAAE,MAAM,QAAQ,YAAY,uBAAuB,SAAS,CAAC,EAAE;AAAA,QACtE,QAAQ,EAAE,MAAM,OAAO,SAAS,GAAG;AAAA,QACnC,eAAe,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,QAC9C,MAAM,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACpD,WAAW,EAAE,MAAM,QAAQ,SAAS,MAAM;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA;;;ICnCA,eAGa;AAAA;AAAA,EAHb;AAAA,EAGa,YAAN,MAAM,kBAAkB,sBAAM,OAAkB;AAAA,IACrD;AAAA,WAEO,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAAA;;;ICbA,eAGa;AAAA;AAAA,EAHb;AAAA,EAGa,YAAN,MAAM,kBAAkB,sBAAM,OAAkB;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,WAEO,WAAW;AAAA,WAEX,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,UAAU;AAAA,MACV,YAAY;AAAA,QACV,UAAU,EAAE,MAAM,OAAO,SAAS,EAAE;AAAA,QACpC,UAAU,EAAE,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAAA,QACxD,aAAa,EAAE,MAAM,UAAU,UAAU,KAAK;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA;;;ICnBA,eAIa;AAAA;AAAA,EAJb;AAAA,EAIa,sBAAN,MAAM,4BAA4B,sBAAM,OAA4B;AAAA,IACzE;AAAA,IACA;AAAA,WAEO,WAAW;AAAA,WAEX,SAAuB;AAAA,MAC5B,MAAM;AAAA,MACN,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,UAAU,EAAE,MAAM,UAAU,UAAU,KAAK;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA;;;;EClBA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;;;;;;;;;;;;;;;;;;;;ACyBO,SAAS,kBAAkB,CAAC,OAAc;AAAA,EAC/C,OAAO,0BACL,MAAM,QACN,sBAAM,cAAc,MAAM,IAAI,CAChC;AAAA;AAUK,SAAS,cAAc,CAAC,OAAc;AAAA,EAC3C,OAAO,MAAM,QAAQ,YAAY;AAAA;AAAA,IA7CnC,eAqCa,aAAa,OAAO,gBAAwB;AAAA,EACvD,OAAO,sBAAM,KAAK;AAAA,IAChB,MAAM;AAAA,IACN,UAAU;AAAA,EACZ,CAAC;AAAA,GAOU,oBAAmB,CAAC,UAAkB,eAA2B;AAAA,EAC5E,MAAM,QAAQ,WAAW;AAAA,EACzB,WAAW,QAAQ,OAAO;AAAA,IACxB,IAAI,KAAK,YAAY;AAAA,MAAU,OAAO,KAAK,KAAK;AAAA,EAClD;AAAA,EACA;AAAA;AAAA;AAAA,EAlDF;AAAA,EAEA;AAAA,EAQA;AAAA,EAKA;AAAA,EAlBA;AAAA;;;ACAiB,IAAjB;AAC8B,IAA9B;AAEqC,IAArC;AACkB,IAAlB;AACwB,IAAxB;;;ACLA;AAgCA,SAAS,WAAW,CAAC,OAAyC;AAAA,EAC5D,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAAA;AAGhE,SAAS,gBAAgB,CAAC,UAAmC;AAAA,EAClE,MAAM,QAAQ,YAAY,CAAC,SAAS,OAAO,SAAS,YAAY,CAAC,EAAE,KAAK,KAAK;AAAA,EAC7E,MAAM,SAAS,YAAY,CAAC,SAAS,QAAQ,SAAS,aAAa,CAAC,EAAE,KAAK,KAAK;AAAA,EAEhF,OAAO,GAAG,SAAS,qBAAqB,UAAU;AAAA;AAG7C,SAAS,gBAAgB,CAAC,UAAkB,YAAgC;AAAA,EACjF,WAAW,QAAQ,WAAW,OAAO;AAAA,IACnC,IAAI,KAAK,aAAa,YAAY,KAAK,MAAM,MAAM;AAAA,MACjD,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA;AAAA;AAGK,SAAS,aAAa,CAC3B,aACA,YACA;AAAA,EACA,MAAM,aAAa,IAAI;AAAA,EACvB,MAAM,WAA4B,CAAC;AAAA,EAEnC,WAAW,cAAc,aAAa;AAAA,IACpC,WAAW,WAAW,WAAW,UAAU;AAAA,MACzC,MAAM,OAAO,iBAAiB,QAAQ,SAAS,aAAa,IAAI,UAAU;AAAA,MAC1E,IAAI,CAAC,QAAQ,WAAW,IAAI,IAAI,GAAG;AAAA,QACjC;AAAA,MACF;AAAA,MAEA,WAAW,IAAI,IAAI;AAAA,MACnB,SAAS,KAAK;AAAA,QACZ;AAAA,QACA,MAAM,eAAe,MAAM,UAAU;AAAA,QACrC,OAAO,iBAAiB,QAAQ,QAAQ;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;;;AC5EgC,IAAzC;AACmC,IAAnC;AACgB,IAAhB;AACe,IAAf;AACiB,IAAjB;AACoC,IAApC;AAuBA,SAAS,YAAY,CAAC,OAAgB;AAAA,EACpC,IAAI,SAAS,OAAO,UAAU,YAAY,UAAU,OAAO;AAAA,IACzD,QAAQ,SAAS;AAAA,IACjB,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA,EAC3C;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,sBAAsB,CAAC,OAAgB;AAAA,EAC9C,MAAM,OAAO,aAAa,KAAK;AAAA,EAC/B,IAAI,MAAM;AAAA,IACR,OACE,SAAS,YACN,SAAS,kBACT,SAAS,WACT,SAAS;AAAA,EAEhB;AAAA,EAEA,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EACrE,OACE,QAAQ,SAAS,QAAQ,KACtB,QAAQ,SAAS,cAAc,KAC/B,QAAQ,SAAS,OAAO,KACxB,QAAQ,SAAS,QAAQ;AAAA;AAIhC,SAAS,gBAAgB,GAAG;AAAA,EAC1B,MAAM,KAAK,gBAAgB,QAAQ,OAAO,KAAK,IAAI;AAAA,EACnD,IAAI,QAAQ,aAAa,SAAS;AAAA,IAChC,OAAO,gBAAgB;AAAA,EACzB;AAAA,EAEA,OAAO,0BAAK,KAAK,uBAAG,OAAO,GAAG,GAAG,SAAS;AAAA;AAG5C,SAAS,aAAa,CAAC,OAAe;AAAA,EACpC,OAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,cAAc;AAAA,IACpC,MAAM,OAAO,UAAU,WAAW,CAAC;AAAA,IACnC,OAAO,OAAO,MAAM,SAAS,OAAS,QAAQ,OAAQ,QAAQ;AAAA,GAC/D;AAAA;AAAA;AAGI,MAAM,iBAA0C;AAAA,EAC5C,OAAO;AAAA,EAER,iBAAuC;AAAA,EAEvC,iBAAuC;AAAA,EAEvC,YAAY;AAAA,EAEH,YAAY,IAAI;AAAA,EAEhB,kBAAkB,IAAI;AAAA,EAE/B,aAAa;AAAA,EAEb,UAA+B;AAAA,EAE/B,YAAY;AAAA,EAEZ,iBAAiB;AAAA,EAEjB,WAAkC;AAAA,IACxC,aAAa;AAAA,IACb,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,qBAAqB;AAAA,EACvB;AAAA,EAEQ,SAA4B;AAAA,EAEnB,aAAa,iBAAiB;AAAA,EAEvC,eAAe;AAAA,EAEvB,WAAW,GAAG;AAAA,IACZ,OAAO,KAAK;AAAA;AAAA,EAGd,SAAS,CAAC,UAAiC;AAAA,IACzC,KAAK,UAAU,IAAI,QAAQ;AAAA,IAC3B,SAAS;AAAA,MACP,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,IACR,CAAC;AAAA,IAED,OAAO,MAAM;AAAA,MACX,KAAK,UAAU,OAAO,QAAQ;AAAA;AAAA;AAAA,OAI5B,MAAK,GAAG;AAAA,IACZ,IAAI,KAAK,UAAU,CAAC,KAAK,OAAO,WAAW;AAAA,MACzC;AAAA,IACF;AAAA,IAEA,IAAI,KAAK,gBAAgB;AAAA,MACvB,OAAO,KAAK;AAAA,IACd;AAAA,IAEA,KAAK,iBAAiB,KAAK,cAAc;AAAA,IAEzC,IAAI;AAAA,MACF,MAAM,KAAK;AAAA,cACX;AAAA,MACA,KAAK,iBAAiB;AAAA;AAAA;AAAA,OAIpB,KAAI,CAAC,UAAkB;AAAA,IAC3B,MAAM,KAAK,MAAM;AAAA,IAEjB,MAAM,mBAAmB,KAAK;AAAA,IAE9B,IAAI;AAAA,MACF,MAAM,KAAK,YAAY,CAAC,YAAY,UAAU,SAAS,CAAC;AAAA,MACxD,MAAM,KAAK,YAAY,CAAC,gBAAgB,SAAS,KAAK,CAAC;AAAA,MACvD,OAAO,OAAO;AAAA,MACd,KAAK,WAAW;AAAA,MAChB,KAAK,KAAK;AAAA,QACR,UAAU,KAAK;AAAA,QACf,MAAM;AAAA,MACR,CAAC;AAAA,MACD,MAAM;AAAA;AAAA,IAGR,KAAK,WAAW;AAAA,SACX,KAAK;AAAA,MACR,aAAa;AAAA,MACb,cAAc;AAAA,MACd,QAAQ,KAAK,aAAa,YAAY;AAAA,MACtC,qBAAqB,KAAK,SAAS,uBAAuB;AAAA,IAC5D;AAAA,IACA,KAAK,KAAK;AAAA,MACR,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,IACR,CAAC;AAAA;AAAA,OAGG,YAAW,GAAG;AAAA,IAClB,MAAM,KAAK,MAAM;AAAA,IACjB,MAAM,KAAK,YAAY,CAAC,SAAS,OAAO,CAAC;AAAA;AAAA,OAGrC,OAAM,CAAC,SAAiB;AAAA,IAC5B,MAAM,KAAK,MAAM;AAAA,IACjB,MAAM,KAAK,YAAY,CAAC,QAAQ,SAAS,UAAU,CAAC;AAAA;AAAA,OAGhD,KAAI,GAAG;AAAA,IACX,IAAI,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW;AAAA,MACzC;AAAA,IACF;AAAA,IAEA,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC;AAAA,IAC/B,KAAK,aAAa;AAAA,IAClB,KAAK,WAAW;AAAA,SACX,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,qBAAqB;AAAA,IACvB;AAAA,IACA,KAAK,KAAK;AAAA,MACR,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,IACR,CAAC;AAAA;AAAA,OAGG,QAAO,GAAG;AAAA,IACd,IAAI,KAAK,gBAAgB;AAAA,MACvB,OAAO,KAAK;AAAA,IACd;AAAA,IAEA,KAAK,iBAAiB,KAAK,gBAAgB;AAAA,IAE3C,IAAI;AAAA,MACF,MAAM,KAAK;AAAA,cACX;AAAA,MACA,KAAK,iBAAiB;AAAA;AAAA;AAAA,EAIlB,IAAI,CAAC,OAA2B;AAAA,IACtC,WAAW,YAAY,KAAK,WAAW;AAAA,MACrC,SAAS,KAAK;AAAA,IAChB;AAAA;AAAA,OAGY,cAAa,GAAG;AAAA,IAC5B,KAAK,kBAAkB;AAAA,IACvB,KAAK,YAAY;AAAA,IACjB,KAAK,eAAe;AAAA,IAEpB,MAAM,gBAAgB,gCACpB,OACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,sBAAsB,KAAK;AAAA,IAC7B,GACA;AAAA,MACE,OAAO,CAAC,UAAU,UAAU,MAAM;AAAA,IACpC,CACF;AAAA,IAEA,KAAK,UAAU;AAAA,IAEf,cAAc,OAAO,YAAY,MAAM;AAAA,IACvC,cAAc,OAAO,GAAG,QAAQ,CAAC,UAAkB;AAAA,MACjD,KAAK,eAAe,GAAG,KAAK,eAAe,QAAQ,MAAM,KAAK;AAAA,KAC/D;AAAA,IAED,cAAc,KAAK,SAAS,CAAC,UAAU;AAAA,MACrC,KAAK,YAAY,KAAK;AAAA,KACvB;AAAA,IAED,cAAc,KAAK,QAAQ,CAAC,MAAM,WAAW;AAAA,MAC3C,IAAI,KAAK,WAAW;AAAA,QAClB;AAAA,MACF;AAAA,MAEA,MAAM,SAAS,KAAK,aAAa,KAAK;AAAA,MACtC,MAAM,SAAS,SAAS;AAAA,EAAK,WAAW;AAAA,MACxC,KAAK,YACH,IAAI,MACF,gCAAgC,SAAS,UAAU,WAAW,QAAQ,UAAU,QAClF,CACF;AAAA,KACD;AAAA,IAED,MAAM,KAAK,cAAc;AAAA,IACzB,MAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,YAAY,CAAC,oBAAoB,GAAG,OAAO,CAAC;AAAA,MACjD,KAAK,YAAY,CAAC,oBAAoB,GAAG,UAAU,CAAC;AAAA,MACpD,KAAK,YAAY,CAAC,oBAAoB,GAAG,UAAU,CAAC;AAAA,MACpD,KAAK,YAAY,CAAC,oBAAoB,GAAG,aAAa,CAAC;AAAA,IACzD,CAAC;AAAA;AAAA,OAGW,cAAa,GAAG;AAAA,IAC5B,MAAM,QAAQ,KAAK,IAAI;AAAA,IACvB,MAAM,YAAY;AAAA,IAElB,OAAO,KAAK,IAAI,IAAI,QAAQ,WAAW;AAAA,MACrC,IAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,aAAa,MAAM;AAAA,QACnD,MAAM,IAAI,MAAM,KAAK,mBAAmB,2CAA2C,CAAC;AAAA,MACtF;AAAA,MAEA,IAAI;AAAA,QACF,MAAM,KAAK,aAAa;AAAA,QACxB;AAAA,QACA,OAAO,OAAO;AAAA,QACd,IAAI,CAAC,uBAAuB,KAAK,GAAG;AAAA,UAClC,MAAM;AAAA,QACR;AAAA;AAAA,MAGF,MAAM,2BAAM,EAAE;AAAA,IAChB;AAAA,IAEA,MAAM,IAAI,MAAM,KAAK,mBAAmB,gDAAgD,CAAC;AAAA;AAAA,OAG7E,aAAY,GAAG;AAAA,IAC3B,MAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAAA,MAC3C,MAAM,SAAS,wBAAI,iBAAiB,KAAK,UAAU;AAAA,MAEnD,MAAM,UAAU,CAAC,UAAiB;AAAA,QAChC,OAAO,QAAQ;AAAA,QACf,OAAO,KAAK;AAAA;AAAA,MAGd,OAAO,KAAK,SAAS,OAAO;AAAA,MAC5B,OAAO,KAAK,WAAW,MAAM;AAAA,QAC3B,OAAO,eAAe,SAAS,OAAO;AAAA,QACtC,OAAO,YAAY,MAAM;AAAA,QACzB,OAAO,GAAG,QAAQ,CAAC,UAAkB;AAAA,UACnC,KAAK,iBAAiB,KAAK;AAAA,SAC5B;AAAA,QACD,OAAO,GAAG,SAAS,CAAC,UAAU;AAAA,UAC5B,IAAI,CAAC,KAAK,WAAW;AAAA,YACnB,KAAK,YAAY,KAAK;AAAA,UACxB;AAAA,SACD;AAAA,QACD,OAAO,GAAG,SAAS,MAAM;AAAA,UACvB,IAAI,CAAC,KAAK,WAAW;AAAA,YACnB,KAAK,YAAY,IAAI,MAAM,qCAAqC,CAAC;AAAA,UACnE;AAAA,SACD;AAAA,QACD,KAAK,SAAS;AAAA,QACd,QAAQ;AAAA,OACT;AAAA,KACF;AAAA;AAAA,OAGW,YAAW,CAAC,SAAoB;AAAA,IAC5C,MAAM,SAAS,KAAK;AAAA,IACpB,IAAI,CAAC,UAAU,OAAO,WAAW;AAAA,MAC/B,MAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAAA,IAEA,MAAM,YAAY,EAAE,KAAK;AAAA,IAEzB,OAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAAA,MAC/C,KAAK,gBAAgB,IAAI,WAAW,EAAE,QAAQ,QAAQ,CAAC;AAAA,MAEvD,OAAO,MACL,GAAG,KAAK,UAAU,EAAE,SAAS,YAAY,UAAU,CAAC;AAAA,GACpD,CAAC,UAAU;AAAA,QACT,IAAI,CAAC,OAAO;AAAA,UACV;AAAA,QACF;AAAA,QAEA,KAAK,gBAAgB,OAAO,SAAS;AAAA,QACrC,OAAO,KAAK;AAAA,OAEhB;AAAA,KACD;AAAA;AAAA,EAGK,gBAAgB,CAAC,OAAe;AAAA,IACtC,KAAK,kBAAkB;AAAA,IAEvB,OAAO,MAAM;AAAA,MACX,MAAM,eAAe,KAAK,eAAe,QAAQ;AAAA,CAAI;AAAA,MACrD,IAAI,iBAAiB,IAAI;AAAA,QACvB;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,KAAK,eAAe,MAAM,GAAG,YAAY,EAAE,KAAK;AAAA,MAC7D,KAAK,iBAAiB,KAAK,eAAe,MAAM,eAAe,CAAC;AAAA,MAEhE,IAAI,CAAC,MAAM;AAAA,QACT;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QACF,MAAM,WAAW,KAAK,MAAM,IAAI;AAAA,QAChC,KAAK,eAAe,QAAQ;AAAA,QAC5B,OAAO,OAAO;AAAA,QACd,KAAK,YACH,IAAI,MACF,oCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAEzD,CACF;AAAA;AAAA,IAEJ;AAAA;AAAA,EAGM,cAAc,CAAC,UAAuB;AAAA,IAC5C,IAAI,OAAO,SAAS,eAAe,UAAU;AAAA,MAC3C,MAAM,UAAU,KAAK,gBAAgB,IAAI,SAAS,UAAU;AAAA,MAC5D,IAAI,SAAS;AAAA,QACX,KAAK,gBAAgB,OAAO,SAAS,UAAU;AAAA,QAC/C,IAAI,SAAS,SAAS,SAAS,UAAU,WAAW;AAAA,UAClD,QAAQ,OAAO,IAAI,MAAM,uBAAuB,SAAS,OAAO,CAAC;AAAA,QACnE,EAAO;AAAA,UACL,QAAQ,QAAQ,SAAS,IAAI;AAAA;AAAA,MAEjC;AAAA,MACA;AAAA,IACF;AAAA,IAEA,IAAI,SAAS,UAAU,mBAAmB;AAAA,MACxC,KAAK,oBAAoB,SAAS,MAAM,SAAS,IAAI;AAAA,MACrD;AAAA,IACF;AAAA,IAEA,IAAI,SAAS,UAAU,YAAY;AAAA,MACjC,KAAK,WAAW;AAAA,WACX,KAAK;AAAA,QACR,QAAQ;AAAA,QACR,qBAAqB,KAAK,SAAS;AAAA,MACrC;AAAA,MACA,KAAK,KAAK;AAAA,QACR,UAAU,KAAK;AAAA,QACf,MAAM;AAAA,MACR,CAAC;AAAA,MACD,KAAK,KAAK;AAAA,QACR,QAAQ,SAAS,UAAU;AAAA,QAC3B,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA;AAAA,EAGM,mBAAmB,CAAC,MAA0B,MAAe;AAAA,IACnE,QAAQ;AAAA,WACD;AAAA,QACH,KAAK,WAAW;AAAA,aACX,KAAK;AAAA,UACR,QAAQ,SAAS,OAAO,WAAW,KAAK,aAAa,YAAY;AAAA,QACnE;AAAA,QACA;AAAA,WACG;AAAA,QACH,KAAK,WAAW;AAAA,aACX,KAAK;AAAA,UACR,qBAAqB,OAAO,SAAS,WAAW,OAAO;AAAA,QACzD;AAAA,QACA;AAAA,WACG;AAAA,QACH,KAAK,WAAW;AAAA,aACX,KAAK;AAAA,UACR,iBAAiB,OAAO,SAAS,WAAW,OAAO;AAAA,QACrD;AAAA,QACA;AAAA,WACG;AAAA,QACH,KAAK,aAAa,SAAS;AAAA,QAC3B,KAAK,WAAW;AAAA,aACX,KAAK;AAAA,UACR,QACE,SAAS,OACL,YACA,KAAK,SAAS,WAAW,WACvB,WACA;AAAA,UACR,qBACE,SAAS,OAAO,KAAK,SAAS,kBAAkB,KAAK,SAAS;AAAA,QAClE;AAAA,QACA;AAAA;AAAA,QAEA;AAAA;AAAA,IAGJ,KAAK,KAAK;AAAA,MACR,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,IACR,CAAC;AAAA;AAAA,EAGK,WAAW,CAAC,OAAgB;AAAA,IAClC,MAAM,kBACJ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,IAE1D,KAAK,WAAW;AAAA,SACX,KAAK;AAAA,MACR,cAAc,gBAAgB;AAAA,MAC9B,QAAQ;AAAA,IACV;AAAA,IAEA,KAAK,KAAK;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AAAA,IAED,YAAY,WAAW,YAAY,KAAK,iBAAiB;AAAA,MACvD,KAAK,gBAAgB,OAAO,SAAS;AAAA,MACrC,QAAQ,OAAO,eAAe;AAAA,IAChC;AAAA;AAAA,OAGY,gBAAe,GAAG;AAAA,IAC9B,KAAK,YAAY;AAAA,IAEjB,IAAI,KAAK,UAAU,CAAC,KAAK,OAAO,WAAW;AAAA,MACzC,IAAI;AAAA,QACF,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC;AAAA,QAC/B,MAAM;AAAA,IAGV;AAAA,IAEA,KAAK,QAAQ,QAAQ;AAAA,IACrB,KAAK,SAAS;AAAA,IAEd,MAAM,gBAAgB,KAAK;AAAA,IAC3B,KAAK,UAAU;AAAA,IACf,IAAI,iBAAiB,cAAc,aAAa,MAAM;AAAA,MACpD,cAAc,KAAK,SAAS;AAAA,MAC5B,MAAM,QAAQ,KAAK;AAAA,QACjB,IAAI,QAAc,CAAC,YAAY;AAAA,UAC7B,cAAc,KAAK,QAAQ,MAAM,QAAQ,CAAC;AAAA,SAC3C;AAAA,QACD,2BAAM,IAAI;AAAA,MACZ,CAAC;AAAA,MAED,IAAI,cAAc,aAAa,MAAM;AAAA,QACnC,cAAc,KAAK,SAAS;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,kBAAkB;AAAA;AAAA,EAGjB,iBAAiB,GAAG;AAAA,IAC1B,IAAI,QAAQ,aAAa,SAAS;AAAA,MAChC;AAAA,IACF;AAAA,IAEA,IAAI,2BAAW,KAAK,UAAU,GAAG;AAAA,MAC/B,uBAAO,KAAK,YAAY,EAAE,OAAO,KAAK,CAAC;AAAA,IACzC;AAAA;AAAA,EAGM,kBAAkB,CAAC,SAAiB;AAAA,IAC1C,MAAM,SAAS,KAAK,aAAa,KAAK;AAAA,IACtC,MAAM,cAAc,UAAU,CAAC,cAAc,MAAM,IAAI;AAAA,EAAK,WAAW;AAAA,IAEvE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACG,OAAO,OAAO,EACd,KAAK;AAAA,CAAI;AAAA;AAEhB;;ACxhBA,SAAS,UAAU,CAAC,OAAe,QAAgB;AAAA,EACjD,IAAI,UAAU,GAAG;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EAEA,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,SAAS,CAAC,CAAC;AAAA;AAGhD,SAAS,SAAS,CAAC,OAAe,QAAgB;AAAA,EAChD,IAAI,UAAU,GAAG;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EAEA,QAAS,QAAQ,SAAU,UAAU;AAAA;AAGvC,SAAS,mBAAmB,CAAC,MAAc;AAAA,EACzC,OAAO,KAAK,KAAK,EAAE,YAAY;AAAA;AAG1B,SAAS,qBAAqB,CACnC,UACA,OACA;AAAA,EACA,MAAM,kBAAkB,oBAAoB,KAAK;AAAA,EACjD,IAAI,CAAC,iBAAiB;AAAA,IACpB,OAAO;AAAA,EACT;AAAA,EAEA,OAAO,SAAS,UAAU,CAAC,UACzB,oBAAoB,MAAM,KAAK,EAAE,SAAS,eAAe,CAC3D;AAAA;AAAA;AAOK,MAAM,sBAAsB;AAAA,EAmBd;AAAA,EAlBF,YAAY,IAAI;AAAA,EAEzB,eAA8B;AAAA,EAE9B,eAA8B;AAAA,EAE9B;AAAA,EAES;AAAA,EAET,cAAc;AAAA,EAEd,gBAAgB;AAAA,EAEP;AAAA,EAEjB,WAAW,CACT,UACiB,SACjB,UAAwC,CAAC,GACzC;AAAA,IAFiB;AAAA,IAGjB,KAAK,WAAW;AAAA,IAChB,KAAK,OAAO,QAAQ,QAAQ;AAAA,IAC5B,KAAK,qBAAqB,QAAQ,UAAU,CAAC,UAAU;AAAA,MAChD,KAAK,mBAAmB,KAAK;AAAA,KACnC;AAAA;AAAA,EAGH,WAAW,GAA2B;AAAA,IACpC,MAAM,kBAAkB,KAAK,QAAQ,YAAY;AAAA,IACjD,MAAM,eACJ,KAAK,iBAAiB,OAAO,KAAK,SAAS,KAAK,iBAAiB,OAAO;AAAA,IAE1E,OAAO;AAAA,MACL,aAAa,gBAAgB;AAAA,MAC7B,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,iBAAiB,gBAAgB;AAAA,MACjC,cAAc,KAAK,gBAAgB,gBAAgB;AAAA,MACnD,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,eAAe,KAAK;AAAA,MACpB,QAAQ,gBAAgB;AAAA,MACxB,qBAAqB,gBAAgB;AAAA,IACvC;AAAA;AAAA,EAGF,SAAS,CAAC,UAAkC;AAAA,IAC1C,KAAK,UAAU,IAAI,QAAQ;AAAA,IAC3B,SAAS,KAAK,YAAY,CAAC;AAAA,IAE3B,OAAO,MAAM;AAAA,MACX,KAAK,UAAU,OAAO,QAAQ;AAAA;AAAA;AAAA,OAI5B,MAAK,GAAG;AAAA,IACZ,MAAM,KAAK,QAAQ,MAAM;AAAA,IACzB,KAAK,KAAK;AAAA;AAAA,OAGN,QAAO,GAAG;AAAA,IACd,KAAK,mBAAmB;AAAA,IACxB,MAAM,KAAK,QAAQ,QAAQ;AAAA;AAAA,EAG7B,aAAa,CAAC,OAAe;AAAA,IAC3B,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB,UACnB,KAAK,gBAAgB,OACrB,KAAK,SAAS,MAChB;AAAA,IACA,KAAK,KAAK;AAAA;AAAA,EAGZ,iBAAiB,CAAC,OAAe,UAAkB;AAAA,IACjD,KAAK,cAAc,QAAQ,KAAK,IAAI,GAAG,QAAQ,CAAC;AAAA;AAAA,EAGlD,UAAU,GAAG;AAAA,IACX,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB;AAAA,IACrB,KAAK,KAAK;AAAA;AAAA,EAGZ,SAAS,GAAG;AAAA,IACV,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB,KAAK,SAAS,SAAS;AAAA,IAC5C,KAAK,KAAK;AAAA;AAAA,EAGZ,iBAAiB,CAAC,OAAe;AAAA,IAC/B,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB,WAAW,OAAO,KAAK,SAAS,MAAM;AAAA,IAC3D,KAAK,KAAK;AAAA;AAAA,EAGZ,UAAU,GAAG;AAAA,IACX,KAAK,OAAO,CAAC,KAAK;AAAA,IAClB,KAAK,KAAK;AAAA;AAAA,EAGZ,iBAAiB,CAAC,MAAc;AAAA,IAC9B,IAAI,CAAC,MAAM;AAAA,MACT;AAAA,IACF;AAAA,IAEA,KAAK,eAAe;AAAA,IACpB,KAAK,sBAAsB;AAAA;AAAA,EAG7B,qBAAqB,GAAG;AAAA,IACtB,IAAI,CAAC,KAAK,aAAa;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,KAAK,cAAc,KAAK,YAAY,MAAM,GAAG,EAAE;AAAA,IAC/C,KAAK,sBAAsB;AAAA;AAAA,EAG7B,WAAW,GAAG;AAAA,IACZ,IAAI,CAAC,KAAK,aAAa;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AAAA,IACnB,KAAK,KAAK;AAAA;AAAA,OAGN,aAAY,GAAG;AAAA,IACnB,MAAM,KAAK,UAAU,KAAK,aAAa;AAAA;AAAA,OAGnC,SAAQ,GAAG;AAAA,IACf,MAAM,YAAY,KAAK,iBAAiB,CAAC;AAAA,IACzC,IAAI,cAAc,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,MAAM,KAAK,UAAU,SAAS;AAAA;AAAA,OAG1B,aAAY,GAAG;AAAA,IACnB,MAAM,gBAAgB,KAAK,iBAAiB,EAAE;AAAA,IAC9C,IAAI,kBAAkB,MAAM;AAAA,MAC1B;AAAA,IACF;AAAA,IAEA,MAAM,KAAK,UAAU,aAAa;AAAA;AAAA,OAG9B,YAAW,GAAG;AAAA,IAClB,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,QAAQ,WAAW,KAAK,QAAQ,YAAY;AAAA,IAC5C,IAAI,WAAW,WAAW;AAAA,MACxB,MAAM,eAAe,KAAK,gBAAgB,KAAK;AAAA,MAC/C,MAAM,KAAK,UAAU,YAAY;AAAA,MACjC;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,MACF,KAAK,WAAW;AAAA,MAChB,MAAM,KAAK,QAAQ,YAAY;AAAA,MAC/B,OAAO,OAAO;AAAA,MACd,KAAK,YAAY,KAAK;AAAA;AAAA;AAAA,OAIpB,OAAM,CAAC,SAAiB;AAAA,IAC5B,IAAI,YAAY,GAAG;AAAA,MACjB;AAAA,IACF;AAAA,IAEA,QAAQ,WAAW,KAAK,QAAQ,YAAY;AAAA,IAC5C,IAAI,WAAW,WAAW;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,MACF,KAAK,WAAW;AAAA,MAChB,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA,MACjC,OAAO,OAAO;AAAA,MACd,KAAK,YAAY,KAAK;AAAA;AAAA;AAAA,OAIpB,KAAI,GAAG;AAAA,IACX,IAAI;AAAA,MACF,KAAK,WAAW;AAAA,MAChB,MAAM,KAAK,QAAQ,KAAK;AAAA,MACxB,OAAO,OAAO;AAAA,MACd,KAAK,YAAY,KAAK;AAAA;AAAA;AAAA,EAI1B,WAAW,CAAC,OAAgB;AAAA,IAC1B,KAAK,eACH,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IACvD,KAAK,KAAK;AAAA;AAAA,EAGJ,UAAU,GAAG;AAAA,IACnB,IAAI,KAAK,iBAAiB,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,KAAK,eAAe;AAAA;AAAA,EAGd,IAAI,GAAG;AAAA,IACb,MAAM,WAAW,KAAK,YAAY;AAAA,IAClC,WAAW,YAAY,KAAK,WAAW;AAAA,MACrC,SAAS,QAAQ;AAAA,IACnB;AAAA;AAAA,OAGY,UAAS,CAAC,OAAe;AAAA,IACrC,MAAM,QAAQ,KAAK,SAAS;AAAA,IAC5B,IAAI,CAAC,OAAO;AAAA,MACV;AAAA,IACF;AAAA,IAEA,MAAM,gBAAgB,KAAK;AAAA,IAC3B,KAAK,eAAe;AAAA,IAEpB,IAAI;AAAA,MACF,KAAK,WAAW;AAAA,MAChB,MAAM,KAAK,QAAQ,KAAK,MAAM,IAAI;AAAA,MAClC,OAAO,OAAO;AAAA,MACd,KAAK,eAAe;AAAA,MACpB,KAAK,YAAY,KAAK;AAAA,MACtB;AAAA;AAAA,IAGF,KAAK,KAAK;AAAA;AAAA,EAGJ,gBAAgB,CAAC,OAAe;AAAA,IACtC,IAAI,KAAK,SAAS,WAAW,GAAG;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,IAEA,MAAM,YAAY,KAAK,gBAAgB,KAAK;AAAA,IAC5C,MAAM,YAAY,YAAY;AAAA,IAE9B,IAAI,YAAY,GAAG;AAAA,MACjB,OAAO,KAAK,OAAO,KAAK,SAAS,SAAS,IAAI;AAAA,IAChD;AAAA,IAEA,IAAI,aAAa,KAAK,SAAS,QAAQ;AAAA,MACrC,OAAO,KAAK,OAAO,IAAI;AAAA,IACzB;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,mBAAkB,CAAC,OAA2B;AAAA,IAC1D,QAAQ,MAAM;AAAA,WACP;AAAA,QACH,KAAK,KAAK;AAAA,QACV;AAAA,WACG;AAAA,QACH,KAAK,YAAY,MAAM,KAAK;AAAA,QAC5B;AAAA,WACG;AAAA,QACH,IAAI,MAAM,WAAW,OAAO;AAAA,UAC1B,MAAM,YAAY,KAAK,iBAAiB,CAAC;AAAA,UACzC,IAAI,cAAc,MAAM;AAAA,YACtB,MAAM,KAAK,UAAU,SAAS;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,KAAK;AAAA;AAAA;AAAA,EAIR,qBAAqB,GAAG;AAAA,IAC9B,MAAM,eAAe,sBAAsB,KAAK,UAAU,KAAK,WAAW;AAAA,IAC1E,IAAI,iBAAiB,IAAI;AAAA,MACvB,KAAK,gBAAgB;AAAA,IACvB;AAAA,IAEA,KAAK,KAAK;AAAA;AAEd;;ACtVO,IANP;AAWA,IAAM,QAAQ;AACd,IAAM,MAAM;AACZ,IAAM,MAAM;AACZ,IAAM,OAAO;AACb,IAAM,UAAU;AAEhB,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAClB,IAAM,uBAAuB;AAC7B,IAAM,eAAe;AAErB,SAAS,KAAK,CAAC,MAAc,MAAc;AAAA,EACzC,OAAO,GAAG,OAAO,OAAO;AAAA;AAG1B,SAAS,QAAQ,CAAC,OAAe,OAAe;AAAA,EAC9C,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE;AAAA,EACzC,OAAO,OAAO,QAAQ,CAAC,EAAE,SAAS,OAAO,GAAG;AAAA;AAG9C,SAAS,aAAa,CAAC,SAAwB;AAAA,EAC7C,IAAI,YAAY,QAAQ,OAAO,MAAM,OAAO,GAAG;AAAA,IAC7C,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC;AAAA,EAC/C,MAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AAAA,EACvC,MAAM,mBAAmB,UAAU;AAAA,EAEnC,OAAO,GAAG,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,KAAK,OAAO,gBAAgB,EAAE,SAAS,GAAG,GAAG;AAAA;AAGxF,SAAS,mBAAmB,CAAC,MAAc;AAAA,EACzC,MAAM,iBAAiB,mCAAqB,IAAI;AAAA,EAChD,IAAI,mBAAmB,WAAW;AAAA,IAChC,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,cAAc;AAAA,IACpD,MAAM,OAAO,UAAU,WAAW,CAAC;AAAA,IACnC,OAAO,OAAO,MAAM,SAAS,OAAS,QAAQ,OAAQ,QAAQ;AAAA,GAC/D;AAAA,EAED,OAAO,kBAAkB,YAAY;AAAA;AAGhC,SAAS,oBAAoB,CAClC,eACA,aACA,YACA;AAAA,EACA,IAAI,eAAe,KAAK,cAAc,GAAG;AAAA,IACvC,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE;AAAA,EAC5B;AAAA,EAEA,MAAM,uBAAuB,KAAK,IAChC,GACA,KAAK,IAAI,eAAe,cAAc,CAAC,CACzC;AAAA,EACA,MAAM,QAAQ,KAAK,IACjB,GACA,KAAK,IACH,uBAAuB,KAAK,MAAM,aAAa,CAAC,GAChD,cAAc,UAChB,CACF;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,KAAK,IAAI,aAAa,QAAQ,UAAU;AAAA,IAC7C;AAAA,EACF;AAAA;AAAA;AAGK,MAAM,qBAA0C;AAAA,EAYlC;AAAA,EACA;AAAA,EAZX,iBAAiB;AAAA,EAEjB,sBAA4D;AAAA,EAE5D,aAAa;AAAA,EAEb;AAAA,EAER;AAAA,EAEA,WAAW,CACQ,SACA,mBACjB;AAAA,IAFiB;AAAA,IACA;AAAA,IAEjB,KAAK,WAAW,QAAQ,YAAY;AAAA;AAAA,EAGtC,WAAW,CAAC,UAAkC;AAAA,IAC5C,KAAK,WAAW;AAAA;AAAA,EAGlB,UAAU,GAAG;AAAA,EAIb,WAAW,CAAC,MAAc;AAAA,IACxB,IAAI,KAAK,YAAY;AAAA,MACnB,KAAK,kBAAkB,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG;AAAA,MAC/B,KAAK,aAAa;AAAA,MAClB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,GAAG,GAAG;AAAA,MACzB,IAAI,KAAK,gBAAgB;AAAA,QACvB,KAAK,oBAAoB;AAAA,QACzB,KAAK,QAAQ,WAAW;AAAA,MAC1B,EAAO;AAAA,QACL,KAAK,kBAAkB;AAAA;AAAA,MAEzB;AAAA,IACF;AAAA,IAEA,KAAK,oBAAoB;AAAA,IAEzB,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MAC5D,KAAK,SAAS;AAAA,MACd;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,EAAE,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MACrD,KAAK,QAAQ,cAAc,EAAE;AAAA,MAC7B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,IAAI,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MACvD,KAAK,QAAQ,cAAc,CAAC;AAAA,MAC5B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,IAAI,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MAClD,KAAK,QAAQ,OAAO,CAAC,YAAY;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MACnD,KAAK,QAAQ,OAAO,YAAY;AAAA,MACrC;AAAA,IACF;AAAA,IAEA,IACE,yBAAW,MAAM,kBAAI,MAAM,KACxB,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,KAC9B,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,GACjC;AAAA,MACA,KAAK,QAAQ,kBAAkB,IAAI,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,IAEA,IACE,yBAAW,MAAM,kBAAI,QAAQ,KAC1B,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,KAC9B,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,GACjC;AAAA,MACA,KAAK,QAAQ,kBAAkB,GAAG,SAAS;AAAA,MAC3C;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,IAAI,KAAK,yBAAW,MAAM,GAAG,GAAG;AAAA,MACvD,KAAK,QAAQ,WAAW;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,GAAG,KAAK,yBAAW,MAAM,kBAAI,MAAM,GAAG,CAAC,GAAG;AAAA,MACjE,KAAK,QAAQ,UAAU;AAAA,MACvB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,MAAM,GAAG,CAAC,GAAG;AAAA,MACpC,KAAK,6BAA6B,KAAK;AAAA,MACvC;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,MAAM,GAAG,CAAC,GAAG;AAAA,MACpC,KAAK,6BAA6B,QAAQ;AAAA,MAC1C;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,MAAM,GAAG,CAAC,GAAG;AAAA,MACpC,KAAK,6BAA6B,QAAQ;AAAA,MAC1C;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG;AAAA,MAC1B,KAAK,QAAQ,aAAa;AAAA,MAC/B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG;AAAA,MAC1B,KAAK,QAAQ,YAAY;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,GAAG,GAAG;AAAA,MACpB,KAAK,QAAQ,SAAS;AAAA,MAC3B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,GAAG,GAAG;AAAA,MACpB,KAAK,QAAQ,aAAa;AAAA,MAC/B;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,GAAG,GAAG;AAAA,MACpB,KAAK,QAAQ,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,GAAG,GAAG;AAAA,MACzB,KAAK,QAAQ,WAAW;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,SAAS,GAAG;AAAA,MACnC,KAAK,QAAQ,sBAAsB;AAAA,MACnC;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,MAAM,GAAG;AAAA,MAChC,KAAK,QAAQ,YAAY;AAAA,MACzB;AAAA,IACF;AAAA;AAAA,EAGF,MAAM,CAAC,OAAe;AAAA,IACpB,QAAQ,aAAa,KAAK;AAAA,IAC1B,MAAM,iBAAiB,KAAK,IAAI,KAAK,kBAAkB,GAAG,aAAa;AAAA,IACvE,MAAM,aAAa,KAAK,cAAc,cAAc;AAAA,IACpD,QAAQ,OAAO,QAAQ,qBACrB,KAAK,SAAS,eACd,SAAS,QACT,UACF;AAAA,IAEA,MAAM,QAAkB;AAAA,MACtB,8BACE,qBAAqB,SAAS,oBAAoB,KAAK,SAAS,sBAC9D,KAAK,SAAS,OAAO,OAAO,SAE9B,KACF;AAAA,MACA,8BACE,MACE,OAAO,KAAK,SAAS,WACnB,KAAK,SAAS,cAAc,SAAS,sBAEvC,IACF,GACA,KACF;AAAA,MACA,8BACE,MACE,GAAG,cAAc,KAAK,SAAS,mBAAmB,OAAO,cACvD,KAAK,SAAS,eAChB,gBAAgB,KAAK,SAAS,gBAAgB,KAAK,KAAK,IACtD,SAAS,QACT,CACF,IACE,KAAK,SAAS,cACV,cAAc,KAAK,SAAS,eAC1B,KAAK,aAAa,aAAa,OAEjC,KAAK,aACH,sBACF,MAEN,GACF,GACA,KACF;AAAA,IACF;AAAA,IAEA,IAAI,KAAK,SAAS,cAAc;AAAA,MAC9B,MAAM,KACJ,8BACE,MAAM,UAAU,KAAK,SAAS,gBAAgB,GAAG,GACjD,KACF,CACF;AAAA,IACF,EAAO;AAAA,MACL,MAAM,KAAK,EAAE;AAAA;AAAA,IAGf,IAAI,SAAS,WAAW,GAAG;AAAA,MACzB,MAAM,KACJ,8BAAgB,mDAAmD,KAAK,CAC1E;AAAA,IACF,EAAO;AAAA,MACL,SAAS,QAAQ,MAAO,QAAQ,KAAK,SAAS,GAAG;AAAA,QAC/C,MAAM,QAAQ,SAAS;AAAA,QACvB,IAAI,CAAC,OAAO;AAAA,UACV;AAAA,QACF;AAAA,QAEA,MAAM,YAAY,UAAU,KAAK,SAAS;AAAA,QAC1C,MAAM,aAAa,UAAU,KAAK,SAAS;AAAA,QAC3C,MAAM,SAAS,GAAG,aAAa,MAAM,OAAO,YAAY,MAAM;AAAA,QAC9D,MAAM,OAAO,GAAG,SAAS,SAAS,OAAO,SAAS,MAAM,MAAM,MAAM;AAAA,QACpE,MAAM,KACJ,8BACE,aAAa,MAAM,MAAM,OAAO,IAAI,MACpC,KACF,CACF;AAAA,MACF;AAAA;AAAA,IAGF,OAAO,MAAM,SAAS,iBAAiB,GAAG;AAAA,MACxC,MAAM,KAAK,EAAE;AAAA,IACf;AAAA,IAEA,MAAM,KACJ,8BACE,MACE,KAAK,aACD,sEACA,qGACJ,GACF,GACA,KACF,CACF;AAAA,IAEA,OAAO;AAAA;AAAA,EAGD,iBAAiB,GAAG;AAAA,IAC1B,KAAK,iBAAiB;AAAA,IACtB,KAAK,sBAAsB,WAAW,MAAM;AAAA,MAC1C,KAAK,iBAAiB;AAAA,MACtB,KAAK,sBAAsB;AAAA,OAC1B,oBAAoB;AAAA;AAAA,EAGjB,mBAAmB,GAAG;AAAA,IAC5B,IAAI,KAAK,qBAAqB;AAAA,MAC5B,aAAa,KAAK,mBAAmB;AAAA,MACrC,KAAK,sBAAsB;AAAA,IAC7B;AAAA,IAEA,KAAK,iBAAiB;AAAA;AAAA,EAGhB,iBAAiB,CAAC,MAAc;AAAA,IACtC,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,GAAG;AAAA,MACnC,KAAK,SAAS;AAAA,MACd;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG;AAAA,MAC/B,KAAK,aAAa;AAAA,MAClB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,MAAM,GAAG;AAAA,MAChC,KAAK,aAAa;AAAA,MAClB;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,SAAS,GAAG;AAAA,MACnC,KAAK,QAAQ,sBAAsB;AAAA,MACnC;AAAA,IACF;AAAA,IAEA,IAAI,yBAAW,MAAM,kBAAI,KAAK,GAAG,CAAC,GAAG;AAAA,MACnC,KAAK,QAAQ,YAAY;AAAA,MACzB;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,oBAAoB,IAAI;AAAA,IAC1C,IAAI,CAAC,aAAa,cAAc,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,IAEA,KAAK,QAAQ,kBAAkB,SAAS;AAAA;AAAA,EAGlC,aAAa,CAAC,gBAAwB;AAAA,IAC5C,OAAO,KAAK,IAAI,eAAe,iBAAiB,aAAa;AAAA;AAAA,EAGvD,4BAA4B,CAClC,QACA;AAAA,IACA,IAAI,KAAK,SAAS,SAAS,WAAW,GAAG;AAAA,MACvC;AAAA,IACF;AAAA,IAEA,QAAQ,OAAO,QAAQ,qBACrB,KAAK,SAAS,eACd,KAAK,SAAS,SAAS,QACvB,KAAK,cAAc,KAAK,IAAI,KAAK,kBAAkB,GAAG,aAAa,CAAC,CACtE;AAAA,IACA,MAAM,mBAAmB,KAAK,IAAI,OAAO,MAAM,CAAC;AAAA,IAEhD,QAAQ;AAAA,WACD;AAAA,QACH,KAAK,QAAQ,kBAAkB,KAAK;AAAA,QACpC;AAAA,WACG;AAAA,QACH,KAAK,QAAQ,kBACX,QAAQ,KAAK,OAAO,mBAAmB,SAAS,CAAC,CACnD;AAAA,QACA;AAAA,WACG;AAAA,QACH,KAAK,QAAQ,kBAAkB,gBAAgB;AAAA;AAAA;AAGvD;;;AJjaA;AAEA,SAAS,oBAAoB,CAAC,OAAgB;AAAA,EAC5C,OAAO;AAAA,IACL;AAAA,IACA,yBAAyB,QAAQ;AAAA,IACjC;AAAA,IACA;AAAA,IACA,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EAC1E,EAAE,KAAK;AAAA,CAAI;AAAA;AAGb,eAAe,qBAAqB,GAAG;AAAA,EACrC,IAAI;AAAA,IACF,SAAS,SAAS,UAAS,eAAe,MAAM,QAAQ,IAAI;AAAA,MACnD;AAAA;AAAA,IAET,CAAC;AAAA,IAED,OAAO;AAAA,MACL;AAAA,SACG;AAAA,IACL;AAAA,IACA,OAAO,OAAO;AAAA,IACd,MAAM,IAAI,MAAM,qBAAqB,KAAK,GAAG,EAAE,OAAO,MAAM,CAAC;AAAA;AAAA;AAI1D,SAAS,OAAO,GAAG;AAAA,EACxB,OAAO,qBAAM,uBAAQ,QAAQ,IAAI,CAAC,EAC/B,WAAW,UAAU,EACrB,MACC;AAAA,oBACF,EACC,OAAO,UAAU;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC,EACA,OAAO,kBAAkB;AAAA,IACxB,MAAM;AAAA,IACN,UAAU;AAAA,EACZ,CAAC,EACA,OAAO,cAAc;AAAA,IACpB,MAAM;AAAA,IACN,SAAS,qBAAqB;AAAA,IAC9B,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC,EACA,OAAO,aAAa;AAAA,IACnB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC,EACA,OAAO,QAAQ;AAAA,IACd,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC,EACA,MAAM,QAAQ,GAAG,EACjB,KAAK,EACL,MAAM;AAAA;AAGX,eAAe,cAAc,CAAC,YAAoB;AAAA,EAChD,MAAM,cAAc,eAAe,EAAE,WAAW,CAAC;AAAA,EACjD,IAAI,CAAC,aAAa;AAAA,IAChB,MAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM,sBAAsB;AAAA,EAEhC,OAAM,MAAM,yBAAyB;AAAA,EAErC,MAAM,QAAQ,MAAM,YAAW,WAAW;AAAA,EAE1C,IAAI;AAAA,IACF,MAAM,eAAe,oBAAmB,KAAK;AAAA,IAC7C,IAAI,CAAC,aAAa,YAAY;AAAA,MAC5B,MAAM,IAAI,MAAM,qCAAoC,YAAY,CAAC;AAAA,IACnE;AAAA,IAEA,OAAO,cAAc,gBAAe,KAAK,GAAG,UAAU;AAAA,YACtD;AAAA,IACA,MAAM,MAAM;AAAA;AAAA;AAIhB,eAAe,YAAY,CACzB,UACA,MACA;AAAA,EACA,MAAM,UAAU,IAAI;AAAA,EACpB,MAAM,UAAU,IAAI,sBAAsB,UAAU,SAAS,EAAE,KAAK,CAAC;AAAA,EACrE,MAAM,WAAW,IAAI;AAAA,EACrB,MAAM,MAAM,IAAI,mBAAI,QAAQ;AAAA,EAC5B,MAAM,SAAS,IAAI,qBAAqB,SAAS,MAAM,SAAS,IAAI;AAAA,EAEpE,IAAI,UAAU;AAAA,EAEd,MAAM,cAAc,IAAI,QAAc,CAAC,YAAY;AAAA,IACjD,OAAO,SAAS,MAAM,QAAQ;AAAA,GAC/B;AAAA,EAED,MAAM,cAAc,QAAQ,UAAU,CAAC,aAAa;AAAA,IAClD,OAAO,YAAY,QAAQ;AAAA,IAC3B,IAAI,SAAS;AAAA,MACX,IAAI,cAAc;AAAA,IACpB;AAAA,GACD;AAAA,EAED,IAAI;AAAA,IACF,MAAM,QAAQ,MAAM;AAAA,IAEpB,IAAI,SAAS,MAAM;AAAA,IACnB,IAAI,SAAS,MAAM;AAAA,IACnB,IAAI,MAAM;AAAA,IACV,UAAU;AAAA,IAEV,MAAM;AAAA,YACN;AAAA,IACA,YAAY;AAAA,IAEZ,IAAI,SAAS;AAAA,MACX,MAAM,SAAS,WAAW,EAAE,MAAM,MAAM,EAAE;AAAA,MAC1C,IAAI,KAAK;AAAA,IACX;AAAA,IAEA,MAAM,QAAQ,QAAQ;AAAA;AAAA;AAI1B,eAAsB,IAAI,GAAG;AAAA,EAC3B,MAAM,OAAO,MAAM,QAAQ;AAAA,EAE3B,IAAI,KAAK,QAAQ;AAAA,IACf,QAAQ,IACN,wGACF;AAAA,EACF;AAAA,EAEA,IAAI,KAAK,WAAW;AAAA,IAClB,QAAQ,IACN,gGACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,MAAM,eAAe,KAAK,UAAU;AAAA,EAErD,IAAI,KAAK,gBAAgB;AAAA,IACvB,MAAM,mBAAmB,SAAS,IAAI,CAAC,UAAU,MAAM,IAAI,EAAE,KAAK;AAAA,CAAI;AAAA,IACtE,8BAAc,KAAK,gBAAgB,gBAAgB;AAAA,IACnD,QAAQ,IACN,mBAAmB,SAAS,oBAAoB,KAAK,iBACvD;AAAA,IACA,QAAQ,IACN,8CAA8C,0BAAK,QAAQ,KAAK,cAAc,2BAChF;AAAA,IACA;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,UAAU,KAAK,IAAI;AAAA;;;AKhLxC,KAAK,EACF,KAAK,MAAM;AAAA,EACV,QAAQ,KAAK,CAAC;AAAA,CACf,EACA,MAAM,CAAC,UAAmB;AAAA,EACzB,QAAQ,MAAM,UAAU,KAAK;AAAA,EAC7B,QAAQ,KAAK,CAAC;AAAA,CACf;",
|
|
23
|
+
"debugId": "092198B3F20C100364756E2164756E21",
|
|
24
|
+
"names": []
|
|
25
|
+
}
|
package/dist/cli.d.cts
ADDED
package/dist/cli.d.ts
ADDED