claudekit-cli 3.35.0-dev.8 → 3.35.0-dev.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@ Command-line tool and web dashboard for managing ClaudeKit projects.
9
9
  ClaudeKit Config UI (`ck`) provides both CLI and web dashboard for managing ClaudeKit projects. Built with Bun, TypeScript, and React, enables fast, secure project setup and comprehensive configuration management.
10
10
 
11
11
  **Key Features:**
12
- - **CLI Commands (14)**: new, init, config, projects, setup, skills, agents, commands, port, doctor, versions, update, uninstall, easter-egg
12
+ - **CLI Commands (14)**: new, init, config, projects, setup, skills, agents, commands, migrate, doctor, versions, update, uninstall, easter-egg
13
13
  - **Web Dashboard**: Interactive React UI via `ck config ui` for configuration and project management
14
14
  - **Projects Registry**: Centralized registry at `~/.claudekit/projects.json` with file locking
15
15
  - **Skill Installation**: Install ClaudeKit skills to other coding agents (Cursor, Codex, etc.)
@@ -92,7 +92,7 @@ ck config --help
92
92
  ck skills --help
93
93
  ck agents --help
94
94
  ck commands --help
95
- ck port --help
95
+ ck migrate --help
96
96
  ```
97
97
 
98
98
  ### Create New Project
package/dist/index.js CHANGED
@@ -11948,7 +11948,7 @@ function parseMergedSections(content, kind) {
11948
11948
  if (kind === "agent") {
11949
11949
  preamble = preamble.replace(/^# Agents\n\n> Ported from Claude Code agents via ClaudeKit CLI \(ck agents\)\n> Target: .*\n+/s, "").trimEnd();
11950
11950
  } else {
11951
- preamble = preamble.replace(/^# Rules\n\n> Ported from Claude Code rules via ClaudeKit CLI \(ck port --rules\)\n> Target: .*\n+/s, "").trimEnd();
11951
+ preamble = preamble.replace(/^# Rules\n\n> Ported from Claude Code rules via ClaudeKit CLI \(ck migrate --rules\)\n> Target: .*\n+/s, "").trimEnd();
11952
11952
  }
11953
11953
  return {
11954
11954
  sections,
@@ -45701,7 +45701,7 @@ function registerHealthRoutes(app) {
45701
45701
  });
45702
45702
  }
45703
45703
 
45704
- // src/commands/port/skill-directory-installer.ts
45704
+ // src/commands/migrate/skill-directory-installer.ts
45705
45705
  import { existsSync as existsSync14 } from "node:fs";
45706
45706
  import { cp, mkdir as mkdir6 } from "node:fs/promises";
45707
45707
  import { join as join17, resolve as resolve6 } from "node:path";
@@ -48840,7 +48840,7 @@ var package_default;
48840
48840
  var init_package = __esm(() => {
48841
48841
  package_default = {
48842
48842
  name: "claudekit-cli",
48843
- version: "3.35.0-dev.8",
48843
+ version: "3.35.0-dev.9",
48844
48844
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
48845
48845
  type: "module",
48846
48846
  repository: {
@@ -61677,21 +61677,21 @@ var init_commands_command_help = __esm(() => {
61677
61677
  };
61678
61678
  });
61679
61679
 
61680
- // src/domains/help/commands/port-command-help.ts
61681
- var portCommandHelp;
61682
- var init_port_command_help = __esm(() => {
61683
- portCommandHelp = {
61684
- name: "port",
61685
- description: "Port agents, commands, skills, config, and rules to other providers",
61686
- usage: "ck port [options]",
61680
+ // src/domains/help/commands/migrate-command-help.ts
61681
+ var migrateCommandHelp;
61682
+ var init_migrate_command_help = __esm(() => {
61683
+ migrateCommandHelp = {
61684
+ name: "migrate",
61685
+ description: "Migrate agents, commands, skills, config, and rules to other providers",
61686
+ usage: "ck migrate [options]",
61687
61687
  examples: [
61688
61688
  {
61689
- command: "ck port --agent codex --agent opencode",
61690
- description: "Port all supported content to selected providers"
61689
+ command: "ck migrate --agent codex --agent opencode",
61690
+ description: "Migrate all supported content to selected providers"
61691
61691
  },
61692
61692
  {
61693
- command: "ck port --config --source ./CLAUDE.md",
61694
- description: "Port only config from a specific source file"
61693
+ command: "ck migrate --config --source ./CLAUDE.md",
61694
+ description: "Migrate only config from a specific source file"
61695
61695
  }
61696
61696
  ],
61697
61697
  optionGroups: [
@@ -61704,7 +61704,7 @@ var init_port_command_help = __esm(() => {
61704
61704
  },
61705
61705
  {
61706
61706
  flags: "--all",
61707
- description: "Port to all supported providers"
61707
+ description: "Migrate to all supported providers"
61708
61708
  },
61709
61709
  {
61710
61710
  flags: "-g, --global",
@@ -61721,19 +61721,19 @@ var init_port_command_help = __esm(() => {
61721
61721
  options: [
61722
61722
  {
61723
61723
  flags: "--config",
61724
- description: "Port CLAUDE.md config only"
61724
+ description: "Migrate CLAUDE.md config only"
61725
61725
  },
61726
61726
  {
61727
61727
  flags: "--rules",
61728
- description: "Port .claude/rules only"
61728
+ description: "Migrate .claude/rules only"
61729
61729
  },
61730
61730
  {
61731
61731
  flags: "--skip-config",
61732
- description: "Skip config porting"
61732
+ description: "Skip config migration"
61733
61733
  },
61734
61734
  {
61735
61735
  flags: "--skip-rules",
61736
- description: "Skip rules porting"
61736
+ description: "Skip rules migration"
61737
61737
  },
61738
61738
  {
61739
61739
  flags: "--source <path>",
@@ -61759,7 +61759,7 @@ var init_commands2 = __esm(() => {
61759
61759
  init_setup_command_help();
61760
61760
  init_agents_command_help();
61761
61761
  init_commands_command_help();
61762
- init_port_command_help();
61762
+ init_migrate_command_help();
61763
61763
  init_common_options();
61764
61764
  });
61765
61765
 
@@ -61784,7 +61784,7 @@ var init_help_commands = __esm(() => {
61784
61784
  skills: skillsCommandHelp,
61785
61785
  agents: agentsCommandHelp,
61786
61786
  commands: commandsCommandHelp,
61787
- port: portCommandHelp
61787
+ migrate: migrateCommandHelp
61788
61788
  };
61789
61789
  });
61790
61790
 
@@ -62094,7 +62094,7 @@ function renderGlobalHelp(commands, options2 = DEFAULT_HELP_OPTIONS) {
62094
62094
  lines.push(` ${padEnd(theme.example("ck config"), 24)}${theme.description("Open the config dashboard")}`);
62095
62095
  lines.push(` ${padEnd(theme.example("ck config --help"), 24)}${theme.description("See config actions and dashboard flags")}`);
62096
62096
  lines.push(` ${padEnd(theme.example("ck skills --help"), 24)}${theme.description("Discover skill installation workflows")}`);
62097
- lines.push(` ${padEnd(theme.example("ck port --help"), 24)}${theme.description("Migrate agents/commands/skills across providers")}`);
62097
+ lines.push(` ${padEnd(theme.example("ck migrate --help"), 24)}${theme.description("Migrate agents/commands/skills across providers")}`);
62098
62098
  lines.push("");
62099
62099
  lines.push(theme.heading("Global Options:"));
62100
62100
  lines.push(` ${padEnd(theme.flag("--verbose"), 20)}${theme.description("Enable verbose logging")}`);
@@ -86403,11 +86403,300 @@ async function initCommand(options2) {
86403
86403
  throw error;
86404
86404
  }
86405
86405
  }
86406
+ // src/commands/migrate/migrate-command.ts
86407
+ init_dist2();
86408
+ init_logger();
86409
+ init_agents_discovery();
86410
+ init_commands_discovery();
86411
+ init_config_discovery();
86412
+ init_portable_installer();
86413
+ init_provider_registry();
86414
+ init_skills_discovery();
86415
+ init_skill_directory_installer();
86416
+ var import_picocolors24 = __toESM(require_picocolors(), 1);
86417
+ async function migrateCommand(options2) {
86418
+ console.log();
86419
+ oe(import_picocolors24.default.bgMagenta(import_picocolors24.default.black(" ck migrate ")));
86420
+ try {
86421
+ const argv = new Set(process.argv.slice(2));
86422
+ const hasConfigArg = argv.has("--config");
86423
+ const hasRulesArg = argv.has("--rules");
86424
+ const hasNoConfigArg = argv.has("--no-config") || argv.has("--skip-config");
86425
+ const hasNoRulesArg = argv.has("--no-rules") || argv.has("--skip-rules");
86426
+ const hasNoToggleArgs = !hasConfigArg && !hasRulesArg && !hasNoConfigArg && !hasNoRulesArg;
86427
+ const fallbackConfigOnly = hasNoToggleArgs && options2.config === true && options2.rules !== true;
86428
+ const fallbackRulesOnly = hasNoToggleArgs && options2.rules === true && options2.config !== true;
86429
+ const hasOnlyFlag = hasConfigArg || hasRulesArg || fallbackConfigOnly || fallbackRulesOnly;
86430
+ const skipConfig = hasNoConfigArg || options2.skipConfig === true || options2.config === false;
86431
+ const skipRules = hasNoRulesArg || options2.skipRules === true || options2.rules === false;
86432
+ const migrateConfigOnly = hasConfigArg || fallbackConfigOnly;
86433
+ const migrateRulesOnly = hasRulesArg || fallbackRulesOnly;
86434
+ const migrateAgents = !hasOnlyFlag;
86435
+ const migrateCommands = !hasOnlyFlag;
86436
+ const migrateSkills = !hasOnlyFlag;
86437
+ const migrateConfig = hasOnlyFlag ? migrateConfigOnly && !skipConfig : !skipConfig;
86438
+ const migrateRules = hasOnlyFlag ? migrateRulesOnly && !skipRules : !skipRules;
86439
+ const spinner = de();
86440
+ spinner.start("Discovering portable items...");
86441
+ const agentSource = migrateAgents ? getAgentSourcePath() : null;
86442
+ const commandSource = migrateCommands ? getCommandSourcePath() : null;
86443
+ const skillSource = migrateSkills ? getSkillSourcePath() : null;
86444
+ const agents2 = agentSource ? await discoverAgents(agentSource) : [];
86445
+ const commands = commandSource ? await discoverCommands(commandSource) : [];
86446
+ const skills = skillSource ? await discoverSkills(skillSource) : [];
86447
+ const configItem = migrateConfig ? await discoverConfig(options2.source) : null;
86448
+ const ruleItems = migrateRules ? await discoverRules() : [];
86449
+ spinner.stop("Discovery complete");
86450
+ const hasItems = agents2.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0;
86451
+ if (!hasItems) {
86452
+ f2.error("Nothing to migrate.");
86453
+ f2.info(import_picocolors24.default.dim("Check ~/.claude/agents/, ~/.claude/commands/, ~/.claude/skills/, and ~/.claude/CLAUDE.md"));
86454
+ $e(import_picocolors24.default.red("Nothing to migrate"));
86455
+ return;
86456
+ }
86457
+ const parts = [];
86458
+ if (agents2.length > 0)
86459
+ parts.push(`${agents2.length} agent(s)`);
86460
+ if (commands.length > 0)
86461
+ parts.push(`${commands.length} command(s)`);
86462
+ if (skills.length > 0)
86463
+ parts.push(`${skills.length} skill(s)`);
86464
+ if (configItem)
86465
+ parts.push("config");
86466
+ if (ruleItems.length > 0)
86467
+ parts.push(`${ruleItems.length} rule(s)`);
86468
+ f2.info(`Found: ${parts.join(", ")}`);
86469
+ const detectedProviders = await detectInstalledProviders();
86470
+ let selectedProviders;
86471
+ if (options2.agent && options2.agent.length > 0) {
86472
+ const validProviders = Object.keys(providers);
86473
+ const invalid = options2.agent.filter((a3) => !validProviders.includes(a3));
86474
+ if (invalid.length > 0) {
86475
+ f2.error(`Unknown provider(s): ${invalid.join(", ")}`);
86476
+ f2.info(import_picocolors24.default.dim(`Valid providers: ${validProviders.join(", ")}`));
86477
+ $e(import_picocolors24.default.red("Invalid provider"));
86478
+ return;
86479
+ }
86480
+ selectedProviders = options2.agent;
86481
+ } else if (options2.all) {
86482
+ const allProviders = new Set([
86483
+ ...getProvidersSupporting("agents"),
86484
+ ...getProvidersSupporting("commands"),
86485
+ ...getProvidersSupporting("skills"),
86486
+ ...getProvidersSupporting("config"),
86487
+ ...getProvidersSupporting("rules")
86488
+ ]);
86489
+ selectedProviders = Array.from(allProviders);
86490
+ f2.info(`Migrating to all ${selectedProviders.length} providers`);
86491
+ } else if (detectedProviders.length === 0) {
86492
+ if (options2.yes) {
86493
+ const allProviders = new Set([
86494
+ ...getProvidersSupporting("agents"),
86495
+ ...getProvidersSupporting("commands"),
86496
+ ...getProvidersSupporting("skills"),
86497
+ ...getProvidersSupporting("config"),
86498
+ ...getProvidersSupporting("rules")
86499
+ ]);
86500
+ selectedProviders = Array.from(allProviders);
86501
+ f2.info("No providers detected, migrating to all");
86502
+ } else {
86503
+ f2.warn("No providers detected on your system.");
86504
+ const allProviders = new Set([
86505
+ ...getProvidersSupporting("agents"),
86506
+ ...getProvidersSupporting("commands"),
86507
+ ...getProvidersSupporting("skills"),
86508
+ ...getProvidersSupporting("config"),
86509
+ ...getProvidersSupporting("rules")
86510
+ ]);
86511
+ const selected = await ae({
86512
+ message: "Select providers to migrate to",
86513
+ options: Array.from(allProviders).map((key) => ({
86514
+ value: key,
86515
+ label: providers[key].displayName
86516
+ })),
86517
+ required: true
86518
+ });
86519
+ if (lD(selected)) {
86520
+ ue("Migrate cancelled");
86521
+ return;
86522
+ }
86523
+ selectedProviders = selected;
86524
+ }
86525
+ } else if (detectedProviders.length === 1 || options2.yes) {
86526
+ selectedProviders = detectedProviders;
86527
+ f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors24.default.cyan(providers[a3].displayName)).join(", ")}`);
86528
+ } else {
86529
+ const selected = await ae({
86530
+ message: "Select providers to migrate to",
86531
+ options: detectedProviders.map((a3) => ({
86532
+ value: a3,
86533
+ label: providers[a3].displayName
86534
+ })),
86535
+ required: true,
86536
+ initialValues: detectedProviders
86537
+ });
86538
+ if (lD(selected)) {
86539
+ ue("Migrate cancelled");
86540
+ return;
86541
+ }
86542
+ selectedProviders = selected;
86543
+ }
86544
+ let installGlobally = options2.global ?? false;
86545
+ if (options2.global === undefined && !options2.yes) {
86546
+ const scope = await ie({
86547
+ message: "Installation scope",
86548
+ options: [
86549
+ {
86550
+ value: false,
86551
+ label: "Project",
86552
+ hint: "Install in current directory"
86553
+ },
86554
+ {
86555
+ value: true,
86556
+ label: "Global",
86557
+ hint: "Install in home directory"
86558
+ }
86559
+ ]
86560
+ });
86561
+ if (lD(scope)) {
86562
+ ue("Migrate cancelled");
86563
+ return;
86564
+ }
86565
+ installGlobally = scope;
86566
+ }
86567
+ console.log();
86568
+ f2.step(import_picocolors24.default.bold("Migrate Summary"));
86569
+ if (agents2.length > 0) {
86570
+ f2.message(` Agents: ${agents2.map((a3) => import_picocolors24.default.cyan(a3.name)).join(", ")}`);
86571
+ }
86572
+ if (commands.length > 0) {
86573
+ const cmdNames = commands.map((c2) => import_picocolors24.default.cyan(`/${c2.displayName || c2.name}`)).join(", ");
86574
+ f2.message(` Commands: ${cmdNames}`);
86575
+ }
86576
+ if (skills.length > 0) {
86577
+ f2.message(` Skills: ${skills.map((s) => import_picocolors24.default.cyan(s.name)).join(", ")}`);
86578
+ }
86579
+ if (configItem) {
86580
+ const lines = configItem.body.split(`
86581
+ `).length;
86582
+ f2.message(` Config: ${import_picocolors24.default.cyan("CLAUDE.md")} (${lines} lines)`);
86583
+ }
86584
+ if (ruleItems.length > 0) {
86585
+ f2.message(` Rules: ${import_picocolors24.default.cyan(`${ruleItems.length} file(s)`)}`);
86586
+ }
86587
+ const providerNames = selectedProviders.map((prov) => import_picocolors24.default.cyan(providers[prov].displayName)).join(", ");
86588
+ f2.message(` Providers: ${providerNames}`);
86589
+ f2.message(` Scope: ${installGlobally ? "Global" : "Project"}`);
86590
+ const cmdProviders = getProvidersSupporting("commands");
86591
+ const unsupportedCmd = selectedProviders.filter((p) => !cmdProviders.includes(p));
86592
+ if (commands.length > 0 && unsupportedCmd.length > 0) {
86593
+ f2.info(import_picocolors24.default.dim(` [i] Commands skipped for: ${unsupportedCmd.map((p) => providers[p].displayName).join(", ")} (unsupported)`));
86594
+ }
86595
+ console.log();
86596
+ if (!options2.yes) {
86597
+ const totalItems = agents2.length + commands.length + skills.length + (configItem ? 1 : 0) + ruleItems.length;
86598
+ const confirmed = await se({
86599
+ message: `Migrate ${totalItems} item(s) to ${selectedProviders.length} provider(s)?`
86600
+ });
86601
+ if (lD(confirmed) || !confirmed) {
86602
+ ue("Migrate cancelled");
86603
+ return;
86604
+ }
86605
+ }
86606
+ const installSpinner = de();
86607
+ installSpinner.start("Migrating...");
86608
+ const allResults = [];
86609
+ const installOpts = { global: installGlobally };
86610
+ if (agents2.length > 0) {
86611
+ const agentProviders = selectedProviders.filter((p) => getProvidersSupporting("agents").includes(p));
86612
+ if (agentProviders.length > 0) {
86613
+ const results = await installPortableItems(agents2, agentProviders, "agent", installOpts);
86614
+ allResults.push(...results);
86615
+ }
86616
+ }
86617
+ if (commands.length > 0) {
86618
+ const cmdProviders2 = selectedProviders.filter((p) => getProvidersSupporting("commands").includes(p));
86619
+ if (cmdProviders2.length > 0) {
86620
+ const results = await installPortableItems(commands, cmdProviders2, "command", installOpts);
86621
+ allResults.push(...results);
86622
+ }
86623
+ }
86624
+ if (skills.length > 0) {
86625
+ const skillProviders = selectedProviders.filter((p) => getProvidersSupporting("skills").includes(p));
86626
+ if (skillProviders.length > 0) {
86627
+ const results = await installSkillDirectories(skills, skillProviders, installOpts);
86628
+ allResults.push(...results);
86629
+ }
86630
+ }
86631
+ if (configItem) {
86632
+ const cfgProviders = selectedProviders.filter((p) => getProvidersSupporting("config").includes(p));
86633
+ if (cfgProviders.length > 0) {
86634
+ const results = await installPortableItems([configItem], cfgProviders, "config", installOpts);
86635
+ allResults.push(...results);
86636
+ }
86637
+ }
86638
+ if (ruleItems.length > 0) {
86639
+ const ruleProviders = selectedProviders.filter((p) => getProvidersSupporting("rules").includes(p));
86640
+ if (ruleProviders.length > 0) {
86641
+ const results = await installPortableItems(ruleItems, ruleProviders, "rules", installOpts);
86642
+ allResults.push(...results);
86643
+ }
86644
+ }
86645
+ installSpinner.stop("Migrate complete");
86646
+ displayResults3(allResults);
86647
+ } catch (error) {
86648
+ logger.error(error instanceof Error ? error.message : "Unknown error");
86649
+ $e(import_picocolors24.default.red("Migrate failed"));
86650
+ process.exit(1);
86651
+ }
86652
+ }
86653
+ function displayResults3(results) {
86654
+ console.log();
86655
+ const successful = results.filter((r2) => r2.success && !r2.skipped);
86656
+ const skipped = results.filter((r2) => r2.skipped);
86657
+ const failed = results.filter((r2) => !r2.success);
86658
+ if (successful.length > 0) {
86659
+ for (const r2 of successful) {
86660
+ f2.success(`${import_picocolors24.default.green("[OK]")} ${r2.providerDisplayName}`);
86661
+ if (r2.warnings) {
86662
+ for (const w3 of r2.warnings) {
86663
+ f2.warn(` ${import_picocolors24.default.yellow("[!]")} ${w3}`);
86664
+ }
86665
+ }
86666
+ }
86667
+ }
86668
+ if (skipped.length > 0) {
86669
+ for (const r2 of skipped) {
86670
+ f2.info(`${import_picocolors24.default.yellow("[i]")} ${r2.providerDisplayName}: ${import_picocolors24.default.dim(r2.skipReason || "Skipped")}`);
86671
+ }
86672
+ }
86673
+ if (failed.length > 0) {
86674
+ for (const r2 of failed) {
86675
+ f2.error(`${import_picocolors24.default.red("[X]")} ${r2.providerDisplayName}: ${import_picocolors24.default.dim(r2.error || "Failed")}`);
86676
+ }
86677
+ }
86678
+ console.log();
86679
+ const parts = [];
86680
+ if (successful.length > 0)
86681
+ parts.push(`${successful.length} installed`);
86682
+ if (skipped.length > 0)
86683
+ parts.push(`${skipped.length} skipped`);
86684
+ if (failed.length > 0)
86685
+ parts.push(`${failed.length} failed`);
86686
+ if (parts.length === 0) {
86687
+ $e(import_picocolors24.default.yellow("No installations performed"));
86688
+ } else if (failed.length > 0 && successful.length === 0) {
86689
+ $e(import_picocolors24.default.red("Migrate failed"));
86690
+ process.exit(1);
86691
+ } else {
86692
+ $e(import_picocolors24.default.green(`Done! ${parts.join(", ")}`));
86693
+ }
86694
+ }
86406
86695
  // src/commands/new/new-command.ts
86407
86696
  init_logger();
86408
86697
  init_safe_prompts();
86409
86698
  init_types3();
86410
- var import_picocolors24 = __toESM(require_picocolors(), 1);
86699
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
86411
86700
 
86412
86701
  // src/commands/new/phases/directory-setup.ts
86413
86702
  init_config_manager();
@@ -86821,301 +87110,12 @@ Please use only one download method.`);
86821
87110
  if (ctx.cancelled)
86822
87111
  return;
86823
87112
  prompts.outro(`✨ Project created successfully at ${ctx.resolvedDir}`);
86824
- log.info(`${import_picocolors24.default.dim("Tip:")} To update later: ${import_picocolors24.default.cyan("ck update")} (CLI) + ${import_picocolors24.default.cyan("ck init")} (kit content)`);
87113
+ log.info(`${import_picocolors25.default.dim("Tip:")} To update later: ${import_picocolors25.default.cyan("ck update")} (CLI) + ${import_picocolors25.default.cyan("ck init")} (kit content)`);
86825
87114
  } catch (error) {
86826
87115
  logger.error(error instanceof Error ? error.message : "Unknown error occurred");
86827
87116
  process.exit(1);
86828
87117
  }
86829
87118
  }
86830
- // src/commands/port/port-command.ts
86831
- init_dist2();
86832
- init_logger();
86833
- init_agents_discovery();
86834
- init_commands_discovery();
86835
- init_config_discovery();
86836
- init_portable_installer();
86837
- init_provider_registry();
86838
- init_skills_discovery();
86839
- init_skill_directory_installer();
86840
- var import_picocolors25 = __toESM(require_picocolors(), 1);
86841
- async function portCommand(options2) {
86842
- console.log();
86843
- oe(import_picocolors25.default.bgMagenta(import_picocolors25.default.black(" ck port ")));
86844
- try {
86845
- const argv = new Set(process.argv.slice(2));
86846
- const hasConfigArg = argv.has("--config");
86847
- const hasRulesArg = argv.has("--rules");
86848
- const hasNoConfigArg = argv.has("--no-config") || argv.has("--skip-config");
86849
- const hasNoRulesArg = argv.has("--no-rules") || argv.has("--skip-rules");
86850
- const hasNoToggleArgs = !hasConfigArg && !hasRulesArg && !hasNoConfigArg && !hasNoRulesArg;
86851
- const fallbackConfigOnly = hasNoToggleArgs && options2.config === true && options2.rules !== true;
86852
- const fallbackRulesOnly = hasNoToggleArgs && options2.rules === true && options2.config !== true;
86853
- const hasOnlyFlag = hasConfigArg || hasRulesArg || fallbackConfigOnly || fallbackRulesOnly;
86854
- const skipConfig = hasNoConfigArg || options2.skipConfig === true || options2.config === false;
86855
- const skipRules = hasNoRulesArg || options2.skipRules === true || options2.rules === false;
86856
- const portConfigOnly = hasConfigArg || fallbackConfigOnly;
86857
- const portRulesOnly = hasRulesArg || fallbackRulesOnly;
86858
- const portAgents = !hasOnlyFlag;
86859
- const portCommands = !hasOnlyFlag;
86860
- const portSkills = !hasOnlyFlag;
86861
- const portConfig = hasOnlyFlag ? portConfigOnly && !skipConfig : !skipConfig;
86862
- const portRules = hasOnlyFlag ? portRulesOnly && !skipRules : !skipRules;
86863
- const spinner = de();
86864
- spinner.start("Discovering portable items...");
86865
- const agentSource = portAgents ? getAgentSourcePath() : null;
86866
- const commandSource = portCommands ? getCommandSourcePath() : null;
86867
- const skillSource = portSkills ? getSkillSourcePath() : null;
86868
- const agents2 = agentSource ? await discoverAgents(agentSource) : [];
86869
- const commands = commandSource ? await discoverCommands(commandSource) : [];
86870
- const skills = skillSource ? await discoverSkills(skillSource) : [];
86871
- const configItem = portConfig ? await discoverConfig(options2.source) : null;
86872
- const ruleItems = portRules ? await discoverRules() : [];
86873
- spinner.stop("Discovery complete");
86874
- const hasItems = agents2.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0;
86875
- if (!hasItems) {
86876
- f2.error("Nothing to port.");
86877
- f2.info(import_picocolors25.default.dim("Check ~/.claude/agents/, ~/.claude/commands/, ~/.claude/skills/, and ~/.claude/CLAUDE.md"));
86878
- $e(import_picocolors25.default.red("Nothing to port"));
86879
- return;
86880
- }
86881
- const parts = [];
86882
- if (agents2.length > 0)
86883
- parts.push(`${agents2.length} agent(s)`);
86884
- if (commands.length > 0)
86885
- parts.push(`${commands.length} command(s)`);
86886
- if (skills.length > 0)
86887
- parts.push(`${skills.length} skill(s)`);
86888
- if (configItem)
86889
- parts.push("config");
86890
- if (ruleItems.length > 0)
86891
- parts.push(`${ruleItems.length} rule(s)`);
86892
- f2.info(`Found: ${parts.join(", ")}`);
86893
- const detectedProviders = await detectInstalledProviders();
86894
- let selectedProviders;
86895
- if (options2.agent && options2.agent.length > 0) {
86896
- const validProviders = Object.keys(providers);
86897
- const invalid = options2.agent.filter((a3) => !validProviders.includes(a3));
86898
- if (invalid.length > 0) {
86899
- f2.error(`Unknown provider(s): ${invalid.join(", ")}`);
86900
- f2.info(import_picocolors25.default.dim(`Valid providers: ${validProviders.join(", ")}`));
86901
- $e(import_picocolors25.default.red("Invalid provider"));
86902
- return;
86903
- }
86904
- selectedProviders = options2.agent;
86905
- } else if (options2.all) {
86906
- const allProviders = new Set([
86907
- ...getProvidersSupporting("agents"),
86908
- ...getProvidersSupporting("commands"),
86909
- ...getProvidersSupporting("skills"),
86910
- ...getProvidersSupporting("config"),
86911
- ...getProvidersSupporting("rules")
86912
- ]);
86913
- selectedProviders = Array.from(allProviders);
86914
- f2.info(`Porting to all ${selectedProviders.length} providers`);
86915
- } else if (detectedProviders.length === 0) {
86916
- if (options2.yes) {
86917
- const allProviders = new Set([
86918
- ...getProvidersSupporting("agents"),
86919
- ...getProvidersSupporting("commands"),
86920
- ...getProvidersSupporting("skills"),
86921
- ...getProvidersSupporting("config"),
86922
- ...getProvidersSupporting("rules")
86923
- ]);
86924
- selectedProviders = Array.from(allProviders);
86925
- f2.info("No providers detected, porting to all");
86926
- } else {
86927
- f2.warn("No providers detected on your system.");
86928
- const allProviders = new Set([
86929
- ...getProvidersSupporting("agents"),
86930
- ...getProvidersSupporting("commands"),
86931
- ...getProvidersSupporting("skills"),
86932
- ...getProvidersSupporting("config"),
86933
- ...getProvidersSupporting("rules")
86934
- ]);
86935
- const selected = await ae({
86936
- message: "Select providers to port to",
86937
- options: Array.from(allProviders).map((key) => ({
86938
- value: key,
86939
- label: providers[key].displayName
86940
- })),
86941
- required: true
86942
- });
86943
- if (lD(selected)) {
86944
- ue("Port cancelled");
86945
- return;
86946
- }
86947
- selectedProviders = selected;
86948
- }
86949
- } else if (detectedProviders.length === 1 || options2.yes) {
86950
- selectedProviders = detectedProviders;
86951
- f2.info(`Porting to: ${detectedProviders.map((a3) => import_picocolors25.default.cyan(providers[a3].displayName)).join(", ")}`);
86952
- } else {
86953
- const selected = await ae({
86954
- message: "Select providers to port to",
86955
- options: detectedProviders.map((a3) => ({
86956
- value: a3,
86957
- label: providers[a3].displayName
86958
- })),
86959
- required: true,
86960
- initialValues: detectedProviders
86961
- });
86962
- if (lD(selected)) {
86963
- ue("Port cancelled");
86964
- return;
86965
- }
86966
- selectedProviders = selected;
86967
- }
86968
- let installGlobally = options2.global ?? false;
86969
- if (options2.global === undefined && !options2.yes) {
86970
- const scope = await ie({
86971
- message: "Installation scope",
86972
- options: [
86973
- {
86974
- value: false,
86975
- label: "Project",
86976
- hint: "Install in current directory"
86977
- },
86978
- {
86979
- value: true,
86980
- label: "Global",
86981
- hint: "Install in home directory"
86982
- }
86983
- ]
86984
- });
86985
- if (lD(scope)) {
86986
- ue("Port cancelled");
86987
- return;
86988
- }
86989
- installGlobally = scope;
86990
- }
86991
- console.log();
86992
- f2.step(import_picocolors25.default.bold("Port Summary"));
86993
- if (agents2.length > 0) {
86994
- f2.message(` Agents: ${agents2.map((a3) => import_picocolors25.default.cyan(a3.name)).join(", ")}`);
86995
- }
86996
- if (commands.length > 0) {
86997
- const cmdNames = commands.map((c2) => import_picocolors25.default.cyan(`/${c2.displayName || c2.name}`)).join(", ");
86998
- f2.message(` Commands: ${cmdNames}`);
86999
- }
87000
- if (skills.length > 0) {
87001
- f2.message(` Skills: ${skills.map((s) => import_picocolors25.default.cyan(s.name)).join(", ")}`);
87002
- }
87003
- if (configItem) {
87004
- const lines = configItem.body.split(`
87005
- `).length;
87006
- f2.message(` Config: ${import_picocolors25.default.cyan("CLAUDE.md")} (${lines} lines)`);
87007
- }
87008
- if (ruleItems.length > 0) {
87009
- f2.message(` Rules: ${import_picocolors25.default.cyan(`${ruleItems.length} file(s)`)}`);
87010
- }
87011
- const providerNames = selectedProviders.map((prov) => import_picocolors25.default.cyan(providers[prov].displayName)).join(", ");
87012
- f2.message(` Providers: ${providerNames}`);
87013
- f2.message(` Scope: ${installGlobally ? "Global" : "Project"}`);
87014
- const cmdProviders = getProvidersSupporting("commands");
87015
- const unsupportedCmd = selectedProviders.filter((p) => !cmdProviders.includes(p));
87016
- if (commands.length > 0 && unsupportedCmd.length > 0) {
87017
- f2.info(import_picocolors25.default.dim(` [i] Commands skipped for: ${unsupportedCmd.map((p) => providers[p].displayName).join(", ")} (unsupported)`));
87018
- }
87019
- console.log();
87020
- if (!options2.yes) {
87021
- const totalItems = agents2.length + commands.length + skills.length + (configItem ? 1 : 0) + ruleItems.length;
87022
- const confirmed = await se({
87023
- message: `Port ${totalItems} item(s) to ${selectedProviders.length} provider(s)?`
87024
- });
87025
- if (lD(confirmed) || !confirmed) {
87026
- ue("Port cancelled");
87027
- return;
87028
- }
87029
- }
87030
- const installSpinner = de();
87031
- installSpinner.start("Porting...");
87032
- const allResults = [];
87033
- const installOpts = { global: installGlobally };
87034
- if (agents2.length > 0) {
87035
- const agentProviders = selectedProviders.filter((p) => getProvidersSupporting("agents").includes(p));
87036
- if (agentProviders.length > 0) {
87037
- const results = await installPortableItems(agents2, agentProviders, "agent", installOpts);
87038
- allResults.push(...results);
87039
- }
87040
- }
87041
- if (commands.length > 0) {
87042
- const cmdProviders2 = selectedProviders.filter((p) => getProvidersSupporting("commands").includes(p));
87043
- if (cmdProviders2.length > 0) {
87044
- const results = await installPortableItems(commands, cmdProviders2, "command", installOpts);
87045
- allResults.push(...results);
87046
- }
87047
- }
87048
- if (skills.length > 0) {
87049
- const skillProviders = selectedProviders.filter((p) => getProvidersSupporting("skills").includes(p));
87050
- if (skillProviders.length > 0) {
87051
- const results = await installSkillDirectories(skills, skillProviders, installOpts);
87052
- allResults.push(...results);
87053
- }
87054
- }
87055
- if (configItem) {
87056
- const cfgProviders = selectedProviders.filter((p) => getProvidersSupporting("config").includes(p));
87057
- if (cfgProviders.length > 0) {
87058
- const results = await installPortableItems([configItem], cfgProviders, "config", installOpts);
87059
- allResults.push(...results);
87060
- }
87061
- }
87062
- if (ruleItems.length > 0) {
87063
- const ruleProviders = selectedProviders.filter((p) => getProvidersSupporting("rules").includes(p));
87064
- if (ruleProviders.length > 0) {
87065
- const results = await installPortableItems(ruleItems, ruleProviders, "rules", installOpts);
87066
- allResults.push(...results);
87067
- }
87068
- }
87069
- installSpinner.stop("Port complete");
87070
- displayResults3(allResults);
87071
- } catch (error) {
87072
- logger.error(error instanceof Error ? error.message : "Unknown error");
87073
- $e(import_picocolors25.default.red("Port failed"));
87074
- process.exit(1);
87075
- }
87076
- }
87077
- function displayResults3(results) {
87078
- console.log();
87079
- const successful = results.filter((r2) => r2.success && !r2.skipped);
87080
- const skipped = results.filter((r2) => r2.skipped);
87081
- const failed = results.filter((r2) => !r2.success);
87082
- if (successful.length > 0) {
87083
- for (const r2 of successful) {
87084
- f2.success(`${import_picocolors25.default.green("[OK]")} ${r2.providerDisplayName}`);
87085
- if (r2.warnings) {
87086
- for (const w3 of r2.warnings) {
87087
- f2.warn(` ${import_picocolors25.default.yellow("[!]")} ${w3}`);
87088
- }
87089
- }
87090
- }
87091
- }
87092
- if (skipped.length > 0) {
87093
- for (const r2 of skipped) {
87094
- f2.info(`${import_picocolors25.default.yellow("[i]")} ${r2.providerDisplayName}: ${import_picocolors25.default.dim(r2.skipReason || "Skipped")}`);
87095
- }
87096
- }
87097
- if (failed.length > 0) {
87098
- for (const r2 of failed) {
87099
- f2.error(`${import_picocolors25.default.red("[X]")} ${r2.providerDisplayName}: ${import_picocolors25.default.dim(r2.error || "Failed")}`);
87100
- }
87101
- }
87102
- console.log();
87103
- const parts = [];
87104
- if (successful.length > 0)
87105
- parts.push(`${successful.length} installed`);
87106
- if (skipped.length > 0)
87107
- parts.push(`${skipped.length} skipped`);
87108
- if (failed.length > 0)
87109
- parts.push(`${failed.length} failed`);
87110
- if (parts.length === 0) {
87111
- $e(import_picocolors25.default.yellow("No installations performed"));
87112
- } else if (failed.length > 0 && successful.length === 0) {
87113
- $e(import_picocolors25.default.red("Port failed"));
87114
- process.exit(1);
87115
- } else {
87116
- $e(import_picocolors25.default.green(`Done! ${parts.join(", ")}`));
87117
- }
87118
- }
87119
87119
  // src/commands/projects/add-handler.ts
87120
87120
  init_claudekit_data2();
87121
87121
  init_logger();
@@ -88617,11 +88617,11 @@ function registerCommands(cli) {
88617
88617
  }
88618
88618
  await commandsCommand(options2);
88619
88619
  });
88620
- cli.command("port", "Port agents, commands, skills, config, and rules to other providers").option("-a, --agent <agents...>", "Target providers (cursor, codex, opencode, etc.)").option("-g, --global", "Install globally instead of project-level").option("--all", "Port to all supported providers").option("-y, --yes", "Skip confirmation prompts").option("--config", "Port CLAUDE.md config only").option("--rules", "Port .claude/rules/ only").option("--skip-config", "Skip config porting").option("--skip-rules", "Skip rules porting").option("--source <path>", "Custom CLAUDE.md source path").action(async (options2) => {
88620
+ cli.command("migrate", "Migrate agents, commands, skills, config, and rules to other providers").option("-a, --agent <agents...>", "Target providers (cursor, codex, opencode, etc.)").option("-g, --global", "Install globally instead of project-level").option("--all", "Migrate to all supported providers").option("-y, --yes", "Skip confirmation prompts").option("--config", "Migrate CLAUDE.md config only").option("--rules", "Migrate .claude/rules/ only").option("--skip-config", "Skip config migration").option("--skip-rules", "Skip rules migration").option("--source <path>", "Custom CLAUDE.md source path").action(async (options2) => {
88621
88621
  if (options2.agent && !Array.isArray(options2.agent)) {
88622
88622
  options2.agent = [options2.agent];
88623
88623
  }
88624
- await portCommand(options2);
88624
+ await migrateCommand(options2);
88625
88625
  });
88626
88626
  }
88627
88627
 
@@ -18,7 +18,7 @@ var a1=Object.defineProperty;var l1=(n,e,t)=>e in n?a1(n,e,{enumerable:!0,config
18
18
  */var Bp=n=>{throw TypeError(n)},b1=(n,e,t)=>e.has(n)||Bp("Cannot "+t),Ga=(n,e,t)=>(b1(n,e,"read from private field"),t?t.call(n):e.get(n)),y1=(n,e,t)=>e.has(n)?Bp("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),pu="popstate";function x1(n={}){function e(r,i){let{pathname:s,search:o,hash:a}=r.location;return wi("",{pathname:s,search:o,hash:a},i.state&&i.state.usr||null,i.state&&i.state.key||"default")}function t(r,i){return typeof i=="string"?i:Yt(i)}return w1(e,t,null,n)}function he(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function Te(n,e){if(!n){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function v1(){return Math.random().toString(36).substring(2,10)}function mu(n,e){return{usr:n.state,key:n.key,idx:e}}function wi(n,e,t=null,r){return{pathname:typeof n=="string"?n:n.pathname,search:"",hash:"",...typeof e=="string"?Rn(e):e,state:t,key:e&&e.key||r||v1()}}function Yt({pathname:n="/",search:e="",hash:t=""}){return e&&e!=="?"&&(n+=e.charAt(0)==="?"?e:"?"+e),t&&t!=="#"&&(n+=t.charAt(0)==="#"?t:"#"+t),n}function Rn(n){let e={};if(n){let t=n.indexOf("#");t>=0&&(e.hash=n.substring(t),n=n.substring(0,t));let r=n.indexOf("?");r>=0&&(e.search=n.substring(r),n=n.substring(0,r)),n&&(e.pathname=n)}return e}function w1(n,e,t,r={}){let{window:i=document.defaultView,v5Compat:s=!1}=r,o=i.history,a="POP",l=null,c=h();c==null&&(c=0,o.replaceState({...o.state,idx:c},""));function h(){return(o.state||{idx:null}).idx}function d(){a="POP";let y=h(),v=y==null?null:y-c;c=y,l&&l({action:a,location:g.location,delta:v})}function f(y,v){a="PUSH";let k=wi(g.location,y,v);c=h()+1;let S=mu(k,c),P=g.createHref(k);try{o.pushState(S,"",P)}catch(O){if(O instanceof DOMException&&O.name==="DataCloneError")throw O;i.location.assign(P)}s&&l&&l({action:a,location:g.location,delta:1})}function p(y,v){a="REPLACE";let k=wi(g.location,y,v);c=h();let S=mu(k,c),P=g.createHref(k);o.replaceState(S,"",P),s&&l&&l({action:a,location:g.location,delta:0})}function m(y){return $p(y)}let g={get action(){return a},get location(){return n(i,o)},listen(y){if(l)throw new Error("A history only accepts one active listener");return i.addEventListener(pu,d),l=y,()=>{i.removeEventListener(pu,d),l=null}},createHref(y){return e(i,y)},createURL:m,encodeLocation(y){let v=m(y);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:f,replace:p,go(y){return o.go(y)}};return g}function $p(n,e=!1){let t="http://localhost";typeof window<"u"&&(t=window.location.origin!=="null"?window.location.origin:window.location.href),he(t,"No window.location.(origin|href) available to create URL");let r=typeof n=="string"?n:Yt(n);return r=r.replace(/ $/,"%20"),!e&&r.startsWith("//")&&(r=t+r),new URL(r,t)}var oi,gu=class{constructor(n){if(y1(this,oi,new Map),n)for(let[e,t]of n)this.set(e,t)}get(n){if(Ga(this,oi).has(n))return Ga(this,oi).get(n);if(n.defaultValue!==void 0)return n.defaultValue;throw new Error("No value found for context")}set(n,e){Ga(this,oi).set(n,e)}};oi=new WeakMap;var k1=new Set(["lazy","caseSensitive","path","id","index","children"]);function S1(n){return k1.has(n)}var C1=new Set(["lazy","caseSensitive","path","id","index","middleware","children"]);function O1(n){return C1.has(n)}function j1(n){return n.index===!0}function ki(n,e,t=[],r={},i=!1){return n.map((s,o)=>{let a=[...t,String(o)],l=typeof s.id=="string"?s.id:a.join("-");if(he(s.index!==!0||!s.children,"Cannot specify children on an index route"),he(i||!r[l],`Found a route id collision on id "${l}". Route id's must be globally unique within Data Router usages`),j1(s)){let c={...s,id:l};return r[l]=bu(c,e(c)),c}else{let c={...s,id:l,children:void 0};return r[l]=bu(c,e(c)),s.children&&(c.children=ki(s.children,e,a,r,i)),c}})}function bu(n,e){return Object.assign(n,{...e,...typeof e.lazy=="object"&&e.lazy!=null?{lazy:{...n.lazy,...e.lazy}}:{}})}function xn(n,e,t="/"){return ai(n,e,t,!1)}function ai(n,e,t,r){let i=typeof e=="string"?Rn(e):e,s=Ct(i.pathname||"/",t);if(s==null)return null;let o=Fp(n);M1(o);let a=null;for(let l=0;a==null&&l<o.length;++l){let c=F1(s);a=B1(o[l],c,r)}return a}function P1(n,e){let{route:t,pathname:r,params:i}=n;return{id:t.id,pathname:r,params:i,data:e[t.id],loaderData:e[t.id],handle:t.handle}}function Fp(n,e=[],t=[],r="",i=!1){let s=(o,a,l=i,c)=>{let h={relativePath:c===void 0?o.path||"":c,caseSensitive:o.caseSensitive===!0,childrenIndex:a,route:o};if(h.relativePath.startsWith("/")){if(!h.relativePath.startsWith(r)&&l)return;he(h.relativePath.startsWith(r),`Absolute route path "${h.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),h.relativePath=h.relativePath.slice(r.length)}let d=Gt([r,h.relativePath]),f=t.concat(h);o.children&&o.children.length>0&&(he(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${d}".`),Fp(o.children,e,f,d,l)),!(o.path==null&&!o.index)&&e.push({path:d,score:L1(d,o.index),routesMeta:f})};return n.forEach((o,a)=>{if(o.path===""||!o.path?.includes("?"))s(o,a);else for(let l of Vp(o.path))s(o,a,!0,l)}),e}function Vp(n){let e=n.split("/");if(e.length===0)return[];let[t,...r]=e,i=t.endsWith("?"),s=t.replace(/\?$/,"");if(r.length===0)return i?[s,""]:[s];let o=Vp(r.join("/")),a=[];return a.push(...o.map(l=>l===""?s:[s,l].join("/"))),i&&a.push(...o),a.map(l=>n.startsWith("/")&&l===""?"/":l)}function M1(n){n.sort((e,t)=>e.score!==t.score?t.score-e.score:I1(e.routesMeta.map(r=>r.childrenIndex),t.routesMeta.map(r=>r.childrenIndex)))}var A1=/^:[\w-]+$/,D1=3,T1=2,N1=1,E1=10,R1=-2,yu=n=>n==="*";function L1(n,e){let t=n.split("/"),r=t.length;return t.some(yu)&&(r+=R1),e&&(r+=T1),t.filter(i=>!yu(i)).reduce((i,s)=>i+(A1.test(s)?D1:s===""?N1:E1),r)}function I1(n,e){return n.length===e.length&&n.slice(0,-1).every((r,i)=>r===e[i])?n[n.length-1]-e[e.length-1]:0}function B1(n,e,t=!1){let{routesMeta:r}=n,i={},s="/",o=[];for(let a=0;a<r.length;++a){let l=r[a],c=a===r.length-1,h=s==="/"?e:e.slice(s.length)||"/",d=_o({path:l.relativePath,caseSensitive:l.caseSensitive,end:c},h),f=l.route;if(!d&&c&&t&&!r[r.length-1].route.index&&(d=_o({path:l.relativePath,caseSensitive:l.caseSensitive,end:!1},h)),!d)return null;Object.assign(i,d.params),o.push({params:i,pathname:Gt([s,d.pathname]),pathnameBase:H1(Gt([s,d.pathnameBase])),route:f}),d.pathnameBase!=="/"&&(s=Gt([s,d.pathnameBase]))}return o}function _o(n,e){typeof n=="string"&&(n={path:n,caseSensitive:!1,end:!0});let[t,r]=$1(n.path,n.caseSensitive,n.end),i=e.match(t);if(!i)return null;let s=i[0],o=s.replace(/(.)\/+$/,"$1"),a=i.slice(1);return{params:r.reduce((c,{paramName:h,isOptional:d},f)=>{if(h==="*"){let m=a[f]||"";o=s.slice(0,s.length-m.length).replace(/(.)\/+$/,"$1")}const p=a[f];return d&&!p?c[h]=void 0:c[h]=(p||"").replace(/%2F/g,"/"),c},{}),pathname:s,pathnameBase:o,pattern:n}}function $1(n,e=!1,t=!0){Te(n==="*"||!n.endsWith("*")||n.endsWith("/*"),`Route path "${n}" will be treated as if it were "${n.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${n.replace(/\*$/,"/*")}".`);let r=[],i="^"+n.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,a,l)=>(r.push({paramName:a,isOptional:l!=null}),l?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return n.endsWith("*")?(r.push({paramName:"*"}),i+=n==="*"||n==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):t?i+="\\/*$":n!==""&&n!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,e?void 0:"i"),r]}function F1(n){try{return n.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return Te(!1,`The URL path "${n}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${e}).`),n}}function Ct(n,e){if(e==="/")return n;if(!n.toLowerCase().startsWith(e.toLowerCase()))return null;let t=e.endsWith("/")?e.length-1:e.length,r=n.charAt(t);return r&&r!=="/"?null:n.slice(t)||"/"}function V1({basename:n,pathname:e}){return e==="/"?n:Gt([n,e])}var zp=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,xa=n=>zp.test(n);function z1(n,e="/"){let{pathname:t,search:r="",hash:i=""}=typeof n=="string"?Rn(n):n,s;if(t)if(xa(t))s=t;else{if(t.includes("//")){let o=t;t=t.replace(/\/\/+/g,"/"),Te(!1,`Pathnames cannot have embedded double slashes - normalizing ${o} -> ${t}`)}t.startsWith("/")?s=xu(t.substring(1),"/"):s=xu(t,e)}else s=e;return{pathname:s,search:W1(r),hash:_1(i)}}function xu(n,e){let t=e.replace(/\/+$/,"").split("/");return n.split("/").forEach(i=>{i===".."?t.length>1&&t.pop():i!=="."&&t.push(i)}),t.length>1?t.join("/"):"/"}function qa(n,e,t,r){return`Cannot include a '${n}' character in a manually specified \`to.${e}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${t}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function Hp(n){return n.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function va(n){let e=Hp(n);return e.map((t,r)=>r===e.length-1?t.pathname:t.pathnameBase)}function wa(n,e,t,r=!1){let i;typeof n=="string"?i=Rn(n):(i={...n},he(!i.pathname||!i.pathname.includes("?"),qa("?","pathname","search",i)),he(!i.pathname||!i.pathname.includes("#"),qa("#","pathname","hash",i)),he(!i.search||!i.search.includes("#"),qa("#","search","hash",i)));let s=n===""||i.pathname==="",o=s?"/":i.pathname,a;if(o==null)a=t;else{let d=e.length-1;if(!r&&o.startsWith("..")){let f=o.split("/");for(;f[0]==="..";)f.shift(),d-=1;i.pathname=f.join("/")}a=d>=0?e[d]:"/"}let l=z1(i,a),c=o&&o!=="/"&&o.endsWith("/"),h=(s||o===".")&&t.endsWith("/");return!l.pathname.endsWith("/")&&(c||h)&&(l.pathname+="/"),l}var Gt=n=>n.join("/").replace(/\/\/+/g,"/"),H1=n=>n.replace(/\/+$/,"").replace(/^\/*/,"/"),W1=n=>!n||n==="?"?"":n.startsWith("?")?n:"?"+n,_1=n=>!n||n==="#"?"":n.startsWith("#")?n:"#"+n,Ps=class{constructor(n,e,t,r=!1){this.status=n,this.statusText=e||"",this.internal=r,t instanceof Error?(this.data=t.toString(),this.error=t):this.data=t}};function Si(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.internal=="boolean"&&"data"in n}function Ms(n){return n.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var Wp=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function _p(n,e){let t=n;if(typeof t!="string"||!zp.test(t))return{absoluteURL:void 0,isExternal:!1,to:t};let r=t,i=!1;if(Wp)try{let s=new URL(window.location.href),o=t.startsWith("//")?new URL(s.protocol+t):new URL(t),a=Ct(o.pathname,e);o.origin===s.origin&&a!=null?t=a+o.search+o.hash:i=!0}catch{Te(!1,`<Link to="${t}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:i,to:t}}var Sn=Symbol("Uninstrumented");function U1(n,e){let t={lazy:[],"lazy.loader":[],"lazy.action":[],"lazy.middleware":[],middleware:[],loader:[],action:[]};n.forEach(i=>i({id:e.id,index:e.index,path:e.path,instrument(s){let o=Object.keys(t);for(let a of o)s[a]&&t[a].push(s[a])}}));let r={};if(typeof e.lazy=="function"&&t.lazy.length>0){let i=fr(t.lazy,e.lazy,()=>{});i&&(r.lazy=i)}if(typeof e.lazy=="object"){let i=e.lazy;["middleware","loader","action"].forEach(s=>{let o=i[s],a=t[`lazy.${s}`];if(typeof o=="function"&&a.length>0){let l=fr(a,o,()=>{});l&&(r.lazy=Object.assign(r.lazy||{},{[s]:l}))}})}return["loader","action"].forEach(i=>{let s=e[i];if(typeof s=="function"&&t[i].length>0){let o=s[Sn]??s,a=fr(t[i],o,(...l)=>vu(l[0]));a&&(a[Sn]=o,r[i]=a)}}),e.middleware&&e.middleware.length>0&&t.middleware.length>0&&(r.middleware=e.middleware.map(i=>{let s=i[Sn]??i,o=fr(t.middleware,s,(...a)=>vu(a[0]));return o?(o[Sn]=s,o):i})),r}function K1(n,e){let t={navigate:[],fetch:[]};if(e.forEach(r=>r({instrument(i){let s=Object.keys(i);for(let o of s)i[o]&&t[o].push(i[o])}})),t.navigate.length>0){let r=n.navigate[Sn]??n.navigate,i=fr(t.navigate,r,(...s)=>{let[o,a]=s;return{to:typeof o=="number"||typeof o=="string"?o:o?Yt(o):".",...wu(n,a??{})}});i&&(i[Sn]=r,n.navigate=i)}if(t.fetch.length>0){let r=n.fetch[Sn]??n.fetch,i=fr(t.fetch,r,(...s)=>{let[o,,a,l]=s;return{href:a??".",fetcherKey:o,...wu(n,l??{})}});i&&(i[Sn]=r,n.fetch=i)}return n}function fr(n,e,t){return n.length===0?null:async(...r)=>{let i=await Up(n,t(...r),()=>e(...r),n.length-1);if(i.type==="error")throw i.value;return i.value}}async function Up(n,e,t,r){let i=n[r],s;if(i){let o,a=async()=>(o?console.error("You cannot call instrumented handlers more than once"):o=Up(n,e,t,r-1),s=await o,he(s,"Expected a result"),s.type==="error"&&s.value instanceof Error?{status:"error",error:s.value}:{status:"success",error:void 0});try{await i(a,e)}catch(l){console.error("An instrumentation function threw an error:",l)}o||await a(),await o}else try{s={type:"success",value:await t()}}catch(o){s={type:"error",value:o}}return s||{type:"error",value:new Error("No result assigned in instrumentation chain.")}}function vu(n){let{request:e,context:t,params:r,unstable_pattern:i}=n;return{request:G1(e),params:{...r},unstable_pattern:i,context:q1(t)}}function wu(n,e){return{currentUrl:Yt(n.state.location),..."formMethod"in e?{formMethod:e.formMethod}:{},..."formEncType"in e?{formEncType:e.formEncType}:{},..."formData"in e?{formData:e.formData}:{},..."body"in e?{body:e.body}:{}}}function G1(n){return{method:n.method,url:n.url,headers:{get:(...e)=>n.headers.get(...e)}}}function q1(n){if(Q1(n)){let e={...n};return Object.freeze(e),e}else return{get:e=>n.get(e)}}var Y1=Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function Q1(n){if(n===null||typeof n!="object")return!1;const e=Object.getPrototypeOf(n);return e===Object.prototype||e===null||Object.getOwnPropertyNames(e).sort().join("\0")===Y1}var Kp=["POST","PUT","PATCH","DELETE"],J1=new Set(Kp),X1=["GET",...Kp],Z1=new Set(X1),Gp=new Set([301,302,303,307,308]),ey=new Set([307,308]),Ya={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},ty={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},Qr={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},ny=n=>({hasErrorBoundary:!!n.hasErrorBoundary}),qp="remix-router-transitions",Yp=Symbol("ResetLoaderData");function ry(n){const e=n.window?n.window:typeof window<"u"?window:void 0,t=typeof e<"u"&&typeof e.document<"u"&&typeof e.document.createElement<"u";he(n.routes.length>0,"You must provide a non-empty routes array to createRouter");let r=n.hydrationRouteProperties||[],i=n.mapRouteProperties||ny,s=i;if(n.unstable_instrumentations){let w=n.unstable_instrumentations;s=C=>({...i(C),...U1(w.map(j=>j.route).filter(Boolean),C)})}let o={},a=ki(n.routes,s,void 0,o),l,c=n.basename||"/";c.startsWith("/")||(c=`/${c}`);let h=n.dataStrategy||ly,d={...n.future},f=null,p=new Set,m=null,g=null,y=null,v=n.hydrationData!=null,k=xn(a,n.history.location,c),S=!1,P=null,O;if(k==null&&!n.patchRoutesOnNavigation){let w=yt(404,{pathname:n.history.location.pathname}),{matches:C,route:j}=Xs(a);O=!0,k=C,P={[j.id]:w}}else if(k&&!n.hydrationData&&Gs(k,a,n.history.location.pathname).active&&(k=null),k)if(k.some(w=>w.route.lazy))O=!1;else if(!k.some(w=>Zc(w.route)))O=!0;else{let w=n.hydrationData?n.hydrationData.loaderData:null,C=n.hydrationData?n.hydrationData.errors:null;if(C){let j=k.findIndex(I=>C[I.route.id]!==void 0);O=k.slice(0,j+1).every(I=>!ec(I.route,w,C))}else O=k.every(j=>!ec(j.route,w,C))}else{O=!1,k=[];let w=Gs(null,a,n.history.location.pathname);w.active&&w.matches&&(S=!0,k=w.matches)}let M,x={historyAction:n.history.action,location:n.history.location,matches:k,initialized:O,navigation:Ya,restoreScrollPosition:n.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:"idle",loaderData:n.hydrationData&&n.hydrationData.loaderData||{},actionData:n.hydrationData&&n.hydrationData.actionData||null,errors:n.hydrationData&&n.hydrationData.errors||P,fetchers:new Map,blockers:new Map},D="POP",T=null,R=!1,L,$=!1,U=new Map,_=null,V=!1,J=!1,ue=new Set,z=new Map,q=0,B=-1,ne=new Map,Z=new Set,ae=new Map,ce=new Map,Se=new Set,rt=new Map,At,$n=null;function Va(){if(f=n.history.listen(({action:w,location:C,delta:j})=>{if(At){At(),At=void 0;return}Te(rt.size===0||j!=null,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let I=au({currentLocation:x.location,nextLocation:C,historyAction:w});if(I&&j!=null){let F=new Promise(ee=>{At=ee});n.history.go(j*-1),Ks(I,{state:"blocked",location:C,proceed(){Ks(I,{state:"proceeding",proceed:void 0,reset:void 0,location:C}),F.then(()=>n.history.go(j))},reset(){let ee=new Map(x.blockers);ee.set(I,Qr),Fe({blockers:ee})}}),T?.resolve(),T=null;return}return we(w,C)}),t){jy(e,U);let w=()=>Py(e,U);e.addEventListener("pagehide",w),_=()=>e.removeEventListener("pagehide",w)}return x.initialized||we("POP",x.location,{initialHydration:!0}),M}function za(){f&&f(),_&&_(),p.clear(),L&&L.abort(),x.fetchers.forEach((w,C)=>_a(C)),x.blockers.forEach((w,C)=>ou(C))}function Ha(w){return p.add(w),()=>p.delete(w)}function Fe(w,C={}){w.matches&&(w.matches=w.matches.map(F=>{let ee=o[F.route.id],Q=F.route;return Q.element!==ee.element||Q.errorElement!==ee.errorElement||Q.hydrateFallbackElement!==ee.hydrateFallbackElement?{...F,route:ee}:F})),x={...x,...w};let j=[],I=[];x.fetchers.forEach((F,ee)=>{F.state==="idle"&&(Se.has(ee)?j.push(ee):I.push(ee))}),Se.forEach(F=>{!x.fetchers.has(F)&&!z.has(F)&&j.push(F)}),[...p].forEach(F=>F(x,{deletedFetchers:j,newErrors:w.errors??null,viewTransitionOpts:C.viewTransitionOpts,flushSync:C.flushSync===!0})),j.forEach(F=>_a(F)),I.forEach(F=>x.fetchers.delete(F))}function E(w,C,{flushSync:j}={}){let I=x.actionData!=null&&x.navigation.formMethod!=null&&Ye(x.navigation.formMethod)&&x.navigation.state==="loading"&&w.state?._isRedirect!==!0,F;C.actionData?Object.keys(C.actionData).length>0?F=C.actionData:F=null:I?F=x.actionData:F=null;let ee=C.loaderData?Tu(x.loaderData,C.loaderData,C.matches||[],C.errors):x.loaderData,Q=x.blockers;Q.size>0&&(Q=new Map(Q),Q.forEach((oe,re)=>Q.set(re,Qr)));let X=V?!1:cu(w,C.matches||x.matches),te=R===!0||x.navigation.formMethod!=null&&Ye(x.navigation.formMethod)&&w.state?._isRedirect!==!0;l&&(a=l,l=void 0),V||D==="POP"||(D==="PUSH"?n.history.push(w,w.state):D==="REPLACE"&&n.history.replace(w,w.state));let se;if(D==="POP"){let oe=U.get(x.location.pathname);oe&&oe.has(w.pathname)?se={currentLocation:x.location,nextLocation:w}:U.has(w.pathname)&&(se={currentLocation:w,nextLocation:x.location})}else if($){let oe=U.get(x.location.pathname);oe?oe.add(w.pathname):(oe=new Set([w.pathname]),U.set(x.location.pathname,oe)),se={currentLocation:x.location,nextLocation:w}}Fe({...C,actionData:F,loaderData:ee,historyAction:D,location:w,initialized:!0,navigation:Ya,revalidation:"idle",restoreScrollPosition:X,preventScrollReset:te,blockers:Q},{viewTransitionOpts:se,flushSync:j===!0}),D="POP",R=!1,$=!1,V=!1,J=!1,T?.resolve(),T=null,$n?.resolve(),$n=null}async function Y(w,C){if(T?.resolve(),T=null,typeof w=="number"){T||(T=Lu());let be=T.promise;return n.history.go(w),be}let j=Zl(x.location,x.matches,c,w,C?.fromRouteId,C?.relative),{path:I,submission:F,error:ee}=ku(!1,j,C),Q=x.location,X=wi(x.location,I,C&&C.state);X={...X,...n.history.encodeLocation(X)};let te=C&&C.replace!=null?C.replace:void 0,se="PUSH";te===!0?se="REPLACE":te===!1||F!=null&&Ye(F.formMethod)&&F.formAction===x.location.pathname+x.location.search&&(se="REPLACE");let oe=C&&"preventScrollReset"in C?C.preventScrollReset===!0:void 0,re=(C&&C.flushSync)===!0,ge=au({currentLocation:Q,nextLocation:X,historyAction:se});if(ge){Ks(ge,{state:"blocked",location:X,proceed(){Ks(ge,{state:"proceeding",proceed:void 0,reset:void 0,location:X}),Y(w,C)},reset(){let be=new Map(x.blockers);be.set(ge,Qr),Fe({blockers:be})}});return}await we(se,X,{submission:F,pendingError:ee,preventScrollReset:oe,replace:C&&C.replace,enableViewTransition:C&&C.viewTransition,flushSync:re,callSiteDefaultShouldRevalidate:C&&C.unstable_defaultShouldRevalidate})}function ve(){$n||($n=Lu()),Wa(),Fe({revalidation:"loading"});let w=$n.promise;return x.navigation.state==="submitting"?w:x.navigation.state==="idle"?(we(x.historyAction,x.location,{startUninterruptedRevalidation:!0}),w):(we(D||x.historyAction,x.navigation.location,{overrideNavigation:x.navigation,enableViewTransition:$===!0}),w)}async function we(w,C,j){L&&L.abort(),L=null,D=w,V=(j&&j.startUninterruptedRevalidation)===!0,r1(x.location,x.matches),R=(j&&j.preventScrollReset)===!0,$=(j&&j.enableViewTransition)===!0;let I=l||a,F=j&&j.overrideNavigation,ee=j?.initialHydration&&x.matches&&x.matches.length>0&&!S?x.matches:xn(I,C,c),Q=(j&&j.flushSync)===!0;if(ee&&x.initialized&&!J&&gy(x.location,C)&&!(j&&j.submission&&Ye(j.submission.formMethod))){E(C,{matches:ee},{flushSync:Q});return}let X=Gs(ee,I,C.pathname);if(X.active&&X.matches&&(ee=X.matches),!ee){let{error:ze,notFoundMatches:Ze,route:ke}=Ua(C.pathname);E(C,{matches:Ze,loaderData:{},errors:{[ke.id]:ze}},{flushSync:Q});return}L=new AbortController;let te=hr(n.history,C,L.signal,j&&j.submission),se=n.getContext?await n.getContext():new gu,oe;if(j&&j.pendingError)oe=[vn(ee).route.id,{type:"error",error:j.pendingError}];else if(j&&j.submission&&Ye(j.submission.formMethod)){let ze=await Fn(te,C,j.submission,ee,se,X.active,j&&j.initialHydration===!0,{replace:j.replace,flushSync:Q});if(ze.shortCircuited)return;if(ze.pendingActionResult){let[Ze,ke]=ze.pendingActionResult;if(ft(ke)&&Si(ke.error)&&ke.error.status===404){L=null,E(C,{matches:ze.matches,loaderData:{},errors:{[Ze]:ke.error}});return}}ee=ze.matches||ee,oe=ze.pendingActionResult,F=Qa(C,j.submission),Q=!1,X.active=!1,te=hr(n.history,te.url,te.signal)}let{shortCircuited:re,matches:ge,loaderData:be,errors:We}=await _s(te,C,ee,se,X.active,F,j&&j.submission,j&&j.fetcherSubmission,j&&j.replace,j&&j.initialHydration===!0,Q,oe,j&&j.callSiteDefaultShouldRevalidate);re||(L=null,E(C,{matches:ge||ee,...Nu(oe),loaderData:be,errors:We}))}async function Fn(w,C,j,I,F,ee,Q,X={}){Wa();let te=Cy(C,j);if(Fe({navigation:te},{flushSync:X.flushSync===!0}),ee){let re=await qs(I,C.pathname,w.signal);if(re.type==="aborted")return{shortCircuited:!0};if(re.type==="error"){if(re.partialMatches.length===0){let{matches:be,route:We}=Xs(a);return{matches:be,pendingActionResult:[We.id,{type:"error",error:re.error}]}}let ge=vn(re.partialMatches).route.id;return{matches:re.partialMatches,pendingActionResult:[ge,{type:"error",error:re.error}]}}else if(re.matches)I=re.matches;else{let{notFoundMatches:ge,error:be,route:We}=Ua(C.pathname);return{matches:ge,pendingActionResult:[We.id,{type:"error",error:be}]}}}let se,oe=To(I,C);if(!oe.route.action&&!oe.route.lazy)se={type:"error",error:yt(405,{method:w.method,pathname:C.pathname,routeId:oe.route.id})};else{let re=xr(s,o,w,I,oe,Q?[]:r,F),ge=await Gr(w,re,F,null);if(se=ge[oe.route.id],!se){for(let be of I)if(ge[be.route.id]){se=ge[be.route.id];break}}if(w.signal.aborted)return{shortCircuited:!0}}if(qn(se)){let re;return X&&X.replace!=null?re=X.replace:re=Mu(se.response.headers.get("Location"),new URL(w.url),c)===x.location.pathname+x.location.search,await Vn(w,se,!0,{submission:j,replace:re}),{shortCircuited:!0}}if(ft(se)){let re=vn(I,oe.route.id);return(X&&X.replace)!==!0&&(D="PUSH"),{matches:I,pendingActionResult:[re.route.id,se,oe.route.id]}}return{matches:I,pendingActionResult:[oe.route.id,se]}}async function _s(w,C,j,I,F,ee,Q,X,te,se,oe,re,ge){let be=ee||Qa(C,Q),We=Q||X||Ru(be),ze=!V&&!se;if(F){if(ze){let qe=Kr(re);Fe({navigation:be,...qe!==void 0?{actionData:qe}:{}},{flushSync:oe})}let me=await qs(j,C.pathname,w.signal);if(me.type==="aborted")return{shortCircuited:!0};if(me.type==="error"){if(me.partialMatches.length===0){let{matches:lr,route:Wn}=Xs(a);return{matches:lr,loaderData:{},errors:{[Wn.id]:me.error}}}let qe=vn(me.partialMatches).route.id;return{matches:me.partialMatches,loaderData:{},errors:{[qe]:me.error}}}else if(me.matches)j=me.matches;else{let{error:qe,notFoundMatches:lr,route:Wn}=Ua(C.pathname);return{matches:lr,loaderData:{},errors:{[Wn.id]:qe}}}}let Ze=l||a,{dsMatches:ke,revalidatingFetchers:bt}=Su(w,I,s,o,n.history,x,j,We,C,se?[]:r,se===!0,J,ue,Se,ae,Z,Ze,c,n.patchRoutesOnNavigation!=null,re,ge);if(B=++q,!n.dataStrategy&&!ke.some(me=>me.shouldLoad)&&!ke.some(me=>me.route.middleware&&me.route.middleware.length>0)&&bt.length===0){let me=iu();return E(C,{matches:j,loaderData:{},errors:re&&ft(re[1])?{[re[0]]:re[1].error}:null,...Nu(re),...me?{fetchers:new Map(x.fetchers)}:{}},{flushSync:oe}),{shortCircuited:!0}}if(ze){let me={};if(!F){me.navigation=be;let qe=Kr(re);qe!==void 0&&(me.actionData=qe)}bt.length>0&&(me.fetchers=Us(bt)),Fe(me,{flushSync:oe})}bt.forEach(me=>{rn(me.key),me.controller&&z.set(me.key,me.controller)});let zn=()=>bt.forEach(me=>rn(me.key));L&&L.signal.addEventListener("abort",zn);let{loaderResults:qr,fetcherResults:pn}=await tu(ke,bt,w,I);if(w.signal.aborted)return{shortCircuited:!0};L&&L.signal.removeEventListener("abort",zn),bt.forEach(me=>z.delete(me.key));let It=Zs(qr);if(It)return await Vn(w,It.result,!0,{replace:te}),{shortCircuited:!0};if(It=Zs(pn),It)return Z.add(It.key),await Vn(w,It.result,!0,{replace:te}),{shortCircuited:!0};let{loaderData:Ka,errors:Yr}=Du(x,j,qr,re,bt,pn);se&&x.errors&&(Yr={...x.errors,...Yr});let Hn=iu(),Ys=su(B),Qs=Hn||Ys||bt.length>0;return{matches:j,loaderData:Ka,errors:Yr,...Qs?{fetchers:new Map(x.fetchers)}:{}}}function Kr(w){if(w&&!ft(w[1]))return{[w[0]]:w[1].data};if(x.actionData)return Object.keys(x.actionData).length===0?null:x.actionData}function Us(w){return w.forEach(C=>{let j=x.fetchers.get(C.key),I=Jr(void 0,j?j.data:void 0);x.fetchers.set(C.key,I)}),new Map(x.fetchers)}async function Ve(w,C,j,I){rn(w);let F=(I&&I.flushSync)===!0,ee=l||a,Q=Zl(x.location,x.matches,c,j,C,I?.relative),X=xn(ee,Q,c),te=Gs(X,ee,Q);if(te.active&&te.matches&&(X=te.matches),!X){nn(w,C,yt(404,{pathname:Q}),{flushSync:F});return}let{path:se,submission:oe,error:re}=ku(!0,Q,I);if(re){nn(w,C,re,{flushSync:F});return}let ge=n.getContext?await n.getContext():new gu,be=(I&&I.preventScrollReset)===!0;if(oe&&Ye(oe.formMethod)){await Jb(w,C,se,X,ge,te.active,F,be,oe,I&&I.unstable_defaultShouldRevalidate);return}ae.set(w,{routeId:C,path:se}),await Xb(w,C,se,X,ge,te.active,F,be,oe)}async function Jb(w,C,j,I,F,ee,Q,X,te,se){Wa(),ae.delete(w);let oe=x.fetchers.get(w);tn(w,Oy(te,oe),{flushSync:Q});let re=new AbortController,ge=hr(n.history,j,re.signal,te);if(ee){let Ae=await qs(I,new URL(ge.url).pathname,ge.signal,w);if(Ae.type==="aborted")return;if(Ae.type==="error"){nn(w,C,Ae.error,{flushSync:Q});return}else if(Ae.matches)I=Ae.matches;else{nn(w,C,yt(404,{pathname:j}),{flushSync:Q});return}}let be=To(I,j);if(!be.route.action&&!be.route.lazy){let Ae=yt(405,{method:te.formMethod,pathname:j,routeId:C});nn(w,C,Ae,{flushSync:Q});return}z.set(w,re);let We=q,ze=xr(s,o,ge,I,be,r,F),Ze=await Gr(ge,ze,F,w),ke=Ze[be.route.id];if(!ke){for(let Ae of ze)if(Ze[Ae.route.id]){ke=Ze[Ae.route.id];break}}if(ge.signal.aborted){z.get(w)===re&&z.delete(w);return}if(Se.has(w)){if(qn(ke)||ft(ke)){tn(w,sn(void 0));return}}else{if(qn(ke))if(z.delete(w),B>We){tn(w,sn(void 0));return}else return Z.add(w),tn(w,Jr(te)),Vn(ge,ke,!1,{fetcherSubmission:te,preventScrollReset:X});if(ft(ke)){nn(w,C,ke.error);return}}let bt=x.navigation.location||x.location,zn=hr(n.history,bt,re.signal),qr=l||a,pn=x.navigation.state!=="idle"?xn(qr,x.navigation.location,c):x.matches;he(pn,"Didn't find any matches after fetcher action");let It=++q;ne.set(w,It);let Ka=Jr(te,ke.data);x.fetchers.set(w,Ka);let{dsMatches:Yr,revalidatingFetchers:Hn}=Su(zn,F,s,o,n.history,x,pn,te,bt,r,!1,J,ue,Se,ae,Z,qr,c,n.patchRoutesOnNavigation!=null,[be.route.id,ke],se);Hn.filter(Ae=>Ae.key!==w).forEach(Ae=>{let Js=Ae.key,uu=x.fetchers.get(Js),o1=Jr(void 0,uu?uu.data:void 0);x.fetchers.set(Js,o1),rn(Js),Ae.controller&&z.set(Js,Ae.controller)}),Fe({fetchers:new Map(x.fetchers)});let Ys=()=>Hn.forEach(Ae=>rn(Ae.key));re.signal.addEventListener("abort",Ys);let{loaderResults:Qs,fetcherResults:me}=await tu(Yr,Hn,zn,F);if(re.signal.aborted)return;if(re.signal.removeEventListener("abort",Ys),ne.delete(w),z.delete(w),Hn.forEach(Ae=>z.delete(Ae.key)),x.fetchers.has(w)){let Ae=sn(ke.data);x.fetchers.set(w,Ae)}let qe=Zs(Qs);if(qe)return Vn(zn,qe.result,!1,{preventScrollReset:X});if(qe=Zs(me),qe)return Z.add(qe.key),Vn(zn,qe.result,!1,{preventScrollReset:X});let{loaderData:lr,errors:Wn}=Du(x,pn,Qs,void 0,Hn,me);su(It),x.navigation.state==="loading"&&It>B?(he(D,"Expected pending action"),L&&L.abort(),E(x.navigation.location,{matches:pn,loaderData:lr,errors:Wn,fetchers:new Map(x.fetchers)})):(Fe({errors:Wn,loaderData:Tu(x.loaderData,lr,pn,Wn),fetchers:new Map(x.fetchers)}),J=!1)}async function Xb(w,C,j,I,F,ee,Q,X,te){let se=x.fetchers.get(w);tn(w,Jr(te,se?se.data:void 0),{flushSync:Q});let oe=new AbortController,re=hr(n.history,j,oe.signal);if(ee){let ke=await qs(I,new URL(re.url).pathname,re.signal,w);if(ke.type==="aborted")return;if(ke.type==="error"){nn(w,C,ke.error,{flushSync:Q});return}else if(ke.matches)I=ke.matches;else{nn(w,C,yt(404,{pathname:j}),{flushSync:Q});return}}let ge=To(I,j);z.set(w,oe);let be=q,We=xr(s,o,re,I,ge,r,F),Ze=(await Gr(re,We,F,w))[ge.route.id];if(z.get(w)===oe&&z.delete(w),!re.signal.aborted){if(Se.has(w)){tn(w,sn(void 0));return}if(qn(Ze))if(B>be){tn(w,sn(void 0));return}else{Z.add(w),await Vn(re,Ze,!1,{preventScrollReset:X});return}if(ft(Ze)){nn(w,C,Ze.error);return}tn(w,sn(Ze.data))}}async function Vn(w,C,j,{submission:I,fetcherSubmission:F,preventScrollReset:ee,replace:Q}={}){j||(T?.resolve(),T=null),C.response.headers.has("X-Remix-Revalidate")&&(J=!0);let X=C.response.headers.get("Location");he(X,"Expected a Location header on the redirect Response"),X=Mu(X,new URL(w.url),c);let te=wi(x.location,X,{_isRedirect:!0});if(t){let We=!1;if(C.response.headers.has("X-Remix-Reload-Document"))We=!0;else if(xa(X)){const ze=$p(X,!0);We=ze.origin!==e.location.origin||Ct(ze.pathname,c)==null}if(We){Q?e.location.replace(X):e.location.assign(X);return}}L=null;let se=Q===!0||C.response.headers.has("X-Remix-Replace")?"REPLACE":"PUSH",{formMethod:oe,formAction:re,formEncType:ge}=x.navigation;!I&&!F&&oe&&re&&ge&&(I=Ru(x.navigation));let be=I||F;if(ey.has(C.response.status)&&be&&Ye(be.formMethod))await we(se,te,{submission:{...be,formAction:X},preventScrollReset:ee||R,enableViewTransition:j?$:void 0});else{let We=Qa(te,I);await we(se,te,{overrideNavigation:We,fetcherSubmission:F,preventScrollReset:ee||R,enableViewTransition:j?$:void 0})}}async function Gr(w,C,j,I){let F,ee={};try{F=await hy(h,w,C,I,j,!1)}catch(Q){return C.filter(X=>X.shouldLoad).forEach(X=>{ee[X.route.id]={type:"error",error:Q}}),ee}if(w.signal.aborted)return ee;if(!Ye(w.method))for(let Q of C){if(F[Q.route.id]?.type==="error")break;!F.hasOwnProperty(Q.route.id)&&!x.loaderData.hasOwnProperty(Q.route.id)&&(!x.errors||!x.errors.hasOwnProperty(Q.route.id))&&Q.shouldCallHandler()&&(F[Q.route.id]={type:"error",result:new Error(`No result returned from dataStrategy for route ${Q.route.id}`)})}for(let[Q,X]of Object.entries(F))if(vy(X)){let te=X.result;ee[Q]={type:"redirect",response:py(te,w,Q,C,c)}}else ee[Q]=await fy(X);return ee}async function tu(w,C,j,I){let F=Gr(j,w,I,null),ee=Promise.all(C.map(async te=>{if(te.matches&&te.match&&te.request&&te.controller){let oe=(await Gr(te.request,te.matches,I,te.key))[te.match.route.id];return{[te.key]:oe}}else return Promise.resolve({[te.key]:{type:"error",error:yt(404,{pathname:te.path})}})})),Q=await F,X=(await ee).reduce((te,se)=>Object.assign(te,se),{});return{loaderResults:Q,fetcherResults:X}}function Wa(){J=!0,ae.forEach((w,C)=>{z.has(C)&&ue.add(C),rn(C)})}function tn(w,C,j={}){x.fetchers.set(w,C),Fe({fetchers:new Map(x.fetchers)},{flushSync:(j&&j.flushSync)===!0})}function nn(w,C,j,I={}){let F=vn(x.matches,C);_a(w),Fe({errors:{[F.route.id]:j},fetchers:new Map(x.fetchers)},{flushSync:(I&&I.flushSync)===!0})}function nu(w){return ce.set(w,(ce.get(w)||0)+1),Se.has(w)&&Se.delete(w),x.fetchers.get(w)||ty}function Zb(w,C){rn(w,C?.reason),tn(w,sn(null))}function _a(w){let C=x.fetchers.get(w);z.has(w)&&!(C&&C.state==="loading"&&ne.has(w))&&rn(w),ae.delete(w),ne.delete(w),Z.delete(w),Se.delete(w),ue.delete(w),x.fetchers.delete(w)}function e1(w){let C=(ce.get(w)||0)-1;C<=0?(ce.delete(w),Se.add(w)):ce.set(w,C),Fe({fetchers:new Map(x.fetchers)})}function rn(w,C){let j=z.get(w);j&&(j.abort(C),z.delete(w))}function ru(w){for(let C of w){let j=nu(C),I=sn(j.data);x.fetchers.set(C,I)}}function iu(){let w=[],C=!1;for(let j of Z){let I=x.fetchers.get(j);he(I,`Expected fetcher: ${j}`),I.state==="loading"&&(Z.delete(j),w.push(j),C=!0)}return ru(w),C}function su(w){let C=[];for(let[j,I]of ne)if(I<w){let F=x.fetchers.get(j);he(F,`Expected fetcher: ${j}`),F.state==="loading"&&(rn(j),ne.delete(j),C.push(j))}return ru(C),C.length>0}function t1(w,C){let j=x.blockers.get(w)||Qr;return rt.get(w)!==C&&rt.set(w,C),j}function ou(w){x.blockers.delete(w),rt.delete(w)}function Ks(w,C){let j=x.blockers.get(w)||Qr;he(j.state==="unblocked"&&C.state==="blocked"||j.state==="blocked"&&C.state==="blocked"||j.state==="blocked"&&C.state==="proceeding"||j.state==="blocked"&&C.state==="unblocked"||j.state==="proceeding"&&C.state==="unblocked",`Invalid blocker state transition: ${j.state} -> ${C.state}`);let I=new Map(x.blockers);I.set(w,C),Fe({blockers:I})}function au({currentLocation:w,nextLocation:C,historyAction:j}){if(rt.size===0)return;rt.size>1&&Te(!1,"A router only supports one blocker at a time");let I=Array.from(rt.entries()),[F,ee]=I[I.length-1],Q=x.blockers.get(F);if(!(Q&&Q.state==="proceeding")&&ee({currentLocation:w,nextLocation:C,historyAction:j}))return F}function Ua(w){let C=yt(404,{pathname:w}),j=l||a,{matches:I,route:F}=Xs(j);return{notFoundMatches:I,route:F,error:C}}function n1(w,C,j){if(m=w,y=C,g=j||null,!v&&x.navigation===Ya){v=!0;let I=cu(x.location,x.matches);I!=null&&Fe({restoreScrollPosition:I})}return()=>{m=null,y=null,g=null}}function lu(w,C){return g&&g(w,C.map(I=>P1(I,x.loaderData)))||w.key}function r1(w,C){if(m&&y){let j=lu(w,C);m[j]=y()}}function cu(w,C){if(m){let j=lu(w,C),I=m[j];if(typeof I=="number")return I}return null}function Gs(w,C,j){if(n.patchRoutesOnNavigation)if(w){if(Object.keys(w[0].params).length>0)return{active:!0,matches:ai(C,j,c,!0)}}else return{active:!0,matches:ai(C,j,c,!0)||[]};return{active:!1,matches:null}}async function qs(w,C,j,I){if(!n.patchRoutesOnNavigation)return{type:"success",matches:w};let F=w;for(;;){let ee=l==null,Q=l||a,X=o;try{await n.patchRoutesOnNavigation({signal:j,path:C,matches:F,fetcherKey:I,patch:(oe,re)=>{j.aborted||Cu(oe,re,Q,X,s,!1)}})}catch(oe){return{type:"error",error:oe,partialMatches:F}}finally{ee&&!j.aborted&&(a=[...a])}if(j.aborted)return{type:"aborted"};let te=xn(Q,C,c),se=null;if(te){if(Object.keys(te[0].params).length===0)return{type:"success",matches:te};if(se=ai(Q,C,c,!0),!(se&&F.length<se.length&&hu(F,se.slice(0,F.length))))return{type:"success",matches:te}}if(se||(se=ai(Q,C,c,!0)),!se||hu(F,se))return{type:"success",matches:null};F=se}}function hu(w,C){return w.length===C.length&&w.every((j,I)=>j.route.id===C[I].route.id)}function i1(w){o={},l=ki(w,s,void 0,o)}function s1(w,C,j=!1){let I=l==null;Cu(w,C,l||a,o,s,j),I&&(a=[...a],Fe({}))}return M={get basename(){return c},get future(){return d},get state(){return x},get routes(){return a},get window(){return e},initialize:Va,subscribe:Ha,enableScrollRestoration:n1,navigate:Y,fetch:Ve,revalidate:ve,createHref:w=>n.history.createHref(w),encodeLocation:w=>n.history.encodeLocation(w),getFetcher:nu,resetFetcher:Zb,deleteFetcher:e1,dispose:za,getBlocker:t1,deleteBlocker:ou,patchRoutes:s1,_internalFetchControllers:z,_internalSetRoutes:i1,_internalSetStateDoNotUseOrYouWillBreakYourApp(w){Fe(w)}},n.unstable_instrumentations&&(M=K1(M,n.unstable_instrumentations.map(w=>w.router).filter(Boolean))),M}function iy(n){return n!=null&&("formData"in n&&n.formData!=null||"body"in n&&n.body!==void 0)}function Zl(n,e,t,r,i,s){let o,a;if(i){o=[];for(let c of e)if(o.push(c),c.route.id===i){a=c;break}}else o=e,a=e[e.length-1];let l=wa(r||".",va(o),Ct(n.pathname,t)||n.pathname,s==="path");if(r==null&&(l.search=n.search,l.hash=n.hash),(r==null||r===""||r===".")&&a){let c=th(l.search);if(a.route.index&&!c)l.search=l.search?l.search.replace(/^\?/,"?index&"):"?index";else if(!a.route.index&&c){let h=new URLSearchParams(l.search),d=h.getAll("index");h.delete("index"),d.filter(p=>p).forEach(p=>h.append("index",p));let f=h.toString();l.search=f?`?${f}`:""}}return t!=="/"&&(l.pathname=V1({basename:t,pathname:l.pathname})),Yt(l)}function ku(n,e,t){if(!t||!iy(t))return{path:e};if(t.formMethod&&!Sy(t.formMethod))return{path:e,error:yt(405,{method:t.formMethod})};let r=()=>({path:e,error:yt(400,{type:"invalid-body"})}),s=(t.formMethod||"get").toUpperCase(),o=tm(e);if(t.body!==void 0){if(t.formEncType==="text/plain"){if(!Ye(s))return r();let d=typeof t.body=="string"?t.body:t.body instanceof FormData||t.body instanceof URLSearchParams?Array.from(t.body.entries()).reduce((f,[p,m])=>`${f}${p}=${m}
19
19
  `,""):String(t.body);return{path:e,submission:{formMethod:s,formAction:o,formEncType:t.formEncType,formData:void 0,json:void 0,text:d}}}else if(t.formEncType==="application/json"){if(!Ye(s))return r();try{let d=typeof t.body=="string"?JSON.parse(t.body):t.body;return{path:e,submission:{formMethod:s,formAction:o,formEncType:t.formEncType,formData:void 0,json:d,text:void 0}}}catch{return r()}}}he(typeof FormData=="function","FormData is not available in this environment");let a,l;if(t.formData)a=nc(t.formData),l=t.formData;else if(t.body instanceof FormData)a=nc(t.body),l=t.body;else if(t.body instanceof URLSearchParams)a=t.body,l=Au(a);else if(t.body==null)a=new URLSearchParams,l=new FormData;else try{a=new URLSearchParams(t.body),l=Au(a)}catch{return r()}let c={formMethod:s,formAction:o,formEncType:t&&t.formEncType||"application/x-www-form-urlencoded",formData:l,json:void 0,text:void 0};if(Ye(c.formMethod))return{path:e,submission:c};let h=Rn(e);return n&&h.search&&th(h.search)&&a.append("index",""),h.search=`?${a}`,{path:Yt(h),submission:c}}function Su(n,e,t,r,i,s,o,a,l,c,h,d,f,p,m,g,y,v,k,S,P){let O=S?ft(S[1])?S[1].error:S[1].data:void 0,M=i.createURL(s.location),x=i.createURL(l),D;if(h&&s.errors){let V=Object.keys(s.errors)[0];D=o.findIndex(J=>J.route.id===V)}else if(S&&ft(S[1])){let V=S[0];D=o.findIndex(J=>J.route.id===V)-1}let T=S?S[1].statusCode:void 0,R=T&&T>=400,L={currentUrl:M,currentParams:s.matches[0]?.params||{},nextUrl:x,nextParams:o[0].params,...a,actionResult:O,actionStatus:T},$=Ms(o),U=o.map((V,J)=>{let{route:ue}=V,z=null;if(D!=null&&J>D?z=!1:ue.lazy?z=!0:Zc(ue)?h?z=ec(ue,s.loaderData,s.errors):sy(s.loaderData,s.matches[J],V)&&(z=!0):z=!1,z!==null)return tc(t,r,n,$,V,c,e,z);let q=!1;typeof P=="boolean"?q=P:R?q=!1:(d||M.pathname+M.search===x.pathname+x.search||M.search!==x.search||oy(s.matches[J],V))&&(q=!0);let B={...L,defaultShouldRevalidate:q},ne=di(V,B);return tc(t,r,n,$,V,c,e,ne,B,P)}),_=[];return m.forEach((V,J)=>{if(h||!o.some(ce=>ce.route.id===V.routeId)||p.has(J))return;let ue=s.fetchers.get(J),z=ue&&ue.state!=="idle"&&ue.data===void 0,q=xn(y,V.path,v);if(!q){if(k&&z)return;_.push({key:J,routeId:V.routeId,path:V.path,matches:null,match:null,request:null,controller:null});return}if(g.has(J))return;let B=To(q,V.path),ne=new AbortController,Z=hr(i,V.path,ne.signal),ae=null;if(f.has(J))f.delete(J),ae=xr(t,r,Z,q,B,c,e);else if(z)d&&(ae=xr(t,r,Z,q,B,c,e));else{let ce;typeof P=="boolean"?ce=P:R?ce=!1:ce=d;let Se={...L,defaultShouldRevalidate:ce};di(B,Se)&&(ae=xr(t,r,Z,q,B,c,e,Se))}ae&&_.push({key:J,routeId:V.routeId,path:V.path,matches:ae,match:B,request:Z,controller:ne})}),{dsMatches:U,revalidatingFetchers:_}}function Zc(n){return n.loader!=null||n.middleware!=null&&n.middleware.length>0}function ec(n,e,t){if(n.lazy)return!0;if(!Zc(n))return!1;let r=e!=null&&n.id in e,i=t!=null&&t[n.id]!==void 0;return!r&&i?!1:typeof n.loader=="function"&&n.loader.hydrate===!0?!0:!r&&!i}function sy(n,e,t){let r=!e||t.route.id!==e.route.id,i=!n.hasOwnProperty(t.route.id);return r||i}function oy(n,e){let t=n.route.path;return n.pathname!==e.pathname||t!=null&&t.endsWith("*")&&n.params["*"]!==e.params["*"]}function di(n,e){if(n.route.shouldRevalidate){let t=n.route.shouldRevalidate(e);if(typeof t=="boolean")return t}return e.defaultShouldRevalidate}function Cu(n,e,t,r,i,s){let o;if(n){let c=r[n];he(c,`No route found to patch children into: routeId = ${n}`),c.children||(c.children=[]),o=c.children}else o=t;let a=[],l=[];if(e.forEach(c=>{let h=o.find(d=>Qp(c,d));h?l.push({existingRoute:h,newRoute:c}):a.push(c)}),a.length>0){let c=ki(a,i,[n||"_","patch",String(o?.length||"0")],r);o.push(...c)}if(s&&l.length>0)for(let c=0;c<l.length;c++){let{existingRoute:h,newRoute:d}=l[c],f=h,[p]=ki([d],i,[],{},!0);Object.assign(f,{element:p.element?p.element:f.element,errorElement:p.errorElement?p.errorElement:f.errorElement,hydrateFallbackElement:p.hydrateFallbackElement?p.hydrateFallbackElement:f.hydrateFallbackElement})}}function Qp(n,e){return"id"in n&&"id"in e&&n.id===e.id?!0:n.index===e.index&&n.path===e.path&&n.caseSensitive===e.caseSensitive?(!n.children||n.children.length===0)&&(!e.children||e.children.length===0)?!0:n.children.every((t,r)=>e.children?.some(i=>Qp(t,i))):!1}var Ou=new WeakMap,Jp=({key:n,route:e,manifest:t,mapRouteProperties:r})=>{let i=t[e.id];if(he(i,"No route found in manifest"),!i.lazy||typeof i.lazy!="object")return;let s=i.lazy[n];if(!s)return;let o=Ou.get(i);o||(o={},Ou.set(i,o));let a=o[n];if(a)return a;let l=(async()=>{let c=S1(n),d=i[n]!==void 0&&n!=="hasErrorBoundary";if(c)Te(!c,"Route property "+n+" is not a supported lazy route property. This property will be ignored."),o[n]=Promise.resolve();else if(d)Te(!1,`Route "${i.id}" has a static property "${n}" defined. The lazy property will be ignored.`);else{let f=await s();f!=null&&(Object.assign(i,{[n]:f}),Object.assign(i,r(i)))}typeof i.lazy=="object"&&(i.lazy[n]=void 0,Object.values(i.lazy).every(f=>f===void 0)&&(i.lazy=void 0))})();return o[n]=l,l},ju=new WeakMap;function ay(n,e,t,r,i){let s=t[n.id];if(he(s,"No route found in manifest"),!n.lazy)return{lazyRoutePromise:void 0,lazyHandlerPromise:void 0};if(typeof n.lazy=="function"){let h=ju.get(s);if(h)return{lazyRoutePromise:h,lazyHandlerPromise:h};let d=(async()=>{he(typeof n.lazy=="function","No lazy route function found");let f=await n.lazy(),p={};for(let m in f){let g=f[m];if(g===void 0)continue;let y=O1(m),k=s[m]!==void 0&&m!=="hasErrorBoundary";y?Te(!y,"Route property "+m+" is not a supported property to be returned from a lazy route function. This property will be ignored."):k?Te(!k,`Route "${s.id}" has a static property "${m}" defined but its lazy function is also returning a value for this property. The lazy route property "${m}" will be ignored.`):p[m]=g}Object.assign(s,p),Object.assign(s,{...r(s),lazy:void 0})})();return ju.set(s,d),d.catch(()=>{}),{lazyRoutePromise:d,lazyHandlerPromise:d}}let o=Object.keys(n.lazy),a=[],l;for(let h of o){if(i&&i.includes(h))continue;let d=Jp({key:h,route:n,manifest:t,mapRouteProperties:r});d&&(a.push(d),h===e&&(l=d))}let c=a.length>0?Promise.all(a).then(()=>{}):void 0;return c?.catch(()=>{}),l?.catch(()=>{}),{lazyRoutePromise:c,lazyHandlerPromise:l}}async function Pu(n){let e=n.matches.filter(i=>i.shouldLoad),t={};return(await Promise.all(e.map(i=>i.resolve()))).forEach((i,s)=>{t[e[s].route.id]=i}),t}async function ly(n){return n.matches.some(e=>e.route.middleware)?Xp(n,()=>Pu(n)):Pu(n)}function Xp(n,e){return cy(n,e,r=>{if(ky(r))throw r;return r},yy,t);function t(r,i,s){if(s)return Promise.resolve(Object.assign(s.value,{[i]:{type:"error",result:r}}));{let{matches:o}=n,a=Math.min(Math.max(o.findIndex(c=>c.route.id===i),0),Math.max(o.findIndex(c=>c.shouldCallHandler()),0)),l=vn(o,o[a].route.id).route.id;return Promise.resolve({[l]:{type:"error",result:r}})}}}async function cy(n,e,t,r,i){let{matches:s,request:o,params:a,context:l,unstable_pattern:c}=n,h=s.flatMap(f=>f.route.middleware?f.route.middleware.map(p=>[f.route.id,p]):[]);return await Zp({request:o,params:a,context:l,unstable_pattern:c},h,e,t,r,i)}async function Zp(n,e,t,r,i,s,o=0){let{request:a}=n;if(a.signal.aborted)throw a.signal.reason??new Error(`Request aborted: ${a.method} ${a.url}`);let l=e[o];if(!l)return await t();let[c,h]=l,d,f=async()=>{if(d)throw new Error("You may only call `next()` once per middleware");try{return d={value:await Zp(n,e,t,r,i,s,o+1)},d.value}catch(p){return d={value:await s(p,c,d)},d.value}};try{let p=await h(n,f),m=p!=null?r(p):void 0;return i(m)?m:d?m??d.value:(d={value:await f()},d.value)}catch(p){return await s(p,c,d)}}function em(n,e,t,r,i){let s=Jp({key:"middleware",route:r.route,manifest:e,mapRouteProperties:n}),o=ay(r.route,Ye(t.method)?"action":"loader",e,n,i);return{middleware:s,route:o.lazyRoutePromise,handler:o.lazyHandlerPromise}}function tc(n,e,t,r,i,s,o,a,l=null,c){let h=!1,d=em(n,e,t,i,s);return{...i,_lazyPromises:d,shouldLoad:a,shouldRevalidateArgs:l,shouldCallHandler(f){return h=!0,l?typeof c=="boolean"?di(i,{...l,defaultShouldRevalidate:c}):typeof f=="boolean"?di(i,{...l,defaultShouldRevalidate:f}):di(i,l):a},resolve(f){let{lazy:p,loader:m,middleware:g}=i.route,y=h||a||f&&!Ye(t.method)&&(p||m),v=g&&g.length>0&&!m&&!p;return y&&(Ye(t.method)||!v)?uy({request:t,unstable_pattern:r,match:i,lazyHandlerPromise:d?.handler,lazyRoutePromise:d?.route,handlerOverride:f,scopedContext:o}):Promise.resolve({type:"data",result:void 0})}}}function xr(n,e,t,r,i,s,o,a=null){return r.map(l=>l.route.id!==i.route.id?{...l,shouldLoad:!1,shouldRevalidateArgs:a,shouldCallHandler:()=>!1,_lazyPromises:em(n,e,t,l,s),resolve:()=>Promise.resolve({type:"data",result:void 0})}:tc(n,e,t,Ms(r),l,s,o,!0,a))}async function hy(n,e,t,r,i,s){t.some(c=>c._lazyPromises?.middleware)&&await Promise.all(t.map(c=>c._lazyPromises?.middleware));let o={request:e,unstable_pattern:Ms(t),params:t[0].params,context:i,matches:t},l=await n({...o,fetcherKey:r,runClientMiddleware:c=>{let h=o;return Xp(h,()=>c({...h,fetcherKey:r,runClientMiddleware:()=>{throw new Error("Cannot call `runClientMiddleware()` from within an `runClientMiddleware` handler")}}))}});try{await Promise.all(t.flatMap(c=>[c._lazyPromises?.handler,c._lazyPromises?.route]))}catch{}return l}async function uy({request:n,unstable_pattern:e,match:t,lazyHandlerPromise:r,lazyRoutePromise:i,handlerOverride:s,scopedContext:o}){let a,l,c=Ye(n.method),h=c?"action":"loader",d=f=>{let p,m=new Promise((v,k)=>p=k);l=()=>p(),n.signal.addEventListener("abort",l);let g=v=>typeof f!="function"?Promise.reject(new Error(`You cannot call the handler for a route which defines a boolean "${h}" [routeId: ${t.route.id}]`)):f({request:n,unstable_pattern:e,params:t.params,context:o},...v!==void 0?[v]:[]),y=(async()=>{try{return{type:"data",result:await(s?s(k=>g(k)):g())}}catch(v){return{type:"error",result:v}}})();return Promise.race([y,m])};try{let f=c?t.route.action:t.route.loader;if(r||i)if(f){let p,[m]=await Promise.all([d(f).catch(g=>{p=g}),r,i]);if(p!==void 0)throw p;a=m}else{await r;let p=c?t.route.action:t.route.loader;if(p)[a]=await Promise.all([d(p),i]);else if(h==="action"){let m=new URL(n.url),g=m.pathname+m.search;throw yt(405,{method:n.method,pathname:g,routeId:t.route.id})}else return{type:"data",result:void 0}}else if(f)a=await d(f);else{let p=new URL(n.url),m=p.pathname+p.search;throw yt(404,{pathname:m})}}catch(f){return{type:"error",result:f}}finally{l&&n.signal.removeEventListener("abort",l)}return a}async function dy(n){let e=n.headers.get("Content-Type");return e&&/\bapplication\/json\b/.test(e)?n.body==null?null:n.json():n.text()}async function fy(n){let{result:e,type:t}=n;if(eh(e)){let r;try{r=await dy(e)}catch(i){return{type:"error",error:i}}return t==="error"?{type:"error",error:new Ps(e.status,e.statusText,r),statusCode:e.status,headers:e.headers}:{type:"data",data:r,statusCode:e.status,headers:e.headers}}return t==="error"?Eu(e)?e.data instanceof Error?{type:"error",error:e.data,statusCode:e.init?.status,headers:e.init?.headers?new Headers(e.init.headers):void 0}:{type:"error",error:by(e),statusCode:Si(e)?e.status:void 0,headers:e.init?.headers?new Headers(e.init.headers):void 0}:{type:"error",error:e,statusCode:Si(e)?e.status:void 0}:Eu(e)?{type:"data",data:e.data,statusCode:e.init?.status,headers:e.init?.headers?new Headers(e.init.headers):void 0}:{type:"data",data:e}}function py(n,e,t,r,i){let s=n.headers.get("Location");if(he(s,"Redirects returned/thrown from loaders/actions must have a Location header"),!xa(s)){let o=r.slice(0,r.findIndex(a=>a.route.id===t)+1);s=Zl(new URL(e.url),o,i,s),n.headers.set("Location",s)}return n}function Mu(n,e,t){if(xa(n)){let r=n,i=r.startsWith("//")?new URL(e.protocol+r):new URL(r),s=Ct(i.pathname,t)!=null;if(i.origin===e.origin&&s)return i.pathname+i.search+i.hash}return n}function hr(n,e,t,r){let i=n.createURL(tm(e)).toString(),s={signal:t};if(r&&Ye(r.formMethod)){let{formMethod:o,formEncType:a}=r;s.method=o.toUpperCase(),a==="application/json"?(s.headers=new Headers({"Content-Type":a}),s.body=JSON.stringify(r.json)):a==="text/plain"?s.body=r.text:a==="application/x-www-form-urlencoded"&&r.formData?s.body=nc(r.formData):s.body=r.formData}return new Request(i,s)}function nc(n){let e=new URLSearchParams;for(let[t,r]of n.entries())e.append(t,typeof r=="string"?r:r.name);return e}function Au(n){let e=new FormData;for(let[t,r]of n.entries())e.append(t,r);return e}function my(n,e,t,r=!1,i=!1){let s={},o=null,a,l=!1,c={},h=t&&ft(t[1])?t[1].error:void 0;return n.forEach(d=>{if(!(d.route.id in e))return;let f=d.route.id,p=e[f];if(he(!qn(p),"Cannot handle redirect results in processLoaderData"),ft(p)){let m=p.error;if(h!==void 0&&(m=h,h=void 0),o=o||{},i)o[f]=m;else{let g=vn(n,f);o[g.route.id]==null&&(o[g.route.id]=m)}r||(s[f]=Yp),l||(l=!0,a=Si(p.error)?p.error.status:500),p.headers&&(c[f]=p.headers)}else s[f]=p.data,p.statusCode&&p.statusCode!==200&&!l&&(a=p.statusCode),p.headers&&(c[f]=p.headers)}),h!==void 0&&t&&(o={[t[0]]:h},t[2]&&(s[t[2]]=void 0)),{loaderData:s,errors:o,statusCode:a||200,loaderHeaders:c}}function Du(n,e,t,r,i,s){let{loaderData:o,errors:a}=my(e,t,r);return i.filter(l=>!l.matches||l.matches.some(c=>c.shouldLoad)).forEach(l=>{let{key:c,match:h,controller:d}=l;if(d&&d.signal.aborted)return;let f=s[c];if(he(f,"Did not find corresponding fetcher result"),ft(f)){let p=vn(n.matches,h?.route.id);a&&a[p.route.id]||(a={...a,[p.route.id]:f.error}),n.fetchers.delete(c)}else if(qn(f))he(!1,"Unhandled fetcher revalidation redirect");else{let p=sn(f.data);n.fetchers.set(c,p)}}),{loaderData:o,errors:a}}function Tu(n,e,t,r){let i=Object.entries(e).filter(([,s])=>s!==Yp).reduce((s,[o,a])=>(s[o]=a,s),{});for(let s of t){let o=s.route.id;if(!e.hasOwnProperty(o)&&n.hasOwnProperty(o)&&s.route.loader&&(i[o]=n[o]),r&&r.hasOwnProperty(o))break}return i}function Nu(n){return n?ft(n[1])?{actionData:{}}:{actionData:{[n[0]]:n[1].data}}:{}}function vn(n,e){return(e?n.slice(0,n.findIndex(r=>r.route.id===e)+1):[...n]).reverse().find(r=>r.route.hasErrorBoundary===!0)||n[0]}function Xs(n){let e=n.length===1?n[0]:n.find(t=>t.index||!t.path||t.path==="/")||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route:e}],route:e}}function yt(n,{pathname:e,routeId:t,method:r,type:i,message:s}={}){let o="Unknown Server Error",a="Unknown @remix-run/router error";return n===400?(o="Bad Request",r&&e&&t?a=`You made a ${r} request to "${e}" but did not provide a \`loader\` for route "${t}", so there is no way to handle the request.`:i==="invalid-body"&&(a="Unable to encode submission body")):n===403?(o="Forbidden",a=`Route "${t}" does not match URL "${e}"`):n===404?(o="Not Found",a=`No route matches URL "${e}"`):n===405&&(o="Method Not Allowed",r&&e&&t?a=`You made a ${r.toUpperCase()} request to "${e}" but did not provide an \`action\` for route "${t}", so there is no way to handle the request.`:r&&(a=`Invalid request method "${r.toUpperCase()}"`)),new Ps(n||500,o,new Error(a),!0)}function Zs(n){let e=Object.entries(n);for(let t=e.length-1;t>=0;t--){let[r,i]=e[t];if(qn(i))return{key:r,result:i}}}function tm(n){let e=typeof n=="string"?Rn(n):n;return Yt({...e,hash:""})}function gy(n,e){return n.pathname!==e.pathname||n.search!==e.search?!1:n.hash===""?e.hash!=="":n.hash===e.hash?!0:e.hash!==""}function by(n){return new Ps(n.init?.status??500,n.init?.statusText??"Internal Server Error",n.data)}function yy(n){return n!=null&&typeof n=="object"&&Object.entries(n).every(([e,t])=>typeof e=="string"&&xy(t))}function xy(n){return n!=null&&typeof n=="object"&&"type"in n&&"result"in n&&(n.type==="data"||n.type==="error")}function vy(n){return eh(n.result)&&Gp.has(n.result.status)}function ft(n){return n.type==="error"}function qn(n){return(n&&n.type)==="redirect"}function Eu(n){return typeof n=="object"&&n!=null&&"type"in n&&"data"in n&&"init"in n&&n.type==="DataWithResponseInit"}function eh(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.headers=="object"&&typeof n.body<"u"}function wy(n){return Gp.has(n)}function ky(n){return eh(n)&&wy(n.status)&&n.headers.has("Location")}function Sy(n){return Z1.has(n.toUpperCase())}function Ye(n){return J1.has(n.toUpperCase())}function th(n){return new URLSearchParams(n).getAll("index").some(e=>e==="")}function To(n,e){let t=typeof e=="string"?Rn(e).search:e.search;if(n[n.length-1].route.index&&th(t||""))return n[n.length-1];let r=Hp(n);return r[r.length-1]}function Ru(n){let{formMethod:e,formAction:t,formEncType:r,text:i,formData:s,json:o}=n;if(!(!e||!t||!r)){if(i!=null)return{formMethod:e,formAction:t,formEncType:r,formData:void 0,json:void 0,text:i};if(s!=null)return{formMethod:e,formAction:t,formEncType:r,formData:s,json:void 0,text:void 0};if(o!==void 0)return{formMethod:e,formAction:t,formEncType:r,formData:void 0,json:o,text:void 0}}}function Qa(n,e){return e?{state:"loading",location:n,formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text}:{state:"loading",location:n,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function Cy(n,e){return{state:"submitting",location:n,formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text}}function Jr(n,e){return n?{state:"loading",formMethod:n.formMethod,formAction:n.formAction,formEncType:n.formEncType,formData:n.formData,json:n.json,text:n.text,data:e}:{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}function Oy(n,e){return{state:"submitting",formMethod:n.formMethod,formAction:n.formAction,formEncType:n.formEncType,formData:n.formData,json:n.json,text:n.text,data:e?e.data:void 0}}function sn(n){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:n}}function jy(n,e){try{let t=n.sessionStorage.getItem(qp);if(t){let r=JSON.parse(t);for(let[i,s]of Object.entries(r||{}))s&&Array.isArray(s)&&e.set(i,new Set(s||[]))}}catch{}}function Py(n,e){if(e.size>0){let t={};for(let[r,i]of e)t[r]=[...i];try{n.sessionStorage.setItem(qp,JSON.stringify(t))}catch(r){Te(!1,`Failed to save applied view transitions in sessionStorage (${r}).`)}}}function Lu(){let n,e,t=new Promise((r,i)=>{n=async s=>{r(s);try{await t}catch{}},e=async s=>{i(s);try{await t}catch{}}});return{promise:t,resolve:n,reject:e}}var ir=b.createContext(null);ir.displayName="DataRouter";var As=b.createContext(null);As.displayName="DataRouterState";var nm=b.createContext(!1);function My(){return b.useContext(nm)}var nh=b.createContext({isTransitioning:!1});nh.displayName="ViewTransition";var rm=b.createContext(new Map);rm.displayName="Fetchers";var Ay=b.createContext(null);Ay.displayName="Await";var mt=b.createContext(null);mt.displayName="Navigation";var ka=b.createContext(null);ka.displayName="Location";var jt=b.createContext({outlet:null,matches:[],isDataRoute:!1});jt.displayName="Route";var rh=b.createContext(null);rh.displayName="RouteError";var im="REACT_ROUTER_ERROR",Dy="REDIRECT",Ty="ROUTE_ERROR_RESPONSE";function Ny(n){if(n.startsWith(`${im}:${Dy}:{`))try{let e=JSON.parse(n.slice(28));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.location=="string"&&typeof e.reloadDocument=="boolean"&&typeof e.replace=="boolean")return e}catch{}}function Ey(n){if(n.startsWith(`${im}:${Ty}:{`))try{let e=JSON.parse(n.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new Ps(e.status,e.statusText,e.data)}catch{}}function Ry(n,{relative:e}={}){he(Lr(),"useHref() may be used only in the context of a <Router> component.");let{basename:t,navigator:r}=b.useContext(mt),{hash:i,pathname:s,search:o}=Ds(n,{relative:e}),a=s;return t!=="/"&&(a=s==="/"?t:Gt([t,s])),r.createHref({pathname:a,search:o,hash:i})}function Lr(){return b.useContext(ka)!=null}function Qt(){return he(Lr(),"useLocation() may be used only in the context of a <Router> component."),b.useContext(ka).location}var sm="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function om(n){b.useContext(mt).static||b.useLayoutEffect(n)}function fn(){let{isDataRoute:n}=b.useContext(jt);return n?Yy():Ly()}function Ly(){he(Lr(),"useNavigate() may be used only in the context of a <Router> component.");let n=b.useContext(ir),{basename:e,navigator:t}=b.useContext(mt),{matches:r}=b.useContext(jt),{pathname:i}=Qt(),s=JSON.stringify(va(r)),o=b.useRef(!1);return om(()=>{o.current=!0}),b.useCallback((l,c={})=>{if(Te(o.current,sm),!o.current)return;if(typeof l=="number"){t.go(l);return}let h=wa(l,JSON.parse(s),i,c.relative==="path");n==null&&e!=="/"&&(h.pathname=h.pathname==="/"?e:Gt([e,h.pathname])),(c.replace?t.replace:t.push)(h,c.state,c)},[e,t,s,i,n])}var am=b.createContext(null);function Iy(){return b.useContext(am)}function By(n){let e=b.useContext(jt).outlet;return b.useMemo(()=>e&&b.createElement(am.Provider,{value:n},e),[e,n])}function lm(){let{matches:n}=b.useContext(jt),e=n[n.length-1];return e?e.params:{}}function Ds(n,{relative:e}={}){let{matches:t}=b.useContext(jt),{pathname:r}=Qt(),i=JSON.stringify(va(t));return b.useMemo(()=>wa(n,JSON.parse(i),r,e==="path"),[n,i,r,e])}function $y(n,e,t,r,i){he(Lr(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:s}=b.useContext(mt),{matches:o}=b.useContext(jt),a=o[o.length-1],l=a?a.params:{},c=a?a.pathname:"/",h=a?a.pathnameBase:"/",d=a&&a.route;{let k=d&&d.path||"";hm(c,!d||k.endsWith("*")||k.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${c}" (under <Route path="${k}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
20
20
 
21
- Please change the parent <Route path="${k}"> to <Route path="${k==="/"?"*":`${k}/*`}">.`)}let f=Qt(),p;p=f;let m=p.pathname||"/",g=m;if(h!=="/"){let k=h.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(k.length).join("/")}let y=xn(n,{pathname:g});return Te(d||y!=null,`No routes matched location "${p.pathname}${p.search}${p.hash}" `),Te(y==null||y[y.length-1].route.element!==void 0||y[y.length-1].route.Component!==void 0||y[y.length-1].route.lazy!==void 0,`Matched leaf route at location "${p.pathname}${p.search}${p.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`),Wy(y&&y.map(k=>Object.assign({},k,{params:Object.assign({},l,k.params),pathname:Gt([h,s.encodeLocation?s.encodeLocation(k.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:k.pathname]),pathnameBase:k.pathnameBase==="/"?h:Gt([h,s.encodeLocation?s.encodeLocation(k.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:k.pathnameBase])})),o,t,r,i)}function Fy(){let n=qy(),e=Si(n)?`${n.status} ${n.statusText}`:n instanceof Error?n.message:JSON.stringify(n),t=n instanceof Error?n.stack:null,r="rgba(200,200,200, 0.5)",i={padding:"0.5rem",backgroundColor:r},s={padding:"2px 4px",backgroundColor:r},o=null;return console.error("Error handled by React Router default ErrorBoundary:",n),o=b.createElement(b.Fragment,null,b.createElement("p",null,"💿 Hey developer 👋"),b.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",b.createElement("code",{style:s},"ErrorBoundary")," or"," ",b.createElement("code",{style:s},"errorElement")," prop on your route.")),b.createElement(b.Fragment,null,b.createElement("h2",null,"Unexpected Application Error!"),b.createElement("h3",{style:{fontStyle:"italic"}},e),t?b.createElement("pre",{style:i},t):null,o)}var Vy=b.createElement(Fy,null),cm=class extends b.Component{constructor(n){super(n),this.state={location:n.location,revalidation:n.revalidation,error:n.error}}static getDerivedStateFromError(n){return{error:n}}static getDerivedStateFromProps(n,e){return e.location!==n.location||e.revalidation!=="idle"&&n.revalidation==="idle"?{error:n.error,location:n.location,revalidation:n.revalidation}:{error:n.error!==void 0?n.error:e.error,location:e.location,revalidation:n.revalidation||e.revalidation}}componentDidCatch(n,e){this.props.onError?this.props.onError(n,e):console.error("React Router caught the following error during render",n)}render(){let n=this.state.error;if(this.context&&typeof n=="object"&&n&&"digest"in n&&typeof n.digest=="string"){const t=Ey(n.digest);t&&(n=t)}let e=n!==void 0?b.createElement(jt.Provider,{value:this.props.routeContext},b.createElement(rh.Provider,{value:n,children:this.props.component})):this.props.children;return this.context?b.createElement(zy,{error:n},e):e}};cm.contextType=nm;var Ja=new WeakMap;function zy({children:n,error:e}){let{basename:t}=b.useContext(mt);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let r=Ny(e.digest);if(r){let i=Ja.get(e);if(i)throw i;let s=_p(r.location,t);if(Wp&&!Ja.get(e))if(s.isExternal||r.reloadDocument)window.location.href=s.absoluteURL||s.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(s.to,{replace:r.replace}));throw Ja.set(e,o),o}return b.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return n}function Hy({routeContext:n,match:e,children:t}){let r=b.useContext(ir);return r&&r.static&&r.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=e.route.id),b.createElement(jt.Provider,{value:n},t)}function Wy(n,e=[],t=null,r=null,i=null){if(n==null){if(!t)return null;if(t.errors)n=t.matches;else if(e.length===0&&!t.initialized&&t.matches.length>0)n=t.matches;else return null}let s=n,o=t?.errors;if(o!=null){let h=s.findIndex(d=>d.route.id&&o?.[d.route.id]!==void 0);he(h>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,h+1))}let a=!1,l=-1;if(t)for(let h=0;h<s.length;h++){let d=s[h];if((d.route.HydrateFallback||d.route.hydrateFallbackElement)&&(l=h),d.route.id){let{loaderData:f,errors:p}=t,m=d.route.loader&&!f.hasOwnProperty(d.route.id)&&(!p||p[d.route.id]===void 0);if(d.route.lazy||m){a=!0,l>=0?s=s.slice(0,l+1):s=[s[0]];break}}}let c=t&&r?(h,d)=>{r(h,{location:t.location,params:t.matches?.[0]?.params??{},unstable_pattern:Ms(t.matches),errorInfo:d})}:void 0;return s.reduceRight((h,d,f)=>{let p,m=!1,g=null,y=null;t&&(p=o&&d.route.id?o[d.route.id]:void 0,g=d.route.errorElement||Vy,a&&(l<0&&f===0?(hm("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,y=null):l===f&&(m=!0,y=d.route.hydrateFallbackElement||null)));let v=e.concat(s.slice(0,f+1)),k=()=>{let S;return p?S=g:m?S=y:d.route.Component?S=b.createElement(d.route.Component,null):d.route.element?S=d.route.element:S=h,b.createElement(Hy,{match:d,routeContext:{outlet:h,matches:v,isDataRoute:t!=null},children:S})};return t&&(d.route.ErrorBoundary||d.route.errorElement||f===0)?b.createElement(cm,{location:t.location,revalidation:t.revalidation,component:g,error:p,children:k(),routeContext:{outlet:null,matches:v,isDataRoute:!0},onError:c}):k()},null)}function ih(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function _y(n){let e=b.useContext(ir);return he(e,ih(n)),e}function Uy(n){let e=b.useContext(As);return he(e,ih(n)),e}function Ky(n){let e=b.useContext(jt);return he(e,ih(n)),e}function sh(n){let e=Ky(n),t=e.matches[e.matches.length-1];return he(t.route.id,`${n} can only be used on routes that contain a unique "id"`),t.route.id}function Gy(){return sh("useRouteId")}function qy(){let n=b.useContext(rh),e=Uy("useRouteError"),t=sh("useRouteError");return n!==void 0?n:e.errors?.[t]}function Yy(){let{router:n}=_y("useNavigate"),e=sh("useNavigate"),t=b.useRef(!1);return om(()=>{t.current=!0}),b.useCallback(async(i,s={})=>{Te(t.current,sm),t.current&&(typeof i=="number"?await n.navigate(i):await n.navigate(i,{fromRouteId:e,...s}))},[n,e])}var Iu={};function hm(n,e,t){!e&&!Iu[n]&&(Iu[n]=!0,Te(!1,t))}var Bu={};function $u(n,e){!n&&!Bu[e]&&(Bu[e]=!0,console.warn(e))}var Qy="useOptimistic",Fu=c1[Qy],Jy=()=>{};function Xy(n){return Fu?Fu(n):[n,Jy]}function Zy(n){let e={hasErrorBoundary:n.hasErrorBoundary||n.ErrorBoundary!=null||n.errorElement!=null};return n.Component&&(n.element&&Te(!1,"You should not include both `Component` and `element` on your route - `Component` will be used."),Object.assign(e,{element:b.createElement(n.Component),Component:void 0})),n.HydrateFallback&&(n.hydrateFallbackElement&&Te(!1,"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."),Object.assign(e,{hydrateFallbackElement:b.createElement(n.HydrateFallback),HydrateFallback:void 0})),n.ErrorBoundary&&(n.errorElement&&Te(!1,"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."),Object.assign(e,{errorElement:b.createElement(n.ErrorBoundary),ErrorBoundary:void 0})),e}var ex=["HydrateFallback","hydrateFallbackElement"],tx=class{constructor(){this.status="pending",this.promise=new Promise((n,e)=>{this.resolve=t=>{this.status==="pending"&&(this.status="resolved",n(t))},this.reject=t=>{this.status==="pending"&&(this.status="rejected",e(t))}})}};function nx({router:n,flushSync:e,onError:t,unstable_useTransitions:r}){r=My()||r;let[s,o]=b.useState(n.state),[a,l]=Xy(s),[c,h]=b.useState(),[d,f]=b.useState({isTransitioning:!1}),[p,m]=b.useState(),[g,y]=b.useState(),[v,k]=b.useState(),S=b.useRef(new Map),P=b.useCallback((D,{deletedFetchers:T,newErrors:R,flushSync:L,viewTransitionOpts:$})=>{R&&t&&Object.values(R).forEach(_=>t(_,{location:D.location,params:D.matches[0]?.params??{},unstable_pattern:Ms(D.matches)})),D.fetchers.forEach((_,V)=>{_.data!==void 0&&S.current.set(V,_.data)}),T.forEach(_=>S.current.delete(_)),$u(L===!1||e!=null,'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.');let U=n.window!=null&&n.window.document!=null&&typeof n.window.document.startViewTransition=="function";if($u($==null||U,"You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available."),!$||!U){e&&L?e(()=>o(D)):r===!1?o(D):b.startTransition(()=>{r===!0&&l(_=>Vu(_,D)),o(D)});return}if(e&&L){e(()=>{g&&(p?.resolve(),g.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:$.currentLocation,nextLocation:$.nextLocation})});let _=n.window.document.startViewTransition(()=>{e(()=>o(D))});_.finished.finally(()=>{e(()=>{m(void 0),y(void 0),h(void 0),f({isTransitioning:!1})})}),e(()=>y(_));return}g?(p?.resolve(),g.skipTransition(),k({state:D,currentLocation:$.currentLocation,nextLocation:$.nextLocation})):(h(D),f({isTransitioning:!0,flushSync:!1,currentLocation:$.currentLocation,nextLocation:$.nextLocation}))},[n.window,e,g,p,r,l,t]);b.useLayoutEffect(()=>n.subscribe(P),[n,P]),b.useEffect(()=>{d.isTransitioning&&!d.flushSync&&m(new tx)},[d]),b.useEffect(()=>{if(p&&c&&n.window){let D=c,T=p.promise,R=n.window.document.startViewTransition(async()=>{r===!1?o(D):b.startTransition(()=>{r===!0&&l(L=>Vu(L,D)),o(D)}),await T});R.finished.finally(()=>{m(void 0),y(void 0),h(void 0),f({isTransitioning:!1})}),y(R)}},[c,p,n.window,r,l]),b.useEffect(()=>{p&&c&&a.location.key===c.location.key&&p.resolve()},[p,g,a.location,c]),b.useEffect(()=>{!d.isTransitioning&&v&&(h(v.state),f({isTransitioning:!0,flushSync:!1,currentLocation:v.currentLocation,nextLocation:v.nextLocation}),k(void 0))},[d.isTransitioning,v]);let O=b.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:D=>n.navigate(D),push:(D,T,R)=>n.navigate(D,{state:T,preventScrollReset:R?.preventScrollReset}),replace:(D,T,R)=>n.navigate(D,{replace:!0,state:T,preventScrollReset:R?.preventScrollReset})}),[n]),M=n.basename||"/",x=b.useMemo(()=>({router:n,navigator:O,static:!1,basename:M,onError:t}),[n,O,M,t]);return b.createElement(b.Fragment,null,b.createElement(ir.Provider,{value:x},b.createElement(As.Provider,{value:a},b.createElement(rm.Provider,{value:S.current},b.createElement(nh.Provider,{value:d},b.createElement(ox,{basename:M,location:a.location,navigationType:a.historyAction,navigator:O,unstable_useTransitions:r},b.createElement(rx,{routes:n.routes,future:n.future,state:a,onError:t})))))),null)}function Vu(n,e){return{...n,navigation:e.navigation.state!=="idle"?e.navigation:n.navigation,revalidation:e.revalidation!=="idle"?e.revalidation:n.revalidation,actionData:e.navigation.state!=="submitting"?e.actionData:n.actionData,fetchers:e.fetchers}}var rx=b.memo(ix);function ix({routes:n,future:e,state:t,onError:r}){return $y(n,void 0,t,r,e)}function Xa({to:n,replace:e,state:t,relative:r}){he(Lr(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=b.useContext(mt);Te(!i,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:s}=b.useContext(jt),{pathname:o}=Qt(),a=fn(),l=wa(n,va(s),o,r==="path"),c=JSON.stringify(l);return b.useEffect(()=>{a(JSON.parse(c),{replace:e,state:t,relative:r})},[a,c,r,e,t]),null}function sx(n){return By(n.context)}function ox({basename:n="/",children:e=null,location:t,navigationType:r="POP",navigator:i,static:s=!1,unstable_useTransitions:o}){he(!Lr(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let a=n.replace(/^\/*/,"/"),l=b.useMemo(()=>({basename:a,navigator:i,static:s,unstable_useTransitions:o,future:{}}),[a,i,s,o]);typeof t=="string"&&(t=Rn(t));let{pathname:c="/",search:h="",hash:d="",state:f=null,key:p="default"}=t,m=b.useMemo(()=>{let g=Ct(c,a);return g==null?null:{location:{pathname:g,search:h,hash:d,state:f,key:p},navigationType:r}},[a,c,h,d,f,p,r]);return Te(m!=null,`<Router basename="${a}"> is not able to match the URL "${c}${h}${d}" because it does not start with the basename, so the <Router> won't render anything.`),m==null?null:b.createElement(mt.Provider,{value:l},b.createElement(ka.Provider,{children:e,value:m}))}var No="get",Eo="application/x-www-form-urlencoded";function Sa(n){return typeof HTMLElement<"u"&&n instanceof HTMLElement}function ax(n){return Sa(n)&&n.tagName.toLowerCase()==="button"}function lx(n){return Sa(n)&&n.tagName.toLowerCase()==="form"}function cx(n){return Sa(n)&&n.tagName.toLowerCase()==="input"}function hx(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function ux(n,e){return n.button===0&&(!e||e==="_self")&&!hx(n)}var eo=null;function dx(){if(eo===null)try{new FormData(document.createElement("form"),0),eo=!1}catch{eo=!0}return eo}var fx=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Za(n){return n!=null&&!fx.has(n)?(Te(!1,`"${n}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Eo}"`),null):n}function px(n,e){let t,r,i,s,o;if(lx(n)){let a=n.getAttribute("action");r=a?Ct(a,e):null,t=n.getAttribute("method")||No,i=Za(n.getAttribute("enctype"))||Eo,s=new FormData(n)}else if(ax(n)||cx(n)&&(n.type==="submit"||n.type==="image")){let a=n.form;if(a==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let l=n.getAttribute("formaction")||a.getAttribute("action");if(r=l?Ct(l,e):null,t=n.getAttribute("formmethod")||a.getAttribute("method")||No,i=Za(n.getAttribute("formenctype"))||Za(a.getAttribute("enctype"))||Eo,s=new FormData(a,n),!dx()){let{name:c,type:h,value:d}=n;if(h==="image"){let f=c?`${c}.`:"";s.append(`${f}x`,"0"),s.append(`${f}y`,"0")}else c&&s.append(c,d)}}else{if(Sa(n))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');t=No,r=null,i=Eo,o=n}return s&&i==="text/plain"&&(o=s,s=void 0),{action:r,method:t.toLowerCase(),encType:i,formData:s,body:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oh(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function mx(n,e,t){let r=typeof n=="string"?new URL(n,typeof window>"u"?"server://singlefetch/":window.location.origin):n;return r.pathname==="/"?r.pathname=`_root.${t}`:e&&Ct(r.pathname,e)==="/"?r.pathname=`${e.replace(/\/$/,"")}/_root.${t}`:r.pathname=`${r.pathname.replace(/\/$/,"")}.${t}`,r}async function gx(n,e){if(n.id in e)return e[n.id];try{let t=await import(n.module);return e[n.id]=t,t}catch(t){return console.error(`Error loading route module \`${n.module}\`, reloading page...`),console.error(t),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function bx(n){return n==null?!1:n.href==null?n.rel==="preload"&&typeof n.imageSrcSet=="string"&&typeof n.imageSizes=="string":typeof n.rel=="string"&&typeof n.href=="string"}async function yx(n,e,t){let r=await Promise.all(n.map(async i=>{let s=e.routes[i.route.id];if(s){let o=await gx(s,t);return o.links?o.links():[]}return[]}));return kx(r.flat(1).filter(bx).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function zu(n,e,t,r,i,s){let o=(l,c)=>t[c]?l.route.id!==t[c].route.id:!0,a=(l,c)=>t[c].pathname!==l.pathname||t[c].route.path?.endsWith("*")&&t[c].params["*"]!==l.params["*"];return s==="assets"?e.filter((l,c)=>o(l,c)||a(l,c)):s==="data"?e.filter((l,c)=>{let h=r.routes[l.route.id];if(!h||!h.hasLoader)return!1;if(o(l,c)||a(l,c))return!0;if(l.route.shouldRevalidate){let d=l.route.shouldRevalidate({currentUrl:new URL(i.pathname+i.search+i.hash,window.origin),currentParams:t[0]?.params||{},nextUrl:new URL(n,window.origin),nextParams:l.params,defaultShouldRevalidate:!0});if(typeof d=="boolean")return d}return!0}):[]}function xx(n,e,{includeHydrateFallback:t}={}){return vx(n.map(r=>{let i=e.routes[r.route.id];if(!i)return[];let s=[i.module];return i.clientActionModule&&(s=s.concat(i.clientActionModule)),i.clientLoaderModule&&(s=s.concat(i.clientLoaderModule)),t&&i.hydrateFallbackModule&&(s=s.concat(i.hydrateFallbackModule)),i.imports&&(s=s.concat(i.imports)),s}).flat(1))}function vx(n){return[...new Set(n)]}function wx(n){let e={},t=Object.keys(n).sort();for(let r of t)e[r]=n[r];return e}function kx(n,e){let t=new Set;return new Set(e),n.reduce((r,i)=>{let s=JSON.stringify(wx(i));return t.has(s)||(t.add(s),r.push({key:s,link:i})),r},[])}function um(){let n=b.useContext(ir);return oh(n,"You must render this element inside a <DataRouterContext.Provider> element"),n}function Sx(){let n=b.useContext(As);return oh(n,"You must render this element inside a <DataRouterStateContext.Provider> element"),n}var ah=b.createContext(void 0);ah.displayName="FrameworkContext";function dm(){let n=b.useContext(ah);return oh(n,"You must render this element inside a <HydratedRouter> element"),n}function Cx(n,e){let t=b.useContext(ah),[r,i]=b.useState(!1),[s,o]=b.useState(!1),{onFocus:a,onBlur:l,onMouseEnter:c,onMouseLeave:h,onTouchStart:d}=e,f=b.useRef(null);b.useEffect(()=>{if(n==="render"&&o(!0),n==="viewport"){let g=v=>{v.forEach(k=>{o(k.isIntersecting)})},y=new IntersectionObserver(g,{threshold:.5});return f.current&&y.observe(f.current),()=>{y.disconnect()}}},[n]),b.useEffect(()=>{if(r){let g=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(g)}}},[r]);let p=()=>{i(!0)},m=()=>{i(!1),o(!1)};return t?n!=="intent"?[s,f,{}]:[s,f,{onFocus:Xr(a,p),onBlur:Xr(l,m),onMouseEnter:Xr(c,p),onMouseLeave:Xr(h,m),onTouchStart:Xr(d,p)}]:[!1,f,{}]}function Xr(n,e){return t=>{n&&n(t),t.defaultPrevented||e(t)}}function Ox({page:n,...e}){let{router:t}=um(),r=b.useMemo(()=>xn(t.routes,n,t.basename),[t.routes,n,t.basename]);return r?b.createElement(Px,{page:n,matches:r,...e}):null}function jx(n){let{manifest:e,routeModules:t}=dm(),[r,i]=b.useState([]);return b.useEffect(()=>{let s=!1;return yx(n,e,t).then(o=>{s||i(o)}),()=>{s=!0}},[n,e,t]),r}function Px({page:n,matches:e,...t}){let r=Qt(),{manifest:i,routeModules:s}=dm(),{basename:o}=um(),{loaderData:a,matches:l}=Sx(),c=b.useMemo(()=>zu(n,e,l,i,r,"data"),[n,e,l,i,r]),h=b.useMemo(()=>zu(n,e,l,i,r,"assets"),[n,e,l,i,r]),d=b.useMemo(()=>{if(n===r.pathname+r.search+r.hash)return[];let m=new Set,g=!1;if(e.forEach(v=>{let k=i.routes[v.route.id];!k||!k.hasLoader||(!c.some(S=>S.route.id===v.route.id)&&v.route.id in a&&s[v.route.id]?.shouldRevalidate||k.hasClientLoader?g=!0:m.add(v.route.id))}),m.size===0)return[];let y=mx(n,o,"data");return g&&m.size>0&&y.searchParams.set("_routes",e.filter(v=>m.has(v.route.id)).map(v=>v.route.id).join(",")),[y.pathname+y.search]},[o,a,r,i,c,e,n,s]),f=b.useMemo(()=>xx(h,i),[h,i]),p=jx(h);return b.createElement(b.Fragment,null,d.map(m=>b.createElement("link",{key:m,rel:"prefetch",as:"fetch",href:m,...t})),f.map(m=>b.createElement("link",{key:m,rel:"modulepreload",href:m,...t})),p.map(({key:m,link:g})=>b.createElement("link",{key:m,nonce:t.nonce,...g})))}function Mx(...n){return e=>{n.forEach(t=>{typeof t=="function"?t(e):t!=null&&(t.current=e)})}}var Ax=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{Ax&&(window.__reactRouterVersion="7.11.0")}catch{}function Dx(n,e){return ry({basename:e?.basename,getContext:e?.getContext,future:e?.future,history:x1({window:e?.window}),hydrationData:Tx(),routes:n,mapRouteProperties:Zy,hydrationRouteProperties:ex,dataStrategy:e?.dataStrategy,patchRoutesOnNavigation:e?.patchRoutesOnNavigation,window:e?.window,unstable_instrumentations:e?.unstable_instrumentations}).initialize()}function Tx(){let n=window?.__staticRouterHydrationData;return n&&n.errors&&(n={...n,errors:Nx(n.errors)}),n}function Nx(n){if(!n)return null;let e=Object.entries(n),t={};for(let[r,i]of e)if(i&&i.__type==="RouteErrorResponse")t[r]=new Ps(i.status,i.statusText,i.data,i.internal===!0);else if(i&&i.__type==="Error"){if(i.__subType){let s=window[i.__subType];if(typeof s=="function")try{let o=new s(i.message);o.stack="",t[r]=o}catch{}}if(t[r]==null){let s=new Error(i.message);s.stack="",t[r]=s}}else t[r]=i;return t}var fm=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,pm=b.forwardRef(function({onClick:e,discover:t="render",prefetch:r="none",relative:i,reloadDocument:s,replace:o,state:a,target:l,to:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f,...p},m){let{basename:g,unstable_useTransitions:y}=b.useContext(mt),v=typeof c=="string"&&fm.test(c),k=_p(c,g);c=k.to;let S=Ry(c,{relative:i}),[P,O,M]=Cx(r,p),x=Ix(c,{replace:o,state:a,target:l,preventScrollReset:h,relative:i,viewTransition:d,unstable_defaultShouldRevalidate:f,unstable_useTransitions:y});function D(R){e&&e(R),R.defaultPrevented||x(R)}let T=b.createElement("a",{...p,...M,href:k.absoluteURL||S,onClick:k.isExternal||s?e:D,ref:Mx(m,O),target:l,"data-discover":!v&&t==="render"?"true":void 0});return P&&!v?b.createElement(b.Fragment,null,T,b.createElement(Ox,{page:S})):T});pm.displayName="Link";var Ex=b.forwardRef(function({"aria-current":e="page",caseSensitive:t=!1,className:r="",end:i=!1,style:s,to:o,viewTransition:a,children:l,...c},h){let d=Ds(o,{relative:c.relative}),f=Qt(),p=b.useContext(As),{navigator:m,basename:g}=b.useContext(mt),y=p!=null&&zx(d)&&a===!0,v=m.encodeLocation?m.encodeLocation(d).pathname:d.pathname,k=f.pathname,S=p&&p.navigation&&p.navigation.location?p.navigation.location.pathname:null;t||(k=k.toLowerCase(),S=S?S.toLowerCase():null,v=v.toLowerCase()),S&&g&&(S=Ct(S,g)||S);const P=v!=="/"&&v.endsWith("/")?v.length-1:v.length;let O=k===v||!i&&k.startsWith(v)&&k.charAt(P)==="/",M=S!=null&&(S===v||!i&&S.startsWith(v)&&S.charAt(v.length)==="/"),x={isActive:O,isPending:M,isTransitioning:y},D=O?e:void 0,T;typeof r=="function"?T=r(x):T=[r,O?"active":null,M?"pending":null,y?"transitioning":null].filter(Boolean).join(" ");let R=typeof s=="function"?s(x):s;return b.createElement(pm,{...c,"aria-current":D,className:T,ref:h,style:R,to:o,viewTransition:a},typeof l=="function"?l(x):l)});Ex.displayName="NavLink";var Rx=b.forwardRef(({discover:n="render",fetcherKey:e,navigate:t,reloadDocument:r,replace:i,state:s,method:o=No,action:a,onSubmit:l,relative:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f,...p},m)=>{let{unstable_useTransitions:g}=b.useContext(mt),y=Fx(),v=Vx(a,{relative:c}),k=o.toLowerCase()==="get"?"get":"post",S=typeof a=="string"&&fm.test(a),P=O=>{if(l&&l(O),O.defaultPrevented)return;O.preventDefault();let M=O.nativeEvent.submitter,x=M?.getAttribute("formmethod")||o,D=()=>y(M||O.currentTarget,{fetcherKey:e,method:x,navigate:t,replace:i,state:s,relative:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f});g&&t!==!1?b.startTransition(()=>D()):D()};return b.createElement("form",{ref:m,method:k,action:v,onSubmit:r?l:P,...p,"data-discover":!S&&n==="render"?"true":void 0})});Rx.displayName="Form";function Lx(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function mm(n){let e=b.useContext(ir);return he(e,Lx(n)),e}function Ix(n,{target:e,replace:t,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a,unstable_useTransitions:l}={}){let c=fn(),h=Qt(),d=Ds(n,{relative:s});return b.useCallback(f=>{if(ux(f,e)){f.preventDefault();let p=t!==void 0?t:Yt(h)===Yt(d),m=()=>c(n,{replace:p,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a});l?b.startTransition(()=>m()):m()}},[h,c,d,t,r,e,n,i,s,o,a,l])}var Bx=0,$x=()=>`__${String(++Bx)}__`;function Fx(){let{router:n}=mm("useSubmit"),{basename:e}=b.useContext(mt),t=Gy(),r=n.fetch,i=n.navigate;return b.useCallback(async(s,o={})=>{let{action:a,method:l,encType:c,formData:h,body:d}=px(s,e);if(o.navigate===!1){let f=o.fetcherKey||$x();await r(f,t,o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:h,body:d,formMethod:o.method||l,formEncType:o.encType||c,flushSync:o.flushSync})}else await i(o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:h,body:d,formMethod:o.method||l,formEncType:o.encType||c,replace:o.replace,state:o.state,fromRouteId:t,flushSync:o.flushSync,viewTransition:o.viewTransition})},[r,i,e,t])}function Vx(n,{relative:e}={}){let{basename:t}=b.useContext(mt),r=b.useContext(jt);he(r,"useFormAction must be used inside a RouteContext");let[i]=r.matches.slice(-1),s={...Ds(n||".",{relative:e})},o=Qt();if(n==null){s.search=o.search;let a=new URLSearchParams(s.search),l=a.getAll("index");if(l.some(h=>h==="")){a.delete("index"),l.filter(d=>d).forEach(d=>a.append("index",d));let h=a.toString();s.search=h?`?${h}`:""}}return(!n||n===".")&&i.route.index&&(s.search=s.search?s.search.replace(/^\?/,"?index&"):"?index"),t!=="/"&&(s.pathname=s.pathname==="/"?t:Gt([t,s.pathname])),Yt(s)}function zx(n,{relative:e}={}){let t=b.useContext(nh);he(t!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=mm("useViewTransitionState"),i=Ds(n,{relative:e});if(!t.isTransitioning)return!1;let s=Ct(t.currentLocation.pathname,r)||t.currentLocation.pathname,o=Ct(t.nextLocation.pathname,r)||t.nextLocation.pathname;return _o(i.pathname,o)!=null||_o(i.pathname,s)!=null}function Hx(n){return b.createElement(nx,{flushSync:Rp.flushSync,...n})}const Wx={en:{loading:"Loading...",error:"Error",selectProject:"Select a project to view dashboard",controlCenter:"Control Center",settings:"Settings",sync:"Sync",offline:"Offline",switchToLight:"Switch to light mode",switchToDark:"Switch to dark mode",settingsSection:"Settings",configEditor:"Config Editor",projects:"Projects",addProject:"Add Project",global:"Global",skills:"Skills",health:"Health",collapse:"Collapse",expand:"Expand",installing:"Installing...",manage:"Manage",uninstall:"Uninstall",installGlobally:"Install Globally",installGloballyDesc:"Available to all projects instead of current project only",selectAtLeastOneAgent:"Please select at least one agent",installationFailed:"Installation failed",allSkills:"All Skills",refresh:"Refresh",browseAndManageSkills:"Browse and manage skills for your agents",detected:"Detected",notDetected:"Not detected",sessions:"sessions",noSessions:"No sessions",terminal:"Terminal",terminalSub:"Open bash at path",editor:"Editor",editorSub:"Open in VS Code",launch:"Launch",launchSub:"Start Claude Code",config:"Config",configSub:"Manage project settings",recentSessions:"Recent Sessions",viewAllHistory:"View All History",showLess:"Show Less",actionFailed:"Action failed",loadingSessions:"Loading sessions...",noSessionsFound:"No sessions found",configuration:"Claude Settings",activeKit:"Active Kit",aiModel:"Model",hooks:"Hooks",active:"active",mcpServers:"MCP Servers",connected:"connected",editProjectConfig:"Edit Project Config",globalSettings:"(Global)",globalSkills:"Global Skills",loadingSkills:"Loading skills...",noDescription:"No description",browseSkillsMarketplace:"Browse Skills Marketplace",backToDashboard:"Back to Dashboard",educationalConfigEditor:"Educational Config Editor",discard:"Discard",saveChanges:"Save Changes",mergedView:"Merged View",localConfig:"Local (.ck.json)",globalConfig:"Global",syntaxValid:"Syntax Valid",configurationHelp:"Configuration Help",field:"Field",type:"Type",default:"Default",description:"Description",validValues:"Valid Values",systemEffect:"System Effect",exampleUsage:"Example Usage",knowledgeBase:"Knowledge Base",clickToSeeHelp:"Click on any configuration field to see detailed documentation and usage examples.",extractedFrom:"Extracted from ClaudeKit v2.x Specification",resetToDefault:"Reset",saving:"Saving...",saved:"Saved",confirmReset:"Reset to Default?",confirmResetMessage:"All changes will be lost and replaced with default values.",confirm:"Confirm",saveFailed:"Save failed",configTab:"Config",systemTab:"System",formTab:"Form",jsonTab:"JSON",installedKit:"Installed Kit",kitVersion:"Kit Version",installedOn:"Installed On",noKitInstalled:"No kit installed",components:"Components",agents:"Agents",commands:"Commands",workflows:"Workflows",kitSkills:"Skills",fileOwnership:"File Ownership",ownershipCk:"kit-managed",ownershipUser:"user-owned",ownershipModified:"modified",componentInventory:"Component Inventory",installedHooks:"Installed Hooks",installedMcpServers:"MCP Servers",lastChecked:"Last update check",staleIndicator:"Stale",skippedVersion:"Skipped",filesModifiedFromDefaults:"files modified from kit defaults",cliCard:"ClaudeKit CLI",checkForUpdates:"Check for Updates",checking:"Checking...",upToDate:"Up to date",updateAvailable:"Update available",updateNow:"Update Now",updating:"Updating...",updateSuccess:"Update Complete!",updateFailed:"Update Failed",closeModal:"Close",showDetails:"Show Details",hideDetails:"Hide Details",environment:"Environment",claudeConfigPath:"Claude config",nodeVersion:"Node",bunVersion:"Bun",osVersion:"OS",channelStable:"Stable",channelBeta:"Beta",betaBadge:"Beta",latestVersion:"Latest",selectVersion:"Select version",loadingVersions:"Loading versions...",prereleaseLabel:"Pre",currentVersionLabel:"Current",checkAll:"Check All",checkingAll:"Checking...",updateAll:"Update All",updatesAvailable:"{count} updates available",allUpToDate:"All up to date",systemControlTower:"System Control Tower",systemOverviewTitle:"Update & Runtime Overview",systemOverviewDesc:"Track CLI and kit health, then run upgrades from one place.",installedComponentsHeading:"Installed Components",updateReadiness:"Update Readiness",checkedComponents:"Checked",activeChannel:"Channel",readyToScan:"Ready to scan",noTrackedFiles:"No tracked files detected",kitsLabel:"Kits",componentFilterAll:"All",componentFilterUpdates:"Updates",componentFilterUpToDate:"Up to date",componentFilterCli:"CLI",componentFilterKits:"Kits",noComponentsMatchFilter:"No components match the current filter.",configWorkspaceHint:"Edit configuration or manage system updates from one workspace.",addProjectTitle:"Add Project",addProjectDescription:"Add a new ClaudeKit project to the control center",projectPath:"Project Path",pathPlaceholder:"/path/to/project",alias:"Alias",aliasOptional:"(optional)",aliasPlaceholder:"my-project",aliasDescription:"Custom display name for the project",pathRequired:"Path is required",failedToAdd:"Failed to add project",cancel:"Cancel",adding:"Adding...",somethingWentWrong:"Something went wrong",reloadApp:"Reload App",serverNotRunning:"Server Not Running",startServerMessage:"The Config UI requires the backend server to be running.",runThisCommand:"Run this command",tryAgain:"Try Again",projectConfig:"Project Config",inheritedFromGlobal:"Inherited from Global",localOverride:"Local Override",viewGlobalConfig:"This field inherits from global config. View",onboardingTitle:"Welcome to ClaudeKit",onboardingSubtitle:"Choose your kit and get started in minutes",kitEngineerName:"ClaudeKit Engineer",kitEngineerTagline:"AI-powered coding with skills, hooks, and multi-agent workflows",kitMarketingName:"ClaudeKit Marketing",kitMarketingTagline:"Content automation: campaigns, social media, analytics",featureAgents:"AI Agents",featureAgentsDesc:"Specialized agents for different tasks",featureHooks:"Lifecycle Hooks",featureHooksDesc:"Customize Claude's behavior at key moments",featureSkills:"Skills Library",featureSkillsDesc:"Pre-built capabilities you can activate",featureMultiAgent:"Multi-Agent Workflows",featureMultiAgentDesc:"Coordinate multiple agents for complex tasks",featureContent:"Content Generation",featureContentDesc:"Automated content creation and optimization",featureSocial:"Social Media Tools",featureSocialDesc:"Scheduling, analytics, and engagement automation",stepChooseKit:"Choose Kit",stepConfigure:"Configure",stepInstall:"Install",back:"Back",next:"Next",install:"Install",installSuccess:"Installation Complete!",installSuccessDesc:"{kit} is ready to use",getStarted:"Get Started",goToDashboard:"Go to Dashboard",kitConfig:"Kit Config",kitConfigSubtitle:"Configure ClaudeKit Engineer settings",scopeGlobal:"Global",scopeProject:"Project",sectionGeneral:"General",sectionPaths:"Paths",sectionPrivacy:"Privacy & Trust",sectionProject:"Project Detection",sectionIntegrations:"Integrations",sectionHooks:"Hooks",sectionAdvanced:"Advanced",fieldCodingLevel:"Coding Level",fieldCodingLevelDesc:"Your coding experience level (-1=auto, 0=beginner, 1=intermediate, 2=advanced, 3=expert, 4=tech-lead, 5=god-mode)",fieldStatusline:"Statusline Mode",fieldStatuslineDesc:"How much info to show in the status line",fieldThinkingLanguage:"Thinking Language",fieldThinkingLanguageDesc:"Language for Claude's internal reasoning (null=English)",fieldResponseLanguage:"Response Language",fieldResponseLanguageDesc:"Language for Claude's responses (null=match user)",fieldDocsPath:"Docs Directory",fieldDocsPathDesc:"Path to documentation directory",fieldPlansPath:"Plans Directory",fieldPlansPathDesc:"Path to plans directory",fieldPrivacyBlock:"Privacy Block",fieldPrivacyBlockDesc:"Block access to sensitive files (.env, credentials)",fieldTrustEnabled:"Trust Mode",fieldTrustEnabledDesc:"Enable auto-approval for tool calls",fieldTrustPassphrase:"Trust Passphrase",fieldTrustPassphraseDesc:"Passphrase to enable trust mode",fieldProjectType:"Project Type",fieldProjectTypeDesc:"Override auto-detected project type",fieldPackageManager:"Package Manager",fieldPackageManagerDesc:"Override auto-detected package manager",fieldFramework:"Framework",fieldFrameworkDesc:"Override auto-detected framework",fieldGeminiModel:"Gemini Model",fieldGeminiModelDesc:"Gemini model for CLI commands",fieldResearchUseGemini:"Use Gemini for Research",fieldResearchUseGeminiDesc:"Use Gemini CLI instead of WebSearch",fieldDocsMaxLoc:"Max Lines per Doc",fieldDocsMaxLocDesc:"Maximum lines of code per documentation file",fieldPlanNamingFormat:"Plan Naming Format",fieldPlanNamingFormatDesc:"Format for plan directory names",fieldPlanDateFormat:"Plan Date Format",fieldPlanDateFormatDesc:"Date format for plan names (moment.js)",fieldPlanValidationMode:"Validation Mode",fieldPlanValidationModeDesc:"How to validate plans before implementation",fieldPlanMinQuestions:"Min Questions",fieldPlanMinQuestionsDesc:"Minimum validation questions",fieldPlanMaxQuestions:"Max Questions",fieldPlanMaxQuestionsDesc:"Maximum validation questions",fieldAssertions:"Assertions",fieldAssertionsDesc:"Code assertions and rules to enforce",fieldHookSessionInit:"Session Init",fieldHookSessionInitDesc:"Project detection and environment setup",fieldHookSubagentInit:"Subagent Init",fieldHookSubagentInitDesc:"Inject context to subagents",fieldHookDescriptiveName:"Descriptive Name",fieldHookDescriptiveNameDesc:"Enforce kebab-case descriptive file naming for scripts",fieldHookDevRulesReminder:"Dev Rules Reminder",fieldHookDevRulesReminderDesc:"Inject development rules context",fieldHookUsageContextAwareness:"Usage Context Awareness",fieldHookUsageContextAwarenessDesc:"Usage limits awareness",fieldHookContextTracking:"Context Tracking",fieldHookContextTrackingDesc:"Context window tracking (% used, token counts)",fieldHookScoutBlock:"Scout Block",fieldHookScoutBlockDesc:"Block heavy directories from exploration",fieldHookPrivacyBlock:"Privacy Block Hook",fieldHookPrivacyBlockDesc:"Block sensitive files from reading",fieldHookPostEditSimplify:"Post-Edit Simplify",fieldHookPostEditSimplifyDesc:"Simplify reminder after edits",skillsPageTitle:"Skills Management",skillsPageDesc:"Install ClaudeKit skills to your coding agents",availableSkills:"Available Skills",installedSkills:"Installed Skills",noSkillsFound:"No skills found",installSkill:"Install",uninstallSkill:"Uninstall",manageSkill:"Manage",syncRegistry:"Sync",installSkillTitle:"Install Skill",selectAgents:"Select target agents",installLocation:"Installation location",globalInstall:"Global",projectInstall:"Project",confirmInstall:"Install to selected agents",installingSkill:"Installing...",skillInstallSuccess:"Skill installed successfully",skillInstallFailed:"Installation failed",agentClaudeCode:"Claude Code",agentCursor:"Cursor",agentCodex:"Codex",agentOpencode:"OpenCode",agentGoose:"Goose",agentGeminiCli:"Gemini CLI",agentAntigravity:"Antigravity",agentGithubCopilot:"GitHub Copilot",agentAmp:"Amp",agentKilo:"Kilo",agentRoo:"Roo",agentWindsurf:"Windsurf",agentCline:"Cline",agentOpenhands:"OpenHands",installed:"Installed",notInstalled:"Not installed",allAgents:"All Agents",filterByAgent:"Filter by agent",skillsTitle:"Skills",skillsSubtitle:"Browse, install, and manage skills for your coding agents",availableCount:"Available",installedCount:"Installed",agentsCount:"Agents",searchSkills:"Search skills...",searchShortcut:"/",sortAZ:"A-Z",sortCategory:"Category",sortInstalledFirst:"Installed first",listView:"List view",gridView:"Grid view",categoryAll:"All",categoryAI:"AI",categoryUIUX:"UI/UX",categoryBackend:"Backend",categorySecurity:"Security",categoryDevOps:"DevOps",categoryDatabase:"Database",categoryDevelopment:"Development",categoryResearch:"Research",categoryGeneral:"General",categoryCore:"Core",categoryDocumentation:"Documentation",categoryTooling:"Tooling",categoryMedia:"Media",categoryFrameworks:"Frameworks",skillsCountLabel:"{count} skills",installToAll:"Install to All Detected",scopeLabel:"Installation Scope",agentInstalled:"Installed",agentNotInstalled:"Not installed",skillSource:"Source location",skillSourceBadge:"Source",detailPanelClose:"Close",versionLabel:"v{version}",installAllToAllAgents:"Install All to All Agents",bulkInstallFailed:"Bulk install failed",noAgentsDetected:"No agents detected",kitBadgeEngineer:"Engineer",kitBadgeMarketing:"Marketing",customizedBadge:"Customized",installedVersionLabel:"Installed Version",installedAtLabel:"Installed At",sourceTimestampLabel:"Source Date",kitLabel:"Kit",skillMetadata:"Skill Info",migrate:"Migrate",migrateTitle:"Migrate",migrateSubtitle:"Port your Claude Code stack to other providers",migrateDetectedProviders:"Detected",migrateSelectedProviders:"Selected",migrateDiscovering:"Discovering migration sources...",migrateRefresh:"Refresh Discovery",migrateRun:"Run Migration",migrateRunning:"Migrating...",migrateSourceSummary:"Source Summary",migratePresetCodex:"Codex",migratePresetAntigravity:"Antigravity",migratePresetBoth:"Codex + Antigravity",migratePresetDetected:"All Detected",migrateScope:"Scope",migrateScopeProject:"Project",migrateScopeGlobal:"Global",migrateTypes:"Portable Types",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateSearchProviders:"Search providers...",migrateSelectVisible:"Select Visible",migrateClearSelection:"Clear Selection",migrateProvidersHeading:"Target Providers",migrateProvidersCountSuffix:"providers",migrateNoProvidersMatch:"No providers match current filters.",migrateSelectButton:"Select",migrateSelectedButton:"Selected",migrateSelectProviderAction:"Select Provider",migrateUnselectProvider:"Unselect Provider",migrateCapabilitiesLabel:"types",migrateCapabilitiesSection:"Capability Matrix",migrateSupported:"Supported",migrateUnsupportedShort:"Unsupported",migrateIncludedEnabled:"Enabled",migrateIncludedDisabled:"Disabled",migrateLatestTarget:"Latest Target",migrateNoResultForProvider:"No migration result for this provider yet.",migrateActionSummaryTitle:"Ready to Migrate",migrateGlobalOnlyCommandsShort:"Commands global-only",migrateNoProviders:"No providers available.",migrateUnsupported:"Will be skipped (unsupported)",migrateGlobalForced:"Codex commands are global-only. Scope will be forced to global.",migrateResults:"Migration Results",migrateInstalled:"Installed",migrateSkipped:"Skipped",migrateFailed:"Failed",migrateProvider:"Provider",migrateStatus:"Status",migratePath:"Path",migrateError:"Error",migrateStatusInstalled:"Installed",migrateStatusSkipped:"Skipped",migrateStatusFailed:"Failed",migrateNoResults:"No migration results yet.",migrateDetectFailed:"Failed to discover migration data",migrateExecuteFailed:"Migration execution failed",migrateSelectProvider:"Select at least one provider",migrateNoTypesEnabled:"Enable at least one portable type",migrateDetectedTag:"Detected",migrateNotDetectedTag:"Not detected",migrateFilterRecommended:"Recommended",developmentFeature:"Development",betaFeature:"Beta",experimentalFeature:"Experimental"},vi:{loading:"Đang tải...",error:"Lỗi",selectProject:"Chọn dự án để xem bảng điều khiển",controlCenter:"Trung tâm điều khiển",settings:"Cài đặt",sync:"Đồng bộ",offline:"Ngoại tuyến",switchToLight:"Chuyển sang chế độ sáng",switchToDark:"Chuyển sang chế độ tối",settingsSection:"Cài đặt",configEditor:"Trình chỉnh sửa cấu hình",projects:"Dự án",addProject:"Thêm dự án",global:"Toàn cục",skills:"Kỹ năng",health:"Sức khỏe",collapse:"Thu gọn",expand:"Mở rộng",installing:"Đang cài đặt...",manage:"Quản lý",uninstall:"Gỡ cài đặt",installGlobally:"Cài đặt toàn cục",installGloballyDesc:"Khả dụng cho tất cả dự án thay vì chỉ dự án hiện tại",selectAtLeastOneAgent:"Vui lòng chọn ít nhất một agent",installationFailed:"Cài đặt thất bại",allSkills:"Tất cả kỹ năng",refresh:"Làm mới",browseAndManageSkills:"Duyệt và quản lý kỹ năng cho agents của bạn",detected:"Đã phát hiện",notDetected:"Chưa phát hiện",sessions:"phiên",noSessions:"Không có phiên",terminal:"Terminal",terminalSub:"Mở bash tại đường dẫn",editor:"Trình soạn thảo",editorSub:"Mở trong VS Code",launch:"Khởi chạy",launchSub:"Bắt đầu Claude Code",config:"Cấu hình",configSub:"Quản lý cài đặt dự án",recentSessions:"Phiên gần đây",viewAllHistory:"Xem tất cả lịch sử",showLess:"Thu gọn",actionFailed:"Thao tác thất bại",loadingSessions:"Đang tải phiên...",noSessionsFound:"Không tìm thấy phiên nào",configuration:"Cài đặt Claude",activeKit:"Kit hoạt động",aiModel:"Mô hình",hooks:"Hooks",active:"hoạt động",mcpServers:"Máy chủ MCP",connected:"kết nối",editProjectConfig:"Chỉnh sửa cấu hình dự án",globalSettings:"(Toàn cục)",globalSkills:"Kỹ năng toàn cục",loadingSkills:"Đang tải kỹ năng...",noDescription:"Không có mô tả",browseSkillsMarketplace:"Duyệt Skills Marketplace",backToDashboard:"Quay lại bảng điều khiển",educationalConfigEditor:"Trình chỉnh sửa cấu hình hướng dẫn",discard:"Hủy bỏ",saveChanges:"Lưu thay đổi",mergedView:"Chế độ gộp",localConfig:"Cục bộ (.ck.json)",globalConfig:"Toàn cục",syntaxValid:"Cú pháp hợp lệ",configurationHelp:"Hướng dẫn cấu hình",field:"Trường",type:"Kiểu",default:"Mặc định",description:"Mô tả",validValues:"Giá trị hợp lệ",systemEffect:"Hiệu ứng hệ thống",exampleUsage:"Ví dụ sử dụng",knowledgeBase:"Cơ sở kiến thức",clickToSeeHelp:"Nhấp vào bất kỳ trường cấu hình nào để xem tài liệu chi tiết và ví dụ sử dụng.",extractedFrom:"Trích xuất từ ClaudeKit v2.x Specification",resetToDefault:"Đặt lại",saving:"Đang lưu...",saved:"Đã lưu",confirmReset:"Đặt lại về mặc định?",confirmResetMessage:"Tất cả thay đổi sẽ bị mất và được thay thế bằng giá trị mặc định.",confirm:"Xác nhận",saveFailed:"Lưu thất bại",configTab:"Cấu hình",systemTab:"Hệ thống",formTab:"Biểu mẫu",jsonTab:"JSON",installedKit:"Kit đã cài",kitVersion:"Phiên bản Kit",installedOn:"Cài đặt vào",noKitInstalled:"Chưa cài kit",components:"Thành phần",agents:"Agents",commands:"Commands",workflows:"Workflows",kitSkills:"Skills",fileOwnership:"Quyền sở hữu tệp",ownershipCk:"do kit quản lý",ownershipUser:"do người dùng",ownershipModified:"đã chỉnh sửa",componentInventory:"Thành phần đã cài",installedHooks:"Hooks đã cài",installedMcpServers:"MCP Servers",lastChecked:"Kiểm tra cập nhật",staleIndicator:"Cũ",skippedVersion:"Đã bỏ qua",filesModifiedFromDefaults:"tệp đã sửa so với mặc định",cliCard:"ClaudeKit CLI",checkForUpdates:"Kiểm tra cập nhật",checking:"Đang kiểm tra...",upToDate:"Đã cập nhật",updateAvailable:"Có bản cập nhật",updateNow:"Cập nhật ngay",updating:"Đang cập nhật...",updateSuccess:"Cập nhật hoàn tất!",updateFailed:"Cập nhật thất bại",closeModal:"Đóng",showDetails:"Xem chi tiết",hideDetails:"Ẩn chi tiết",environment:"Môi trường",claudeConfigPath:"Cấu hình Claude",nodeVersion:"Node",bunVersion:"Bun",osVersion:"Hệ điều hành",channelStable:"Ổn định",channelBeta:"Beta",betaBadge:"Beta",latestVersion:"Mới nhất",selectVersion:"Chọn phiên bản",loadingVersions:"Đang tải...",prereleaseLabel:"Thử nghiệm",currentVersionLabel:"Hiện tại",checkAll:"Kiểm tra tất cả",checkingAll:"Đang kiểm tra...",updateAll:"Cập nhật tất cả",updatesAvailable:"{count} bản cập nhật",allUpToDate:"Tất cả đã cập nhật",systemControlTower:"Trung tâm hệ thống",systemOverviewTitle:"Tổng quan cập nhật & môi trường",systemOverviewDesc:"Theo dõi CLI và kit, rồi nâng cấp từ một nơi.",installedComponentsHeading:"Thành phần đã cài",updateReadiness:"Mức sẵn sàng cập nhật",checkedComponents:"Đã kiểm tra",activeChannel:"Kênh",readyToScan:"Sẵn sàng kiểm tra",noTrackedFiles:"Không phát hiện tệp theo dõi",kitsLabel:"Kit",componentFilterAll:"Tất cả",componentFilterUpdates:"Bản cập nhật",componentFilterUpToDate:"Đã cập nhật",componentFilterCli:"CLI",componentFilterKits:"Kit",noComponentsMatchFilter:"Không có thành phần phù hợp bộ lọc hiện tại.",configWorkspaceHint:"Chỉnh sửa cấu hình hoặc quản lý cập nhật hệ thống trong một màn hình.",addProjectTitle:"Thêm dự án",addProjectDescription:"Thêm dự án ClaudeKit mới vào trung tâm điều khiển",projectPath:"Đường dẫn dự án",pathPlaceholder:"/đường/dẫn/dự/án",alias:"Bí danh",aliasOptional:"(tùy chọn)",aliasPlaceholder:"dự-án-của-tôi",aliasDescription:"Tên hiển thị tùy chỉnh cho dự án",pathRequired:"Đường dẫn bắt buộc",failedToAdd:"Không thể thêm dự án",cancel:"Hủy",adding:"Đang thêm...",somethingWentWrong:"Đã xảy ra lỗi",reloadApp:"Tải lại ứng dụng",serverNotRunning:"Máy chủ không chạy",startServerMessage:"Config UI yêu cầu máy chủ backend đang chạy.",runThisCommand:"Chạy lệnh này",tryAgain:"Thử lại",projectConfig:"Cấu hình dự án",inheritedFromGlobal:"Kế thừa từ toàn cục",localOverride:"Ghi đè cục bộ",viewGlobalConfig:"Trường này kế thừa từ cấu hình toàn cục. Xem",onboardingTitle:"Chào mừng đến ClaudeKit",onboardingSubtitle:"Chọn kit của bạn và bắt đầu trong vài phút",kitEngineerName:"ClaudeKit Engineer",kitEngineerTagline:"Lập trình AI với skills, hooks và multi-agent",kitMarketingName:"ClaudeKit Marketing",kitMarketingTagline:"Tự động hóa nội dung: chiến dịch, mạng xã hội, phân tích",featureAgents:"AI Agents",featureAgentsDesc:"Các agent chuyên biệt cho từng tác vụ",featureHooks:"Lifecycle Hooks",featureHooksDesc:"Tùy chỉnh hành vi của Claude tại các thời điểm quan trọng",featureSkills:"Thư viện Skills",featureSkillsDesc:"Các khả năng có sẵn bạn có thể kích hoạt",featureMultiAgent:"Multi-Agent Workflows",featureMultiAgentDesc:"Phối hợp nhiều agent cho các tác vụ phức tạp",featureContent:"Tạo nội dung",featureContentDesc:"Tự động tạo và tối ưu nội dung",featureSocial:"Công cụ mạng xã hội",featureSocialDesc:"Lên lịch, phân tích và tự động tương tác",stepChooseKit:"Chọn Kit",stepConfigure:"Cấu hình",stepInstall:"Cài đặt",back:"Quay lại",next:"Tiếp theo",install:"Cài đặt",installSuccess:"Cài đặt hoàn tất!",installSuccessDesc:"{kit} đã sẵn sàng sử dụng",getStarted:"Bắt đầu",goToDashboard:"Đi đến Dashboard",kitConfig:"Cấu hình Kit",kitConfigSubtitle:"Cấu hình ClaudeKit Engineer",scopeGlobal:"Toàn cục",scopeProject:"Dự án",sectionGeneral:"Cài đặt chung",sectionPaths:"Đường dẫn",sectionPrivacy:"Bảo mật & Tin cậy",sectionProject:"Phát hiện dự án",sectionIntegrations:"Tích hợp",sectionHooks:"Hooks",sectionAdvanced:"Nâng cao",fieldCodingLevel:"Cấp độ lập trình",fieldCodingLevelDesc:"Cấp độ kinh nghiệm (-1=tự động, 0=mới bắt đầu, 1=trung cấp, 2=nâng cao, 3=chuyên gia, 4=tech-lead, 5=thần)",fieldStatusline:"Chế độ thanh trạng thái",fieldStatuslineDesc:"Lượng thông tin hiển thị trên thanh trạng thái",fieldThinkingLanguage:"Ngôn ngữ suy nghĩ",fieldThinkingLanguageDesc:"Ngôn ngữ cho suy luận nội bộ của Claude (null=Tiếng Anh)",fieldResponseLanguage:"Ngôn ngữ phản hồi",fieldResponseLanguageDesc:"Ngôn ngữ cho phản hồi của Claude (null=theo người dùng)",fieldDocsPath:"Thư mục tài liệu",fieldDocsPathDesc:"Đường dẫn đến thư mục tài liệu",fieldPlansPath:"Thư mục kế hoạch",fieldPlansPathDesc:"Đường dẫn đến thư mục kế hoạch",fieldPrivacyBlock:"Chặn quyền riêng tư",fieldPrivacyBlockDesc:"Chặn truy cập file nhạy cảm (.env, credentials)",fieldTrustEnabled:"Chế độ tin cậy",fieldTrustEnabledDesc:"Tự động phê duyệt các tool calls",fieldTrustPassphrase:"Mật khẩu tin cậy",fieldTrustPassphraseDesc:"Mật khẩu để bật chế độ tin cậy",fieldProjectType:"Loại dự án",fieldProjectTypeDesc:"Ghi đè loại dự án tự động phát hiện",fieldPackageManager:"Trình quản lý gói",fieldPackageManagerDesc:"Ghi đè trình quản lý gói tự động phát hiện",fieldFramework:"Framework",fieldFrameworkDesc:"Ghi đè framework tự động phát hiện",fieldGeminiModel:"Mô hình Gemini",fieldGeminiModelDesc:"Mô hình Gemini cho các lệnh CLI",fieldResearchUseGemini:"Dùng Gemini cho nghiên cứu",fieldResearchUseGeminiDesc:"Dùng Gemini CLI thay vì WebSearch",fieldDocsMaxLoc:"Số dòng tối đa/tài liệu",fieldDocsMaxLocDesc:"Số dòng code tối đa cho mỗi file tài liệu",fieldPlanNamingFormat:"Định dạng tên kế hoạch",fieldPlanNamingFormatDesc:"Định dạng cho tên thư mục kế hoạch",fieldPlanDateFormat:"Định dạng ngày kế hoạch",fieldPlanDateFormatDesc:"Định dạng ngày cho tên kế hoạch (moment.js)",fieldPlanValidationMode:"Chế độ xác thực",fieldPlanValidationModeDesc:"Cách xác thực kế hoạch trước khi triển khai",fieldPlanMinQuestions:"Số câu hỏi tối thiểu",fieldPlanMinQuestionsDesc:"Số câu hỏi xác thực tối thiểu",fieldPlanMaxQuestions:"Số câu hỏi tối đa",fieldPlanMaxQuestionsDesc:"Số câu hỏi xác thực tối đa",fieldAssertions:"Assertions",fieldAssertionsDesc:"Các assertions và quy tắc cần thực thi",fieldHookSessionInit:"Khởi tạo phiên",fieldHookSessionInitDesc:"Phát hiện dự án và thiết lập môi trường",fieldHookSubagentInit:"Khởi tạo subagent",fieldHookSubagentInitDesc:"Inject context vào subagents",fieldHookDescriptiveName:"Tên mô tả",fieldHookDescriptiveNameDesc:"Bắt buộc đặt tên file dạng kebab-case mô tả cho scripts",fieldHookDevRulesReminder:"Nhắc nhở quy tắc dev",fieldHookDevRulesReminderDesc:"Inject context quy tắc phát triển",fieldHookUsageContextAwareness:"Nhận thức ngữ cảnh sử dụng",fieldHookUsageContextAwarenessDesc:"Nhận thức giới hạn sử dụng",fieldHookContextTracking:"Theo dõi ngữ cảnh",fieldHookContextTrackingDesc:"Theo dõi cửa sổ ngữ cảnh (% đã dùng, số token)",fieldHookScoutBlock:"Chặn Scout",fieldHookScoutBlockDesc:"Chặn thư mục nặng khỏi việc khám phá",fieldHookPrivacyBlock:"Hook chặn quyền riêng tư",fieldHookPrivacyBlockDesc:"Chặn đọc file nhạy cảm",fieldHookPostEditSimplify:"Đơn giản sau chỉnh sửa",fieldHookPostEditSimplifyDesc:"Nhắc đơn giản sau khi chỉnh sửa",skillsPageTitle:"Quản lý Kỹ năng",skillsPageDesc:"Cài đặt kỹ năng ClaudeKit cho các agent lập trình",availableSkills:"Kỹ năng có sẵn",installedSkills:"Kỹ năng đã cài",noSkillsFound:"Không tìm thấy kỹ năng",installSkill:"Cài đặt",uninstallSkill:"Gỡ cài đặt",manageSkill:"Quản lý",syncRegistry:"Đồng bộ",installSkillTitle:"Cài đặt Kỹ năng",selectAgents:"Chọn agent đích",installLocation:"Vị trí cài đặt",globalInstall:"Toàn cục",projectInstall:"Dự án",confirmInstall:"Cài đặt cho các agent đã chọn",installingSkill:"Đang cài đặt...",skillInstallSuccess:"Cài đặt kỹ năng thành công",skillInstallFailed:"Cài đặt thất bại",agentClaudeCode:"Claude Code",agentCursor:"Cursor",agentCodex:"Codex",agentOpencode:"OpenCode",agentGoose:"Goose",agentGeminiCli:"Gemini CLI",agentAntigravity:"Antigravity",agentGithubCopilot:"GitHub Copilot",agentAmp:"Amp",agentKilo:"Kilo",agentRoo:"Roo",agentWindsurf:"Windsurf",agentCline:"Cline",agentOpenhands:"OpenHands",installed:"Đã cài",notInstalled:"Chưa cài",allAgents:"Tất cả Agent",filterByAgent:"Lọc theo agent",skillsTitle:"Kỹ năng",skillsSubtitle:"Duyệt, cài đặt và quản lý kỹ năng cho coding agents",availableCount:"Có sẵn",installedCount:"Đã cài",agentsCount:"Agents",searchSkills:"Tìm kiếm kỹ năng...",searchShortcut:"/",sortAZ:"A-Z",sortCategory:"Danh mục",sortInstalledFirst:"Đã cài trước",listView:"Dạng danh sách",gridView:"Dạng lưới",categoryAll:"Tất cả",categoryAI:"AI",categoryUIUX:"UI/UX",categoryBackend:"Backend",categorySecurity:"Bảo mật",categoryDevOps:"DevOps",categoryDatabase:"Cơ sở dữ liệu",categoryDevelopment:"Phát triển",categoryResearch:"Nghiên cứu",categoryGeneral:"Tổng quát",categoryCore:"Cốt lõi",categoryDocumentation:"Tài liệu",categoryTooling:"Công cụ",categoryMedia:"Phương tiện",categoryFrameworks:"Framework",skillsCountLabel:"{count} kỹ năng",installToAll:"Cài cho tất cả đã phát hiện",scopeLabel:"Phạm vi cài đặt",agentInstalled:"Đã cài",agentNotInstalled:"Chưa cài",skillSource:"Vị trí nguồn",skillSourceBadge:"Nguồn",detailPanelClose:"Đóng",versionLabel:"v{version}",installAllToAllAgents:"Cài tất cả cho tất cả Agent",bulkInstallFailed:"Cài hàng loạt thất bại",noAgentsDetected:"Không phát hiện agent nào",kitBadgeEngineer:"Engineer",kitBadgeMarketing:"Marketing",customizedBadge:"Đã tùy chỉnh",installedVersionLabel:"Phiên bản cài đặt",installedAtLabel:"Cài đặt lúc",sourceTimestampLabel:"Ngày nguồn",kitLabel:"Kit",skillMetadata:"Thông tin Skill",migrate:"Di trú",migrateTitle:"Di trú",migrateSubtitle:"Chuyển toàn bộ stack Claude Code sang provider khác",migrateDetectedProviders:"Đã phát hiện",migrateSelectedProviders:"Đã chọn",migrateDiscovering:"Đang quét nguồn di trú...",migrateRefresh:"Làm mới quét",migrateRun:"Chạy di trú",migrateRunning:"Đang di trú...",migrateSourceSummary:"Tổng quan nguồn",migratePresetCodex:"Codex",migratePresetAntigravity:"Antigravity",migratePresetBoth:"Codex + Antigravity",migratePresetDetected:"Tất cả đã phát hiện",migrateScope:"Phạm vi",migrateScopeProject:"Dự án",migrateScopeGlobal:"Toàn cục",migrateTypes:"Loại di trú",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateSearchProviders:"Tìm provider...",migrateSelectVisible:"Chọn phần đang hiện",migrateClearSelection:"Bỏ chọn tất cả",migrateProvidersHeading:"Provider đích",migrateProvidersCountSuffix:"provider",migrateNoProvidersMatch:"Không có provider khớp bộ lọc hiện tại.",migrateSelectButton:"Chọn",migrateSelectedButton:"Đã chọn",migrateSelectProviderAction:"Chọn provider",migrateUnselectProvider:"Bỏ chọn provider",migrateCapabilitiesLabel:"loại",migrateCapabilitiesSection:"Ma trận khả năng",migrateSupported:"Hỗ trợ",migrateUnsupportedShort:"Không hỗ trợ",migrateIncludedEnabled:"Đang bật",migrateIncludedDisabled:"Đang tắt",migrateLatestTarget:"Đích gần nhất",migrateNoResultForProvider:"Chưa có kết quả di trú cho provider này.",migrateActionSummaryTitle:"Sẵn sàng di trú",migrateGlobalOnlyCommandsShort:"Commands chỉ global",migrateNoProviders:"Không có provider khả dụng.",migrateUnsupported:"Sẽ bỏ qua (không hỗ trợ)",migrateGlobalForced:"Lệnh Codex chỉ hỗ trợ global. Phạm vi sẽ tự chuyển global.",migrateResults:"Kết quả di trú",migrateInstalled:"Đã cài",migrateSkipped:"Đã bỏ qua",migrateFailed:"Lỗi",migrateProvider:"Provider",migrateStatus:"Trạng thái",migratePath:"Đường dẫn",migrateError:"Lỗi",migrateStatusInstalled:"Đã cài",migrateStatusSkipped:"Đã bỏ qua",migrateStatusFailed:"Lỗi",migrateNoResults:"Chưa có kết quả di trú.",migrateDetectFailed:"Không thể quét dữ liệu di trú",migrateExecuteFailed:"Chạy di trú thất bại",migrateSelectProvider:"Vui lòng chọn ít nhất một provider",migrateNoTypesEnabled:"Bật ít nhất một loại di trú",migrateDetectedTag:"Đã phát hiện",migrateNotDetectedTag:"Chưa phát hiện",migrateFilterRecommended:"Đề xuất",developmentFeature:"Đang phát triển",betaFeature:"Beta",experimentalFeature:"Thử nghiệm"}},lh=b.createContext(null),gm="ck-dashboard-lang";function _x(){const n=localStorage.getItem(gm);return n==="en"||n==="vi"?n:navigator.language.startsWith("vi")?"vi":"en"}function Ux({children:n}){const[e,t]=b.useState(_x),r=s=>{localStorage.setItem(gm,s),t(s)},i=s=>Wx[e][s];return u.jsx(lh.Provider,{value:{lang:e,setLang:r,t:i},children:n})}function xe(){const n=b.useContext(lh);if(!n)throw new Error("useI18n must be used within I18nProvider");return n}class Kx extends b.Component{constructor(){super(...arguments);du(this,"state",{hasError:!1,error:null})}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,r){console.error("App error:",t,r.componentStack)}render(){if(this.state.hasError){const t=this.state.error?.name==="ServerUnavailableError";return u.jsx(lh.Consumer,{children:r=>u.jsx("div",{className:"flex h-screen items-center justify-center bg-dash-bg",children:u.jsx("div",{className:"text-center space-y-4 max-w-md px-6",children:t?u.jsxs(u.Fragment,{children:[u.jsx("div",{className:"w-16 h-16 mx-auto rounded-full bg-orange-500/10 border border-orange-500/30 flex items-center justify-center text-3xl",children:"🔌"}),u.jsx("h1",{className:"text-2xl font-bold text-orange-500",children:r?.t("serverNotRunning")??"Server Not Running"}),u.jsx("p",{className:"text-dash-text-secondary",children:r?.t("startServerMessage")??"The Config UI requires the backend server to be running."}),u.jsxs("div",{className:"bg-dash-surface border border-dash-border rounded-lg p-4",children:[u.jsx("p",{className:"text-xs text-dash-text-muted uppercase tracking-widest mb-2 font-bold",children:r?.t("runThisCommand")??"Run this command"}),u.jsx("code",{className:"block text-sm text-dash-accent font-mono bg-dash-bg px-3 py-2 rounded border border-dash-border",children:"ck config"})]}),u.jsx("button",{onClick:()=>window.location.reload(),className:"px-6 py-2 bg-dash-accent text-dash-bg rounded-lg font-bold hover:bg-dash-accent-hover transition-colors",children:r?.t("tryAgain")??"Try Again"})]}):u.jsxs(u.Fragment,{children:[u.jsx("h1",{className:"text-2xl font-bold text-red-500",children:r?.t("somethingWentWrong")??"Something went wrong"}),u.jsx("p",{className:"text-dash-text-muted",children:this.state.error?.message}),u.jsx("button",{onClick:()=>window.location.reload(),className:"px-4 py-2 bg-dash-accent text-white rounded-md hover:opacity-90",children:r?.t("reloadApp")??"Reload App"})]})})})})}return this.props.children}}const Ci=({direction:n="horizontal",isDragging:e=!1,onMouseDown:t})=>{const r=n==="horizontal";return u.jsx("div",{onMouseDown:t,className:`
21
+ Please change the parent <Route path="${k}"> to <Route path="${k==="/"?"*":`${k}/*`}">.`)}let f=Qt(),p;p=f;let m=p.pathname||"/",g=m;if(h!=="/"){let k=h.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(k.length).join("/")}let y=xn(n,{pathname:g});return Te(d||y!=null,`No routes matched location "${p.pathname}${p.search}${p.hash}" `),Te(y==null||y[y.length-1].route.element!==void 0||y[y.length-1].route.Component!==void 0||y[y.length-1].route.lazy!==void 0,`Matched leaf route at location "${p.pathname}${p.search}${p.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`),Wy(y&&y.map(k=>Object.assign({},k,{params:Object.assign({},l,k.params),pathname:Gt([h,s.encodeLocation?s.encodeLocation(k.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:k.pathname]),pathnameBase:k.pathnameBase==="/"?h:Gt([h,s.encodeLocation?s.encodeLocation(k.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:k.pathnameBase])})),o,t,r,i)}function Fy(){let n=qy(),e=Si(n)?`${n.status} ${n.statusText}`:n instanceof Error?n.message:JSON.stringify(n),t=n instanceof Error?n.stack:null,r="rgba(200,200,200, 0.5)",i={padding:"0.5rem",backgroundColor:r},s={padding:"2px 4px",backgroundColor:r},o=null;return console.error("Error handled by React Router default ErrorBoundary:",n),o=b.createElement(b.Fragment,null,b.createElement("p",null,"💿 Hey developer 👋"),b.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",b.createElement("code",{style:s},"ErrorBoundary")," or"," ",b.createElement("code",{style:s},"errorElement")," prop on your route.")),b.createElement(b.Fragment,null,b.createElement("h2",null,"Unexpected Application Error!"),b.createElement("h3",{style:{fontStyle:"italic"}},e),t?b.createElement("pre",{style:i},t):null,o)}var Vy=b.createElement(Fy,null),cm=class extends b.Component{constructor(n){super(n),this.state={location:n.location,revalidation:n.revalidation,error:n.error}}static getDerivedStateFromError(n){return{error:n}}static getDerivedStateFromProps(n,e){return e.location!==n.location||e.revalidation!=="idle"&&n.revalidation==="idle"?{error:n.error,location:n.location,revalidation:n.revalidation}:{error:n.error!==void 0?n.error:e.error,location:e.location,revalidation:n.revalidation||e.revalidation}}componentDidCatch(n,e){this.props.onError?this.props.onError(n,e):console.error("React Router caught the following error during render",n)}render(){let n=this.state.error;if(this.context&&typeof n=="object"&&n&&"digest"in n&&typeof n.digest=="string"){const t=Ey(n.digest);t&&(n=t)}let e=n!==void 0?b.createElement(jt.Provider,{value:this.props.routeContext},b.createElement(rh.Provider,{value:n,children:this.props.component})):this.props.children;return this.context?b.createElement(zy,{error:n},e):e}};cm.contextType=nm;var Ja=new WeakMap;function zy({children:n,error:e}){let{basename:t}=b.useContext(mt);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let r=Ny(e.digest);if(r){let i=Ja.get(e);if(i)throw i;let s=_p(r.location,t);if(Wp&&!Ja.get(e))if(s.isExternal||r.reloadDocument)window.location.href=s.absoluteURL||s.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(s.to,{replace:r.replace}));throw Ja.set(e,o),o}return b.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return n}function Hy({routeContext:n,match:e,children:t}){let r=b.useContext(ir);return r&&r.static&&r.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=e.route.id),b.createElement(jt.Provider,{value:n},t)}function Wy(n,e=[],t=null,r=null,i=null){if(n==null){if(!t)return null;if(t.errors)n=t.matches;else if(e.length===0&&!t.initialized&&t.matches.length>0)n=t.matches;else return null}let s=n,o=t?.errors;if(o!=null){let h=s.findIndex(d=>d.route.id&&o?.[d.route.id]!==void 0);he(h>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,h+1))}let a=!1,l=-1;if(t)for(let h=0;h<s.length;h++){let d=s[h];if((d.route.HydrateFallback||d.route.hydrateFallbackElement)&&(l=h),d.route.id){let{loaderData:f,errors:p}=t,m=d.route.loader&&!f.hasOwnProperty(d.route.id)&&(!p||p[d.route.id]===void 0);if(d.route.lazy||m){a=!0,l>=0?s=s.slice(0,l+1):s=[s[0]];break}}}let c=t&&r?(h,d)=>{r(h,{location:t.location,params:t.matches?.[0]?.params??{},unstable_pattern:Ms(t.matches),errorInfo:d})}:void 0;return s.reduceRight((h,d,f)=>{let p,m=!1,g=null,y=null;t&&(p=o&&d.route.id?o[d.route.id]:void 0,g=d.route.errorElement||Vy,a&&(l<0&&f===0?(hm("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,y=null):l===f&&(m=!0,y=d.route.hydrateFallbackElement||null)));let v=e.concat(s.slice(0,f+1)),k=()=>{let S;return p?S=g:m?S=y:d.route.Component?S=b.createElement(d.route.Component,null):d.route.element?S=d.route.element:S=h,b.createElement(Hy,{match:d,routeContext:{outlet:h,matches:v,isDataRoute:t!=null},children:S})};return t&&(d.route.ErrorBoundary||d.route.errorElement||f===0)?b.createElement(cm,{location:t.location,revalidation:t.revalidation,component:g,error:p,children:k(),routeContext:{outlet:null,matches:v,isDataRoute:!0},onError:c}):k()},null)}function ih(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function _y(n){let e=b.useContext(ir);return he(e,ih(n)),e}function Uy(n){let e=b.useContext(As);return he(e,ih(n)),e}function Ky(n){let e=b.useContext(jt);return he(e,ih(n)),e}function sh(n){let e=Ky(n),t=e.matches[e.matches.length-1];return he(t.route.id,`${n} can only be used on routes that contain a unique "id"`),t.route.id}function Gy(){return sh("useRouteId")}function qy(){let n=b.useContext(rh),e=Uy("useRouteError"),t=sh("useRouteError");return n!==void 0?n:e.errors?.[t]}function Yy(){let{router:n}=_y("useNavigate"),e=sh("useNavigate"),t=b.useRef(!1);return om(()=>{t.current=!0}),b.useCallback(async(i,s={})=>{Te(t.current,sm),t.current&&(typeof i=="number"?await n.navigate(i):await n.navigate(i,{fromRouteId:e,...s}))},[n,e])}var Iu={};function hm(n,e,t){!e&&!Iu[n]&&(Iu[n]=!0,Te(!1,t))}var Bu={};function $u(n,e){!n&&!Bu[e]&&(Bu[e]=!0,console.warn(e))}var Qy="useOptimistic",Fu=c1[Qy],Jy=()=>{};function Xy(n){return Fu?Fu(n):[n,Jy]}function Zy(n){let e={hasErrorBoundary:n.hasErrorBoundary||n.ErrorBoundary!=null||n.errorElement!=null};return n.Component&&(n.element&&Te(!1,"You should not include both `Component` and `element` on your route - `Component` will be used."),Object.assign(e,{element:b.createElement(n.Component),Component:void 0})),n.HydrateFallback&&(n.hydrateFallbackElement&&Te(!1,"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."),Object.assign(e,{hydrateFallbackElement:b.createElement(n.HydrateFallback),HydrateFallback:void 0})),n.ErrorBoundary&&(n.errorElement&&Te(!1,"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."),Object.assign(e,{errorElement:b.createElement(n.ErrorBoundary),ErrorBoundary:void 0})),e}var ex=["HydrateFallback","hydrateFallbackElement"],tx=class{constructor(){this.status="pending",this.promise=new Promise((n,e)=>{this.resolve=t=>{this.status==="pending"&&(this.status="resolved",n(t))},this.reject=t=>{this.status==="pending"&&(this.status="rejected",e(t))}})}};function nx({router:n,flushSync:e,onError:t,unstable_useTransitions:r}){r=My()||r;let[s,o]=b.useState(n.state),[a,l]=Xy(s),[c,h]=b.useState(),[d,f]=b.useState({isTransitioning:!1}),[p,m]=b.useState(),[g,y]=b.useState(),[v,k]=b.useState(),S=b.useRef(new Map),P=b.useCallback((D,{deletedFetchers:T,newErrors:R,flushSync:L,viewTransitionOpts:$})=>{R&&t&&Object.values(R).forEach(_=>t(_,{location:D.location,params:D.matches[0]?.params??{},unstable_pattern:Ms(D.matches)})),D.fetchers.forEach((_,V)=>{_.data!==void 0&&S.current.set(V,_.data)}),T.forEach(_=>S.current.delete(_)),$u(L===!1||e!=null,'You provided the `flushSync` option to a router update, but you are not using the `<RouterProvider>` from `react-router/dom` so `ReactDOM.flushSync()` is unavailable. Please update your app to `import { RouterProvider } from "react-router/dom"` and ensure you have `react-dom` installed as a dependency to use the `flushSync` option.');let U=n.window!=null&&n.window.document!=null&&typeof n.window.document.startViewTransition=="function";if($u($==null||U,"You provided the `viewTransition` option to a router update, but you do not appear to be running in a DOM environment as `window.startViewTransition` is not available."),!$||!U){e&&L?e(()=>o(D)):r===!1?o(D):b.startTransition(()=>{r===!0&&l(_=>Vu(_,D)),o(D)});return}if(e&&L){e(()=>{g&&(p?.resolve(),g.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:$.currentLocation,nextLocation:$.nextLocation})});let _=n.window.document.startViewTransition(()=>{e(()=>o(D))});_.finished.finally(()=>{e(()=>{m(void 0),y(void 0),h(void 0),f({isTransitioning:!1})})}),e(()=>y(_));return}g?(p?.resolve(),g.skipTransition(),k({state:D,currentLocation:$.currentLocation,nextLocation:$.nextLocation})):(h(D),f({isTransitioning:!0,flushSync:!1,currentLocation:$.currentLocation,nextLocation:$.nextLocation}))},[n.window,e,g,p,r,l,t]);b.useLayoutEffect(()=>n.subscribe(P),[n,P]),b.useEffect(()=>{d.isTransitioning&&!d.flushSync&&m(new tx)},[d]),b.useEffect(()=>{if(p&&c&&n.window){let D=c,T=p.promise,R=n.window.document.startViewTransition(async()=>{r===!1?o(D):b.startTransition(()=>{r===!0&&l(L=>Vu(L,D)),o(D)}),await T});R.finished.finally(()=>{m(void 0),y(void 0),h(void 0),f({isTransitioning:!1})}),y(R)}},[c,p,n.window,r,l]),b.useEffect(()=>{p&&c&&a.location.key===c.location.key&&p.resolve()},[p,g,a.location,c]),b.useEffect(()=>{!d.isTransitioning&&v&&(h(v.state),f({isTransitioning:!0,flushSync:!1,currentLocation:v.currentLocation,nextLocation:v.nextLocation}),k(void 0))},[d.isTransitioning,v]);let O=b.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:D=>n.navigate(D),push:(D,T,R)=>n.navigate(D,{state:T,preventScrollReset:R?.preventScrollReset}),replace:(D,T,R)=>n.navigate(D,{replace:!0,state:T,preventScrollReset:R?.preventScrollReset})}),[n]),M=n.basename||"/",x=b.useMemo(()=>({router:n,navigator:O,static:!1,basename:M,onError:t}),[n,O,M,t]);return b.createElement(b.Fragment,null,b.createElement(ir.Provider,{value:x},b.createElement(As.Provider,{value:a},b.createElement(rm.Provider,{value:S.current},b.createElement(nh.Provider,{value:d},b.createElement(ox,{basename:M,location:a.location,navigationType:a.historyAction,navigator:O,unstable_useTransitions:r},b.createElement(rx,{routes:n.routes,future:n.future,state:a,onError:t})))))),null)}function Vu(n,e){return{...n,navigation:e.navigation.state!=="idle"?e.navigation:n.navigation,revalidation:e.revalidation!=="idle"?e.revalidation:n.revalidation,actionData:e.navigation.state!=="submitting"?e.actionData:n.actionData,fetchers:e.fetchers}}var rx=b.memo(ix);function ix({routes:n,future:e,state:t,onError:r}){return $y(n,void 0,t,r,e)}function Xa({to:n,replace:e,state:t,relative:r}){he(Lr(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=b.useContext(mt);Te(!i,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:s}=b.useContext(jt),{pathname:o}=Qt(),a=fn(),l=wa(n,va(s),o,r==="path"),c=JSON.stringify(l);return b.useEffect(()=>{a(JSON.parse(c),{replace:e,state:t,relative:r})},[a,c,r,e,t]),null}function sx(n){return By(n.context)}function ox({basename:n="/",children:e=null,location:t,navigationType:r="POP",navigator:i,static:s=!1,unstable_useTransitions:o}){he(!Lr(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let a=n.replace(/^\/*/,"/"),l=b.useMemo(()=>({basename:a,navigator:i,static:s,unstable_useTransitions:o,future:{}}),[a,i,s,o]);typeof t=="string"&&(t=Rn(t));let{pathname:c="/",search:h="",hash:d="",state:f=null,key:p="default"}=t,m=b.useMemo(()=>{let g=Ct(c,a);return g==null?null:{location:{pathname:g,search:h,hash:d,state:f,key:p},navigationType:r}},[a,c,h,d,f,p,r]);return Te(m!=null,`<Router basename="${a}"> is not able to match the URL "${c}${h}${d}" because it does not start with the basename, so the <Router> won't render anything.`),m==null?null:b.createElement(mt.Provider,{value:l},b.createElement(ka.Provider,{children:e,value:m}))}var No="get",Eo="application/x-www-form-urlencoded";function Sa(n){return typeof HTMLElement<"u"&&n instanceof HTMLElement}function ax(n){return Sa(n)&&n.tagName.toLowerCase()==="button"}function lx(n){return Sa(n)&&n.tagName.toLowerCase()==="form"}function cx(n){return Sa(n)&&n.tagName.toLowerCase()==="input"}function hx(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function ux(n,e){return n.button===0&&(!e||e==="_self")&&!hx(n)}var eo=null;function dx(){if(eo===null)try{new FormData(document.createElement("form"),0),eo=!1}catch{eo=!0}return eo}var fx=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Za(n){return n!=null&&!fx.has(n)?(Te(!1,`"${n}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Eo}"`),null):n}function px(n,e){let t,r,i,s,o;if(lx(n)){let a=n.getAttribute("action");r=a?Ct(a,e):null,t=n.getAttribute("method")||No,i=Za(n.getAttribute("enctype"))||Eo,s=new FormData(n)}else if(ax(n)||cx(n)&&(n.type==="submit"||n.type==="image")){let a=n.form;if(a==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let l=n.getAttribute("formaction")||a.getAttribute("action");if(r=l?Ct(l,e):null,t=n.getAttribute("formmethod")||a.getAttribute("method")||No,i=Za(n.getAttribute("formenctype"))||Za(a.getAttribute("enctype"))||Eo,s=new FormData(a,n),!dx()){let{name:c,type:h,value:d}=n;if(h==="image"){let f=c?`${c}.`:"";s.append(`${f}x`,"0"),s.append(`${f}y`,"0")}else c&&s.append(c,d)}}else{if(Sa(n))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');t=No,r=null,i=Eo,o=n}return s&&i==="text/plain"&&(o=s,s=void 0),{action:r,method:t.toLowerCase(),encType:i,formData:s,body:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oh(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function mx(n,e,t){let r=typeof n=="string"?new URL(n,typeof window>"u"?"server://singlefetch/":window.location.origin):n;return r.pathname==="/"?r.pathname=`_root.${t}`:e&&Ct(r.pathname,e)==="/"?r.pathname=`${e.replace(/\/$/,"")}/_root.${t}`:r.pathname=`${r.pathname.replace(/\/$/,"")}.${t}`,r}async function gx(n,e){if(n.id in e)return e[n.id];try{let t=await import(n.module);return e[n.id]=t,t}catch(t){return console.error(`Error loading route module \`${n.module}\`, reloading page...`),console.error(t),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function bx(n){return n==null?!1:n.href==null?n.rel==="preload"&&typeof n.imageSrcSet=="string"&&typeof n.imageSizes=="string":typeof n.rel=="string"&&typeof n.href=="string"}async function yx(n,e,t){let r=await Promise.all(n.map(async i=>{let s=e.routes[i.route.id];if(s){let o=await gx(s,t);return o.links?o.links():[]}return[]}));return kx(r.flat(1).filter(bx).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function zu(n,e,t,r,i,s){let o=(l,c)=>t[c]?l.route.id!==t[c].route.id:!0,a=(l,c)=>t[c].pathname!==l.pathname||t[c].route.path?.endsWith("*")&&t[c].params["*"]!==l.params["*"];return s==="assets"?e.filter((l,c)=>o(l,c)||a(l,c)):s==="data"?e.filter((l,c)=>{let h=r.routes[l.route.id];if(!h||!h.hasLoader)return!1;if(o(l,c)||a(l,c))return!0;if(l.route.shouldRevalidate){let d=l.route.shouldRevalidate({currentUrl:new URL(i.pathname+i.search+i.hash,window.origin),currentParams:t[0]?.params||{},nextUrl:new URL(n,window.origin),nextParams:l.params,defaultShouldRevalidate:!0});if(typeof d=="boolean")return d}return!0}):[]}function xx(n,e,{includeHydrateFallback:t}={}){return vx(n.map(r=>{let i=e.routes[r.route.id];if(!i)return[];let s=[i.module];return i.clientActionModule&&(s=s.concat(i.clientActionModule)),i.clientLoaderModule&&(s=s.concat(i.clientLoaderModule)),t&&i.hydrateFallbackModule&&(s=s.concat(i.hydrateFallbackModule)),i.imports&&(s=s.concat(i.imports)),s}).flat(1))}function vx(n){return[...new Set(n)]}function wx(n){let e={},t=Object.keys(n).sort();for(let r of t)e[r]=n[r];return e}function kx(n,e){let t=new Set;return new Set(e),n.reduce((r,i)=>{let s=JSON.stringify(wx(i));return t.has(s)||(t.add(s),r.push({key:s,link:i})),r},[])}function um(){let n=b.useContext(ir);return oh(n,"You must render this element inside a <DataRouterContext.Provider> element"),n}function Sx(){let n=b.useContext(As);return oh(n,"You must render this element inside a <DataRouterStateContext.Provider> element"),n}var ah=b.createContext(void 0);ah.displayName="FrameworkContext";function dm(){let n=b.useContext(ah);return oh(n,"You must render this element inside a <HydratedRouter> element"),n}function Cx(n,e){let t=b.useContext(ah),[r,i]=b.useState(!1),[s,o]=b.useState(!1),{onFocus:a,onBlur:l,onMouseEnter:c,onMouseLeave:h,onTouchStart:d}=e,f=b.useRef(null);b.useEffect(()=>{if(n==="render"&&o(!0),n==="viewport"){let g=v=>{v.forEach(k=>{o(k.isIntersecting)})},y=new IntersectionObserver(g,{threshold:.5});return f.current&&y.observe(f.current),()=>{y.disconnect()}}},[n]),b.useEffect(()=>{if(r){let g=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(g)}}},[r]);let p=()=>{i(!0)},m=()=>{i(!1),o(!1)};return t?n!=="intent"?[s,f,{}]:[s,f,{onFocus:Xr(a,p),onBlur:Xr(l,m),onMouseEnter:Xr(c,p),onMouseLeave:Xr(h,m),onTouchStart:Xr(d,p)}]:[!1,f,{}]}function Xr(n,e){return t=>{n&&n(t),t.defaultPrevented||e(t)}}function Ox({page:n,...e}){let{router:t}=um(),r=b.useMemo(()=>xn(t.routes,n,t.basename),[t.routes,n,t.basename]);return r?b.createElement(Px,{page:n,matches:r,...e}):null}function jx(n){let{manifest:e,routeModules:t}=dm(),[r,i]=b.useState([]);return b.useEffect(()=>{let s=!1;return yx(n,e,t).then(o=>{s||i(o)}),()=>{s=!0}},[n,e,t]),r}function Px({page:n,matches:e,...t}){let r=Qt(),{manifest:i,routeModules:s}=dm(),{basename:o}=um(),{loaderData:a,matches:l}=Sx(),c=b.useMemo(()=>zu(n,e,l,i,r,"data"),[n,e,l,i,r]),h=b.useMemo(()=>zu(n,e,l,i,r,"assets"),[n,e,l,i,r]),d=b.useMemo(()=>{if(n===r.pathname+r.search+r.hash)return[];let m=new Set,g=!1;if(e.forEach(v=>{let k=i.routes[v.route.id];!k||!k.hasLoader||(!c.some(S=>S.route.id===v.route.id)&&v.route.id in a&&s[v.route.id]?.shouldRevalidate||k.hasClientLoader?g=!0:m.add(v.route.id))}),m.size===0)return[];let y=mx(n,o,"data");return g&&m.size>0&&y.searchParams.set("_routes",e.filter(v=>m.has(v.route.id)).map(v=>v.route.id).join(",")),[y.pathname+y.search]},[o,a,r,i,c,e,n,s]),f=b.useMemo(()=>xx(h,i),[h,i]),p=jx(h);return b.createElement(b.Fragment,null,d.map(m=>b.createElement("link",{key:m,rel:"prefetch",as:"fetch",href:m,...t})),f.map(m=>b.createElement("link",{key:m,rel:"modulepreload",href:m,...t})),p.map(({key:m,link:g})=>b.createElement("link",{key:m,nonce:t.nonce,...g})))}function Mx(...n){return e=>{n.forEach(t=>{typeof t=="function"?t(e):t!=null&&(t.current=e)})}}var Ax=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{Ax&&(window.__reactRouterVersion="7.11.0")}catch{}function Dx(n,e){return ry({basename:e?.basename,getContext:e?.getContext,future:e?.future,history:x1({window:e?.window}),hydrationData:Tx(),routes:n,mapRouteProperties:Zy,hydrationRouteProperties:ex,dataStrategy:e?.dataStrategy,patchRoutesOnNavigation:e?.patchRoutesOnNavigation,window:e?.window,unstable_instrumentations:e?.unstable_instrumentations}).initialize()}function Tx(){let n=window?.__staticRouterHydrationData;return n&&n.errors&&(n={...n,errors:Nx(n.errors)}),n}function Nx(n){if(!n)return null;let e=Object.entries(n),t={};for(let[r,i]of e)if(i&&i.__type==="RouteErrorResponse")t[r]=new Ps(i.status,i.statusText,i.data,i.internal===!0);else if(i&&i.__type==="Error"){if(i.__subType){let s=window[i.__subType];if(typeof s=="function")try{let o=new s(i.message);o.stack="",t[r]=o}catch{}}if(t[r]==null){let s=new Error(i.message);s.stack="",t[r]=s}}else t[r]=i;return t}var fm=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,pm=b.forwardRef(function({onClick:e,discover:t="render",prefetch:r="none",relative:i,reloadDocument:s,replace:o,state:a,target:l,to:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f,...p},m){let{basename:g,unstable_useTransitions:y}=b.useContext(mt),v=typeof c=="string"&&fm.test(c),k=_p(c,g);c=k.to;let S=Ry(c,{relative:i}),[P,O,M]=Cx(r,p),x=Ix(c,{replace:o,state:a,target:l,preventScrollReset:h,relative:i,viewTransition:d,unstable_defaultShouldRevalidate:f,unstable_useTransitions:y});function D(R){e&&e(R),R.defaultPrevented||x(R)}let T=b.createElement("a",{...p,...M,href:k.absoluteURL||S,onClick:k.isExternal||s?e:D,ref:Mx(m,O),target:l,"data-discover":!v&&t==="render"?"true":void 0});return P&&!v?b.createElement(b.Fragment,null,T,b.createElement(Ox,{page:S})):T});pm.displayName="Link";var Ex=b.forwardRef(function({"aria-current":e="page",caseSensitive:t=!1,className:r="",end:i=!1,style:s,to:o,viewTransition:a,children:l,...c},h){let d=Ds(o,{relative:c.relative}),f=Qt(),p=b.useContext(As),{navigator:m,basename:g}=b.useContext(mt),y=p!=null&&zx(d)&&a===!0,v=m.encodeLocation?m.encodeLocation(d).pathname:d.pathname,k=f.pathname,S=p&&p.navigation&&p.navigation.location?p.navigation.location.pathname:null;t||(k=k.toLowerCase(),S=S?S.toLowerCase():null,v=v.toLowerCase()),S&&g&&(S=Ct(S,g)||S);const P=v!=="/"&&v.endsWith("/")?v.length-1:v.length;let O=k===v||!i&&k.startsWith(v)&&k.charAt(P)==="/",M=S!=null&&(S===v||!i&&S.startsWith(v)&&S.charAt(v.length)==="/"),x={isActive:O,isPending:M,isTransitioning:y},D=O?e:void 0,T;typeof r=="function"?T=r(x):T=[r,O?"active":null,M?"pending":null,y?"transitioning":null].filter(Boolean).join(" ");let R=typeof s=="function"?s(x):s;return b.createElement(pm,{...c,"aria-current":D,className:T,ref:h,style:R,to:o,viewTransition:a},typeof l=="function"?l(x):l)});Ex.displayName="NavLink";var Rx=b.forwardRef(({discover:n="render",fetcherKey:e,navigate:t,reloadDocument:r,replace:i,state:s,method:o=No,action:a,onSubmit:l,relative:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f,...p},m)=>{let{unstable_useTransitions:g}=b.useContext(mt),y=Fx(),v=Vx(a,{relative:c}),k=o.toLowerCase()==="get"?"get":"post",S=typeof a=="string"&&fm.test(a),P=O=>{if(l&&l(O),O.defaultPrevented)return;O.preventDefault();let M=O.nativeEvent.submitter,x=M?.getAttribute("formmethod")||o,D=()=>y(M||O.currentTarget,{fetcherKey:e,method:x,navigate:t,replace:i,state:s,relative:c,preventScrollReset:h,viewTransition:d,unstable_defaultShouldRevalidate:f});g&&t!==!1?b.startTransition(()=>D()):D()};return b.createElement("form",{ref:m,method:k,action:v,onSubmit:r?l:P,...p,"data-discover":!S&&n==="render"?"true":void 0})});Rx.displayName="Form";function Lx(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function mm(n){let e=b.useContext(ir);return he(e,Lx(n)),e}function Ix(n,{target:e,replace:t,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a,unstable_useTransitions:l}={}){let c=fn(),h=Qt(),d=Ds(n,{relative:s});return b.useCallback(f=>{if(ux(f,e)){f.preventDefault();let p=t!==void 0?t:Yt(h)===Yt(d),m=()=>c(n,{replace:p,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a});l?b.startTransition(()=>m()):m()}},[h,c,d,t,r,e,n,i,s,o,a,l])}var Bx=0,$x=()=>`__${String(++Bx)}__`;function Fx(){let{router:n}=mm("useSubmit"),{basename:e}=b.useContext(mt),t=Gy(),r=n.fetch,i=n.navigate;return b.useCallback(async(s,o={})=>{let{action:a,method:l,encType:c,formData:h,body:d}=px(s,e);if(o.navigate===!1){let f=o.fetcherKey||$x();await r(f,t,o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:h,body:d,formMethod:o.method||l,formEncType:o.encType||c,flushSync:o.flushSync})}else await i(o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:h,body:d,formMethod:o.method||l,formEncType:o.encType||c,replace:o.replace,state:o.state,fromRouteId:t,flushSync:o.flushSync,viewTransition:o.viewTransition})},[r,i,e,t])}function Vx(n,{relative:e}={}){let{basename:t}=b.useContext(mt),r=b.useContext(jt);he(r,"useFormAction must be used inside a RouteContext");let[i]=r.matches.slice(-1),s={...Ds(n||".",{relative:e})},o=Qt();if(n==null){s.search=o.search;let a=new URLSearchParams(s.search),l=a.getAll("index");if(l.some(h=>h==="")){a.delete("index"),l.filter(d=>d).forEach(d=>a.append("index",d));let h=a.toString();s.search=h?`?${h}`:""}}return(!n||n===".")&&i.route.index&&(s.search=s.search?s.search.replace(/^\?/,"?index&"):"?index"),t!=="/"&&(s.pathname=s.pathname==="/"?t:Gt([t,s.pathname])),Yt(s)}function zx(n,{relative:e}={}){let t=b.useContext(nh);he(t!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=mm("useViewTransitionState"),i=Ds(n,{relative:e});if(!t.isTransitioning)return!1;let s=Ct(t.currentLocation.pathname,r)||t.currentLocation.pathname,o=Ct(t.nextLocation.pathname,r)||t.nextLocation.pathname;return _o(i.pathname,o)!=null||_o(i.pathname,s)!=null}function Hx(n){return b.createElement(nx,{flushSync:Rp.flushSync,...n})}const Wx={en:{loading:"Loading...",error:"Error",selectProject:"Select a project to view dashboard",controlCenter:"Control Center",settings:"Settings",sync:"Sync",offline:"Offline",switchToLight:"Switch to light mode",switchToDark:"Switch to dark mode",settingsSection:"Settings",configEditor:"Config Editor",projects:"Projects",addProject:"Add Project",global:"Global",skills:"Skills",health:"Health",collapse:"Collapse",expand:"Expand",installing:"Installing...",manage:"Manage",uninstall:"Uninstall",installGlobally:"Install Globally",installGloballyDesc:"Available to all projects instead of current project only",selectAtLeastOneAgent:"Please select at least one agent",installationFailed:"Installation failed",allSkills:"All Skills",refresh:"Refresh",browseAndManageSkills:"Browse and manage skills for your agents",detected:"Detected",notDetected:"Not detected",sessions:"sessions",noSessions:"No sessions",terminal:"Terminal",terminalSub:"Open bash at path",editor:"Editor",editorSub:"Open in VS Code",launch:"Launch",launchSub:"Start Claude Code",config:"Config",configSub:"Manage project settings",recentSessions:"Recent Sessions",viewAllHistory:"View All History",showLess:"Show Less",actionFailed:"Action failed",loadingSessions:"Loading sessions...",noSessionsFound:"No sessions found",configuration:"Claude Settings",activeKit:"Active Kit",aiModel:"Model",hooks:"Hooks",active:"active",mcpServers:"MCP Servers",connected:"connected",editProjectConfig:"Edit Project Config",globalSettings:"(Global)",globalSkills:"Global Skills",loadingSkills:"Loading skills...",noDescription:"No description",browseSkillsMarketplace:"Browse Skills Marketplace",backToDashboard:"Back to Dashboard",educationalConfigEditor:"Educational Config Editor",discard:"Discard",saveChanges:"Save Changes",mergedView:"Merged View",localConfig:"Local (.ck.json)",globalConfig:"Global",syntaxValid:"Syntax Valid",configurationHelp:"Configuration Help",field:"Field",type:"Type",default:"Default",description:"Description",validValues:"Valid Values",systemEffect:"System Effect",exampleUsage:"Example Usage",knowledgeBase:"Knowledge Base",clickToSeeHelp:"Click on any configuration field to see detailed documentation and usage examples.",extractedFrom:"Extracted from ClaudeKit v2.x Specification",resetToDefault:"Reset",saving:"Saving...",saved:"Saved",confirmReset:"Reset to Default?",confirmResetMessage:"All changes will be lost and replaced with default values.",confirm:"Confirm",saveFailed:"Save failed",configTab:"Config",systemTab:"System",formTab:"Form",jsonTab:"JSON",installedKit:"Installed Kit",kitVersion:"Kit Version",installedOn:"Installed On",noKitInstalled:"No kit installed",components:"Components",agents:"Agents",commands:"Commands",workflows:"Workflows",kitSkills:"Skills",fileOwnership:"File Ownership",ownershipCk:"kit-managed",ownershipUser:"user-owned",ownershipModified:"modified",componentInventory:"Component Inventory",installedHooks:"Installed Hooks",installedMcpServers:"MCP Servers",lastChecked:"Last update check",staleIndicator:"Stale",skippedVersion:"Skipped",filesModifiedFromDefaults:"files modified from kit defaults",cliCard:"ClaudeKit CLI",checkForUpdates:"Check for Updates",checking:"Checking...",upToDate:"Up to date",updateAvailable:"Update available",updateNow:"Update Now",updating:"Updating...",updateSuccess:"Update Complete!",updateFailed:"Update Failed",closeModal:"Close",showDetails:"Show Details",hideDetails:"Hide Details",environment:"Environment",claudeConfigPath:"Claude config",nodeVersion:"Node",bunVersion:"Bun",osVersion:"OS",channelStable:"Stable",channelBeta:"Beta",betaBadge:"Beta",latestVersion:"Latest",selectVersion:"Select version",loadingVersions:"Loading versions...",prereleaseLabel:"Pre",currentVersionLabel:"Current",checkAll:"Check All",checkingAll:"Checking...",updateAll:"Update All",updatesAvailable:"{count} updates available",allUpToDate:"All up to date",systemControlTower:"System Control Tower",systemOverviewTitle:"Update & Runtime Overview",systemOverviewDesc:"Track CLI and kit health, then run upgrades from one place.",installedComponentsHeading:"Installed Components",updateReadiness:"Update Readiness",checkedComponents:"Checked",activeChannel:"Channel",readyToScan:"Ready to scan",noTrackedFiles:"No tracked files detected",kitsLabel:"Kits",componentFilterAll:"All",componentFilterUpdates:"Updates",componentFilterUpToDate:"Up to date",componentFilterCli:"CLI",componentFilterKits:"Kits",noComponentsMatchFilter:"No components match the current filter.",configWorkspaceHint:"Edit configuration or manage system updates from one workspace.",addProjectTitle:"Add Project",addProjectDescription:"Add a new ClaudeKit project to the control center",projectPath:"Project Path",pathPlaceholder:"/path/to/project",alias:"Alias",aliasOptional:"(optional)",aliasPlaceholder:"my-project",aliasDescription:"Custom display name for the project",pathRequired:"Path is required",failedToAdd:"Failed to add project",cancel:"Cancel",adding:"Adding...",somethingWentWrong:"Something went wrong",reloadApp:"Reload App",serverNotRunning:"Server Not Running",startServerMessage:"The Config UI requires the backend server to be running.",runThisCommand:"Run this command",tryAgain:"Try Again",projectConfig:"Project Config",inheritedFromGlobal:"Inherited from Global",localOverride:"Local Override",viewGlobalConfig:"This field inherits from global config. View",onboardingTitle:"Welcome to ClaudeKit",onboardingSubtitle:"Choose your kit and get started in minutes",kitEngineerName:"ClaudeKit Engineer",kitEngineerTagline:"AI-powered coding with skills, hooks, and multi-agent workflows",kitMarketingName:"ClaudeKit Marketing",kitMarketingTagline:"Content automation: campaigns, social media, analytics",featureAgents:"AI Agents",featureAgentsDesc:"Specialized agents for different tasks",featureHooks:"Lifecycle Hooks",featureHooksDesc:"Customize Claude's behavior at key moments",featureSkills:"Skills Library",featureSkillsDesc:"Pre-built capabilities you can activate",featureMultiAgent:"Multi-Agent Workflows",featureMultiAgentDesc:"Coordinate multiple agents for complex tasks",featureContent:"Content Generation",featureContentDesc:"Automated content creation and optimization",featureSocial:"Social Media Tools",featureSocialDesc:"Scheduling, analytics, and engagement automation",stepChooseKit:"Choose Kit",stepConfigure:"Configure",stepInstall:"Install",back:"Back",next:"Next",install:"Install",installSuccess:"Installation Complete!",installSuccessDesc:"{kit} is ready to use",getStarted:"Get Started",goToDashboard:"Go to Dashboard",kitConfig:"Kit Config",kitConfigSubtitle:"Configure ClaudeKit Engineer settings",scopeGlobal:"Global",scopeProject:"Project",sectionGeneral:"General",sectionPaths:"Paths",sectionPrivacy:"Privacy & Trust",sectionProject:"Project Detection",sectionIntegrations:"Integrations",sectionHooks:"Hooks",sectionAdvanced:"Advanced",fieldCodingLevel:"Coding Level",fieldCodingLevelDesc:"Your coding experience level (-1=auto, 0=beginner, 1=intermediate, 2=advanced, 3=expert, 4=tech-lead, 5=god-mode)",fieldStatusline:"Statusline Mode",fieldStatuslineDesc:"How much info to show in the status line",fieldThinkingLanguage:"Thinking Language",fieldThinkingLanguageDesc:"Language for Claude's internal reasoning (null=English)",fieldResponseLanguage:"Response Language",fieldResponseLanguageDesc:"Language for Claude's responses (null=match user)",fieldDocsPath:"Docs Directory",fieldDocsPathDesc:"Path to documentation directory",fieldPlansPath:"Plans Directory",fieldPlansPathDesc:"Path to plans directory",fieldPrivacyBlock:"Privacy Block",fieldPrivacyBlockDesc:"Block access to sensitive files (.env, credentials)",fieldTrustEnabled:"Trust Mode",fieldTrustEnabledDesc:"Enable auto-approval for tool calls",fieldTrustPassphrase:"Trust Passphrase",fieldTrustPassphraseDesc:"Passphrase to enable trust mode",fieldProjectType:"Project Type",fieldProjectTypeDesc:"Override auto-detected project type",fieldPackageManager:"Package Manager",fieldPackageManagerDesc:"Override auto-detected package manager",fieldFramework:"Framework",fieldFrameworkDesc:"Override auto-detected framework",fieldGeminiModel:"Gemini Model",fieldGeminiModelDesc:"Gemini model for CLI commands",fieldResearchUseGemini:"Use Gemini for Research",fieldResearchUseGeminiDesc:"Use Gemini CLI instead of WebSearch",fieldDocsMaxLoc:"Max Lines per Doc",fieldDocsMaxLocDesc:"Maximum lines of code per documentation file",fieldPlanNamingFormat:"Plan Naming Format",fieldPlanNamingFormatDesc:"Format for plan directory names",fieldPlanDateFormat:"Plan Date Format",fieldPlanDateFormatDesc:"Date format for plan names (moment.js)",fieldPlanValidationMode:"Validation Mode",fieldPlanValidationModeDesc:"How to validate plans before implementation",fieldPlanMinQuestions:"Min Questions",fieldPlanMinQuestionsDesc:"Minimum validation questions",fieldPlanMaxQuestions:"Max Questions",fieldPlanMaxQuestionsDesc:"Maximum validation questions",fieldAssertions:"Assertions",fieldAssertionsDesc:"Code assertions and rules to enforce",fieldHookSessionInit:"Session Init",fieldHookSessionInitDesc:"Project detection and environment setup",fieldHookSubagentInit:"Subagent Init",fieldHookSubagentInitDesc:"Inject context to subagents",fieldHookDescriptiveName:"Descriptive Name",fieldHookDescriptiveNameDesc:"Enforce kebab-case descriptive file naming for scripts",fieldHookDevRulesReminder:"Dev Rules Reminder",fieldHookDevRulesReminderDesc:"Inject development rules context",fieldHookUsageContextAwareness:"Usage Context Awareness",fieldHookUsageContextAwarenessDesc:"Usage limits awareness",fieldHookContextTracking:"Context Tracking",fieldHookContextTrackingDesc:"Context window tracking (% used, token counts)",fieldHookScoutBlock:"Scout Block",fieldHookScoutBlockDesc:"Block heavy directories from exploration",fieldHookPrivacyBlock:"Privacy Block Hook",fieldHookPrivacyBlockDesc:"Block sensitive files from reading",fieldHookPostEditSimplify:"Post-Edit Simplify",fieldHookPostEditSimplifyDesc:"Simplify reminder after edits",skillsPageTitle:"Skills Management",skillsPageDesc:"Install ClaudeKit skills to your coding agents",availableSkills:"Available Skills",installedSkills:"Installed Skills",noSkillsFound:"No skills found",installSkill:"Install",uninstallSkill:"Uninstall",manageSkill:"Manage",syncRegistry:"Sync",installSkillTitle:"Install Skill",selectAgents:"Select target agents",installLocation:"Installation location",globalInstall:"Global",projectInstall:"Project",confirmInstall:"Install to selected agents",installingSkill:"Installing...",skillInstallSuccess:"Skill installed successfully",skillInstallFailed:"Installation failed",agentClaudeCode:"Claude Code",agentCursor:"Cursor",agentCodex:"Codex",agentOpencode:"OpenCode",agentGoose:"Goose",agentGeminiCli:"Gemini CLI",agentAntigravity:"Antigravity",agentGithubCopilot:"GitHub Copilot",agentAmp:"Amp",agentKilo:"Kilo",agentRoo:"Roo",agentWindsurf:"Windsurf",agentCline:"Cline",agentOpenhands:"OpenHands",installed:"Installed",notInstalled:"Not installed",allAgents:"All Agents",filterByAgent:"Filter by agent",skillsTitle:"Skills",skillsSubtitle:"Browse, install, and manage skills for your coding agents",availableCount:"Available",installedCount:"Installed",agentsCount:"Agents",searchSkills:"Search skills...",searchShortcut:"/",sortAZ:"A-Z",sortCategory:"Category",sortInstalledFirst:"Installed first",listView:"List view",gridView:"Grid view",categoryAll:"All",categoryAI:"AI",categoryUIUX:"UI/UX",categoryBackend:"Backend",categorySecurity:"Security",categoryDevOps:"DevOps",categoryDatabase:"Database",categoryDevelopment:"Development",categoryResearch:"Research",categoryGeneral:"General",categoryCore:"Core",categoryDocumentation:"Documentation",categoryTooling:"Tooling",categoryMedia:"Media",categoryFrameworks:"Frameworks",skillsCountLabel:"{count} skills",installToAll:"Install to All Detected",scopeLabel:"Installation Scope",agentInstalled:"Installed",agentNotInstalled:"Not installed",skillSource:"Source location",skillSourceBadge:"Source",detailPanelClose:"Close",versionLabel:"v{version}",installAllToAllAgents:"Install All to All Agents",bulkInstallFailed:"Bulk install failed",noAgentsDetected:"No agents detected",kitBadgeEngineer:"Engineer",kitBadgeMarketing:"Marketing",customizedBadge:"Customized",installedVersionLabel:"Installed Version",installedAtLabel:"Installed At",sourceTimestampLabel:"Source Date",kitLabel:"Kit",skillMetadata:"Skill Info",migrate:"Migrate",migrateTitle:"Migrate",migrateSubtitle:"Migrate your Claude Code stack to other providers",migrateDetectedProviders:"Detected",migrateSelectedProviders:"Selected",migrateDiscovering:"Discovering migration sources...",migrateRefresh:"Refresh Discovery",migrateRun:"Run Migration",migrateRunning:"Migrating...",migrateSourceSummary:"Source Summary",migratePresetCodex:"Codex",migratePresetAntigravity:"Antigravity",migratePresetBoth:"Codex + Antigravity",migratePresetDetected:"All Detected",migrateScope:"Scope",migrateScopeProject:"Project",migrateScopeGlobal:"Global",migrateTypes:"Portable Types",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateSearchProviders:"Search providers...",migrateSelectVisible:"Select Visible",migrateClearSelection:"Clear Selection",migrateProvidersHeading:"Target Providers",migrateProvidersCountSuffix:"providers",migrateNoProvidersMatch:"No providers match current filters.",migrateSelectButton:"Select",migrateSelectedButton:"Selected",migrateSelectProviderAction:"Select Provider",migrateUnselectProvider:"Unselect Provider",migrateCapabilitiesLabel:"types",migrateCapabilitiesSection:"Capability Matrix",migrateSupported:"Supported",migrateUnsupportedShort:"Unsupported",migrateIncludedEnabled:"Enabled",migrateIncludedDisabled:"Disabled",migrateLatestTarget:"Latest Target",migrateNoResultForProvider:"No migration result for this provider yet.",migrateActionSummaryTitle:"Ready to Migrate",migrateGlobalOnlyCommandsShort:"Commands global-only",migrateNoProviders:"No providers available.",migrateUnsupported:"Will be skipped (unsupported)",migrateGlobalForced:"Codex commands are global-only. Scope will be forced to global.",migrateResults:"Migration Results",migrateInstalled:"Installed",migrateSkipped:"Skipped",migrateFailed:"Failed",migrateProvider:"Provider",migrateStatus:"Status",migratePath:"Path",migrateError:"Error",migrateStatusInstalled:"Installed",migrateStatusSkipped:"Skipped",migrateStatusFailed:"Failed",migrateNoResults:"No migration results yet.",migrateDetectFailed:"Failed to discover migration data",migrateExecuteFailed:"Migration execution failed",migrateSelectProvider:"Select at least one provider",migrateNoTypesEnabled:"Enable at least one portable type",migrateDetectedTag:"Detected",migrateNotDetectedTag:"Not detected",migrateFilterRecommended:"Recommended",developmentFeature:"Development",betaFeature:"Beta",experimentalFeature:"Experimental"},vi:{loading:"Đang tải...",error:"Lỗi",selectProject:"Chọn dự án để xem bảng điều khiển",controlCenter:"Trung tâm điều khiển",settings:"Cài đặt",sync:"Đồng bộ",offline:"Ngoại tuyến",switchToLight:"Chuyển sang chế độ sáng",switchToDark:"Chuyển sang chế độ tối",settingsSection:"Cài đặt",configEditor:"Trình chỉnh sửa cấu hình",projects:"Dự án",addProject:"Thêm dự án",global:"Toàn cục",skills:"Kỹ năng",health:"Sức khỏe",collapse:"Thu gọn",expand:"Mở rộng",installing:"Đang cài đặt...",manage:"Quản lý",uninstall:"Gỡ cài đặt",installGlobally:"Cài đặt toàn cục",installGloballyDesc:"Khả dụng cho tất cả dự án thay vì chỉ dự án hiện tại",selectAtLeastOneAgent:"Vui lòng chọn ít nhất một agent",installationFailed:"Cài đặt thất bại",allSkills:"Tất cả kỹ năng",refresh:"Làm mới",browseAndManageSkills:"Duyệt và quản lý kỹ năng cho agents của bạn",detected:"Đã phát hiện",notDetected:"Chưa phát hiện",sessions:"phiên",noSessions:"Không có phiên",terminal:"Terminal",terminalSub:"Mở bash tại đường dẫn",editor:"Trình soạn thảo",editorSub:"Mở trong VS Code",launch:"Khởi chạy",launchSub:"Bắt đầu Claude Code",config:"Cấu hình",configSub:"Quản lý cài đặt dự án",recentSessions:"Phiên gần đây",viewAllHistory:"Xem tất cả lịch sử",showLess:"Thu gọn",actionFailed:"Thao tác thất bại",loadingSessions:"Đang tải phiên...",noSessionsFound:"Không tìm thấy phiên nào",configuration:"Cài đặt Claude",activeKit:"Kit hoạt động",aiModel:"Mô hình",hooks:"Hooks",active:"hoạt động",mcpServers:"Máy chủ MCP",connected:"kết nối",editProjectConfig:"Chỉnh sửa cấu hình dự án",globalSettings:"(Toàn cục)",globalSkills:"Kỹ năng toàn cục",loadingSkills:"Đang tải kỹ năng...",noDescription:"Không có mô tả",browseSkillsMarketplace:"Duyệt Skills Marketplace",backToDashboard:"Quay lại bảng điều khiển",educationalConfigEditor:"Trình chỉnh sửa cấu hình hướng dẫn",discard:"Hủy bỏ",saveChanges:"Lưu thay đổi",mergedView:"Chế độ gộp",localConfig:"Cục bộ (.ck.json)",globalConfig:"Toàn cục",syntaxValid:"Cú pháp hợp lệ",configurationHelp:"Hướng dẫn cấu hình",field:"Trường",type:"Kiểu",default:"Mặc định",description:"Mô tả",validValues:"Giá trị hợp lệ",systemEffect:"Hiệu ứng hệ thống",exampleUsage:"Ví dụ sử dụng",knowledgeBase:"Cơ sở kiến thức",clickToSeeHelp:"Nhấp vào bất kỳ trường cấu hình nào để xem tài liệu chi tiết và ví dụ sử dụng.",extractedFrom:"Trích xuất từ ClaudeKit v2.x Specification",resetToDefault:"Đặt lại",saving:"Đang lưu...",saved:"Đã lưu",confirmReset:"Đặt lại về mặc định?",confirmResetMessage:"Tất cả thay đổi sẽ bị mất và được thay thế bằng giá trị mặc định.",confirm:"Xác nhận",saveFailed:"Lưu thất bại",configTab:"Cấu hình",systemTab:"Hệ thống",formTab:"Biểu mẫu",jsonTab:"JSON",installedKit:"Kit đã cài",kitVersion:"Phiên bản Kit",installedOn:"Cài đặt vào",noKitInstalled:"Chưa cài kit",components:"Thành phần",agents:"Agents",commands:"Commands",workflows:"Workflows",kitSkills:"Skills",fileOwnership:"Quyền sở hữu tệp",ownershipCk:"do kit quản lý",ownershipUser:"do người dùng",ownershipModified:"đã chỉnh sửa",componentInventory:"Thành phần đã cài",installedHooks:"Hooks đã cài",installedMcpServers:"MCP Servers",lastChecked:"Kiểm tra cập nhật",staleIndicator:"Cũ",skippedVersion:"Đã bỏ qua",filesModifiedFromDefaults:"tệp đã sửa so với mặc định",cliCard:"ClaudeKit CLI",checkForUpdates:"Kiểm tra cập nhật",checking:"Đang kiểm tra...",upToDate:"Đã cập nhật",updateAvailable:"Có bản cập nhật",updateNow:"Cập nhật ngay",updating:"Đang cập nhật...",updateSuccess:"Cập nhật hoàn tất!",updateFailed:"Cập nhật thất bại",closeModal:"Đóng",showDetails:"Xem chi tiết",hideDetails:"Ẩn chi tiết",environment:"Môi trường",claudeConfigPath:"Cấu hình Claude",nodeVersion:"Node",bunVersion:"Bun",osVersion:"Hệ điều hành",channelStable:"Ổn định",channelBeta:"Beta",betaBadge:"Beta",latestVersion:"Mới nhất",selectVersion:"Chọn phiên bản",loadingVersions:"Đang tải...",prereleaseLabel:"Thử nghiệm",currentVersionLabel:"Hiện tại",checkAll:"Kiểm tra tất cả",checkingAll:"Đang kiểm tra...",updateAll:"Cập nhật tất cả",updatesAvailable:"{count} bản cập nhật",allUpToDate:"Tất cả đã cập nhật",systemControlTower:"Trung tâm hệ thống",systemOverviewTitle:"Tổng quan cập nhật & môi trường",systemOverviewDesc:"Theo dõi CLI và kit, rồi nâng cấp từ một nơi.",installedComponentsHeading:"Thành phần đã cài",updateReadiness:"Mức sẵn sàng cập nhật",checkedComponents:"Đã kiểm tra",activeChannel:"Kênh",readyToScan:"Sẵn sàng kiểm tra",noTrackedFiles:"Không phát hiện tệp theo dõi",kitsLabel:"Kit",componentFilterAll:"Tất cả",componentFilterUpdates:"Bản cập nhật",componentFilterUpToDate:"Đã cập nhật",componentFilterCli:"CLI",componentFilterKits:"Kit",noComponentsMatchFilter:"Không có thành phần phù hợp bộ lọc hiện tại.",configWorkspaceHint:"Chỉnh sửa cấu hình hoặc quản lý cập nhật hệ thống trong một màn hình.",addProjectTitle:"Thêm dự án",addProjectDescription:"Thêm dự án ClaudeKit mới vào trung tâm điều khiển",projectPath:"Đường dẫn dự án",pathPlaceholder:"/đường/dẫn/dự/án",alias:"Bí danh",aliasOptional:"(tùy chọn)",aliasPlaceholder:"dự-án-của-tôi",aliasDescription:"Tên hiển thị tùy chỉnh cho dự án",pathRequired:"Đường dẫn bắt buộc",failedToAdd:"Không thể thêm dự án",cancel:"Hủy",adding:"Đang thêm...",somethingWentWrong:"Đã xảy ra lỗi",reloadApp:"Tải lại ứng dụng",serverNotRunning:"Máy chủ không chạy",startServerMessage:"Config UI yêu cầu máy chủ backend đang chạy.",runThisCommand:"Chạy lệnh này",tryAgain:"Thử lại",projectConfig:"Cấu hình dự án",inheritedFromGlobal:"Kế thừa từ toàn cục",localOverride:"Ghi đè cục bộ",viewGlobalConfig:"Trường này kế thừa từ cấu hình toàn cục. Xem",onboardingTitle:"Chào mừng đến ClaudeKit",onboardingSubtitle:"Chọn kit của bạn và bắt đầu trong vài phút",kitEngineerName:"ClaudeKit Engineer",kitEngineerTagline:"Lập trình AI với skills, hooks và multi-agent",kitMarketingName:"ClaudeKit Marketing",kitMarketingTagline:"Tự động hóa nội dung: chiến dịch, mạng xã hội, phân tích",featureAgents:"AI Agents",featureAgentsDesc:"Các agent chuyên biệt cho từng tác vụ",featureHooks:"Lifecycle Hooks",featureHooksDesc:"Tùy chỉnh hành vi của Claude tại các thời điểm quan trọng",featureSkills:"Thư viện Skills",featureSkillsDesc:"Các khả năng có sẵn bạn có thể kích hoạt",featureMultiAgent:"Multi-Agent Workflows",featureMultiAgentDesc:"Phối hợp nhiều agent cho các tác vụ phức tạp",featureContent:"Tạo nội dung",featureContentDesc:"Tự động tạo và tối ưu nội dung",featureSocial:"Công cụ mạng xã hội",featureSocialDesc:"Lên lịch, phân tích và tự động tương tác",stepChooseKit:"Chọn Kit",stepConfigure:"Cấu hình",stepInstall:"Cài đặt",back:"Quay lại",next:"Tiếp theo",install:"Cài đặt",installSuccess:"Cài đặt hoàn tất!",installSuccessDesc:"{kit} đã sẵn sàng sử dụng",getStarted:"Bắt đầu",goToDashboard:"Đi đến Dashboard",kitConfig:"Cấu hình Kit",kitConfigSubtitle:"Cấu hình ClaudeKit Engineer",scopeGlobal:"Toàn cục",scopeProject:"Dự án",sectionGeneral:"Cài đặt chung",sectionPaths:"Đường dẫn",sectionPrivacy:"Bảo mật & Tin cậy",sectionProject:"Phát hiện dự án",sectionIntegrations:"Tích hợp",sectionHooks:"Hooks",sectionAdvanced:"Nâng cao",fieldCodingLevel:"Cấp độ lập trình",fieldCodingLevelDesc:"Cấp độ kinh nghiệm (-1=tự động, 0=mới bắt đầu, 1=trung cấp, 2=nâng cao, 3=chuyên gia, 4=tech-lead, 5=thần)",fieldStatusline:"Chế độ thanh trạng thái",fieldStatuslineDesc:"Lượng thông tin hiển thị trên thanh trạng thái",fieldThinkingLanguage:"Ngôn ngữ suy nghĩ",fieldThinkingLanguageDesc:"Ngôn ngữ cho suy luận nội bộ của Claude (null=Tiếng Anh)",fieldResponseLanguage:"Ngôn ngữ phản hồi",fieldResponseLanguageDesc:"Ngôn ngữ cho phản hồi của Claude (null=theo người dùng)",fieldDocsPath:"Thư mục tài liệu",fieldDocsPathDesc:"Đường dẫn đến thư mục tài liệu",fieldPlansPath:"Thư mục kế hoạch",fieldPlansPathDesc:"Đường dẫn đến thư mục kế hoạch",fieldPrivacyBlock:"Chặn quyền riêng tư",fieldPrivacyBlockDesc:"Chặn truy cập file nhạy cảm (.env, credentials)",fieldTrustEnabled:"Chế độ tin cậy",fieldTrustEnabledDesc:"Tự động phê duyệt các tool calls",fieldTrustPassphrase:"Mật khẩu tin cậy",fieldTrustPassphraseDesc:"Mật khẩu để bật chế độ tin cậy",fieldProjectType:"Loại dự án",fieldProjectTypeDesc:"Ghi đè loại dự án tự động phát hiện",fieldPackageManager:"Trình quản lý gói",fieldPackageManagerDesc:"Ghi đè trình quản lý gói tự động phát hiện",fieldFramework:"Framework",fieldFrameworkDesc:"Ghi đè framework tự động phát hiện",fieldGeminiModel:"Mô hình Gemini",fieldGeminiModelDesc:"Mô hình Gemini cho các lệnh CLI",fieldResearchUseGemini:"Dùng Gemini cho nghiên cứu",fieldResearchUseGeminiDesc:"Dùng Gemini CLI thay vì WebSearch",fieldDocsMaxLoc:"Số dòng tối đa/tài liệu",fieldDocsMaxLocDesc:"Số dòng code tối đa cho mỗi file tài liệu",fieldPlanNamingFormat:"Định dạng tên kế hoạch",fieldPlanNamingFormatDesc:"Định dạng cho tên thư mục kế hoạch",fieldPlanDateFormat:"Định dạng ngày kế hoạch",fieldPlanDateFormatDesc:"Định dạng ngày cho tên kế hoạch (moment.js)",fieldPlanValidationMode:"Chế độ xác thực",fieldPlanValidationModeDesc:"Cách xác thực kế hoạch trước khi triển khai",fieldPlanMinQuestions:"Số câu hỏi tối thiểu",fieldPlanMinQuestionsDesc:"Số câu hỏi xác thực tối thiểu",fieldPlanMaxQuestions:"Số câu hỏi tối đa",fieldPlanMaxQuestionsDesc:"Số câu hỏi xác thực tối đa",fieldAssertions:"Assertions",fieldAssertionsDesc:"Các assertions và quy tắc cần thực thi",fieldHookSessionInit:"Khởi tạo phiên",fieldHookSessionInitDesc:"Phát hiện dự án và thiết lập môi trường",fieldHookSubagentInit:"Khởi tạo subagent",fieldHookSubagentInitDesc:"Inject context vào subagents",fieldHookDescriptiveName:"Tên mô tả",fieldHookDescriptiveNameDesc:"Bắt buộc đặt tên file dạng kebab-case mô tả cho scripts",fieldHookDevRulesReminder:"Nhắc nhở quy tắc dev",fieldHookDevRulesReminderDesc:"Inject context quy tắc phát triển",fieldHookUsageContextAwareness:"Nhận thức ngữ cảnh sử dụng",fieldHookUsageContextAwarenessDesc:"Nhận thức giới hạn sử dụng",fieldHookContextTracking:"Theo dõi ngữ cảnh",fieldHookContextTrackingDesc:"Theo dõi cửa sổ ngữ cảnh (% đã dùng, số token)",fieldHookScoutBlock:"Chặn Scout",fieldHookScoutBlockDesc:"Chặn thư mục nặng khỏi việc khám phá",fieldHookPrivacyBlock:"Hook chặn quyền riêng tư",fieldHookPrivacyBlockDesc:"Chặn đọc file nhạy cảm",fieldHookPostEditSimplify:"Đơn giản sau chỉnh sửa",fieldHookPostEditSimplifyDesc:"Nhắc đơn giản sau khi chỉnh sửa",skillsPageTitle:"Quản lý Kỹ năng",skillsPageDesc:"Cài đặt kỹ năng ClaudeKit cho các agent lập trình",availableSkills:"Kỹ năng có sẵn",installedSkills:"Kỹ năng đã cài",noSkillsFound:"Không tìm thấy kỹ năng",installSkill:"Cài đặt",uninstallSkill:"Gỡ cài đặt",manageSkill:"Quản lý",syncRegistry:"Đồng bộ",installSkillTitle:"Cài đặt Kỹ năng",selectAgents:"Chọn agent đích",installLocation:"Vị trí cài đặt",globalInstall:"Toàn cục",projectInstall:"Dự án",confirmInstall:"Cài đặt cho các agent đã chọn",installingSkill:"Đang cài đặt...",skillInstallSuccess:"Cài đặt kỹ năng thành công",skillInstallFailed:"Cài đặt thất bại",agentClaudeCode:"Claude Code",agentCursor:"Cursor",agentCodex:"Codex",agentOpencode:"OpenCode",agentGoose:"Goose",agentGeminiCli:"Gemini CLI",agentAntigravity:"Antigravity",agentGithubCopilot:"GitHub Copilot",agentAmp:"Amp",agentKilo:"Kilo",agentRoo:"Roo",agentWindsurf:"Windsurf",agentCline:"Cline",agentOpenhands:"OpenHands",installed:"Đã cài",notInstalled:"Chưa cài",allAgents:"Tất cả Agent",filterByAgent:"Lọc theo agent",skillsTitle:"Kỹ năng",skillsSubtitle:"Duyệt, cài đặt và quản lý kỹ năng cho coding agents",availableCount:"Có sẵn",installedCount:"Đã cài",agentsCount:"Agents",searchSkills:"Tìm kiếm kỹ năng...",searchShortcut:"/",sortAZ:"A-Z",sortCategory:"Danh mục",sortInstalledFirst:"Đã cài trước",listView:"Dạng danh sách",gridView:"Dạng lưới",categoryAll:"Tất cả",categoryAI:"AI",categoryUIUX:"UI/UX",categoryBackend:"Backend",categorySecurity:"Bảo mật",categoryDevOps:"DevOps",categoryDatabase:"Cơ sở dữ liệu",categoryDevelopment:"Phát triển",categoryResearch:"Nghiên cứu",categoryGeneral:"Tổng quát",categoryCore:"Cốt lõi",categoryDocumentation:"Tài liệu",categoryTooling:"Công cụ",categoryMedia:"Phương tiện",categoryFrameworks:"Framework",skillsCountLabel:"{count} kỹ năng",installToAll:"Cài cho tất cả đã phát hiện",scopeLabel:"Phạm vi cài đặt",agentInstalled:"Đã cài",agentNotInstalled:"Chưa cài",skillSource:"Vị trí nguồn",skillSourceBadge:"Nguồn",detailPanelClose:"Đóng",versionLabel:"v{version}",installAllToAllAgents:"Cài tất cả cho tất cả Agent",bulkInstallFailed:"Cài hàng loạt thất bại",noAgentsDetected:"Không phát hiện agent nào",kitBadgeEngineer:"Engineer",kitBadgeMarketing:"Marketing",customizedBadge:"Đã tùy chỉnh",installedVersionLabel:"Phiên bản cài đặt",installedAtLabel:"Cài đặt lúc",sourceTimestampLabel:"Ngày nguồn",kitLabel:"Kit",skillMetadata:"Thông tin Skill",migrate:"Di trú",migrateTitle:"Di trú",migrateSubtitle:"Chuyển toàn bộ stack Claude Code sang provider khác",migrateDetectedProviders:"Đã phát hiện",migrateSelectedProviders:"Đã chọn",migrateDiscovering:"Đang quét nguồn di trú...",migrateRefresh:"Làm mới quét",migrateRun:"Chạy di trú",migrateRunning:"Đang di trú...",migrateSourceSummary:"Tổng quan nguồn",migratePresetCodex:"Codex",migratePresetAntigravity:"Antigravity",migratePresetBoth:"Codex + Antigravity",migratePresetDetected:"Tất cả đã phát hiện",migrateScope:"Phạm vi",migrateScopeProject:"Dự án",migrateScopeGlobal:"Toàn cục",migrateTypes:"Loại di trú",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateSearchProviders:"Tìm provider...",migrateSelectVisible:"Chọn phần đang hiện",migrateClearSelection:"Bỏ chọn tất cả",migrateProvidersHeading:"Provider đích",migrateProvidersCountSuffix:"provider",migrateNoProvidersMatch:"Không có provider khớp bộ lọc hiện tại.",migrateSelectButton:"Chọn",migrateSelectedButton:"Đã chọn",migrateSelectProviderAction:"Chọn provider",migrateUnselectProvider:"Bỏ chọn provider",migrateCapabilitiesLabel:"loại",migrateCapabilitiesSection:"Ma trận khả năng",migrateSupported:"Hỗ trợ",migrateUnsupportedShort:"Không hỗ trợ",migrateIncludedEnabled:"Đang bật",migrateIncludedDisabled:"Đang tắt",migrateLatestTarget:"Đích gần nhất",migrateNoResultForProvider:"Chưa có kết quả di trú cho provider này.",migrateActionSummaryTitle:"Sẵn sàng di trú",migrateGlobalOnlyCommandsShort:"Commands chỉ global",migrateNoProviders:"Không có provider khả dụng.",migrateUnsupported:"Sẽ bỏ qua (không hỗ trợ)",migrateGlobalForced:"Lệnh Codex chỉ hỗ trợ global. Phạm vi sẽ tự chuyển global.",migrateResults:"Kết quả di trú",migrateInstalled:"Đã cài",migrateSkipped:"Đã bỏ qua",migrateFailed:"Lỗi",migrateProvider:"Provider",migrateStatus:"Trạng thái",migratePath:"Đường dẫn",migrateError:"Lỗi",migrateStatusInstalled:"Đã cài",migrateStatusSkipped:"Đã bỏ qua",migrateStatusFailed:"Lỗi",migrateNoResults:"Chưa có kết quả di trú.",migrateDetectFailed:"Không thể quét dữ liệu di trú",migrateExecuteFailed:"Chạy di trú thất bại",migrateSelectProvider:"Vui lòng chọn ít nhất một provider",migrateNoTypesEnabled:"Bật ít nhất một loại di trú",migrateDetectedTag:"Đã phát hiện",migrateNotDetectedTag:"Chưa phát hiện",migrateFilterRecommended:"Đề xuất",developmentFeature:"Đang phát triển",betaFeature:"Beta",experimentalFeature:"Thử nghiệm"}},lh=b.createContext(null),gm="ck-dashboard-lang";function _x(){const n=localStorage.getItem(gm);return n==="en"||n==="vi"?n:navigator.language.startsWith("vi")?"vi":"en"}function Ux({children:n}){const[e,t]=b.useState(_x),r=s=>{localStorage.setItem(gm,s),t(s)},i=s=>Wx[e][s];return u.jsx(lh.Provider,{value:{lang:e,setLang:r,t:i},children:n})}function xe(){const n=b.useContext(lh);if(!n)throw new Error("useI18n must be used within I18nProvider");return n}class Kx extends b.Component{constructor(){super(...arguments);du(this,"state",{hasError:!1,error:null})}static getDerivedStateFromError(t){return{hasError:!0,error:t}}componentDidCatch(t,r){console.error("App error:",t,r.componentStack)}render(){if(this.state.hasError){const t=this.state.error?.name==="ServerUnavailableError";return u.jsx(lh.Consumer,{children:r=>u.jsx("div",{className:"flex h-screen items-center justify-center bg-dash-bg",children:u.jsx("div",{className:"text-center space-y-4 max-w-md px-6",children:t?u.jsxs(u.Fragment,{children:[u.jsx("div",{className:"w-16 h-16 mx-auto rounded-full bg-orange-500/10 border border-orange-500/30 flex items-center justify-center text-3xl",children:"🔌"}),u.jsx("h1",{className:"text-2xl font-bold text-orange-500",children:r?.t("serverNotRunning")??"Server Not Running"}),u.jsx("p",{className:"text-dash-text-secondary",children:r?.t("startServerMessage")??"The Config UI requires the backend server to be running."}),u.jsxs("div",{className:"bg-dash-surface border border-dash-border rounded-lg p-4",children:[u.jsx("p",{className:"text-xs text-dash-text-muted uppercase tracking-widest mb-2 font-bold",children:r?.t("runThisCommand")??"Run this command"}),u.jsx("code",{className:"block text-sm text-dash-accent font-mono bg-dash-bg px-3 py-2 rounded border border-dash-border",children:"ck config"})]}),u.jsx("button",{onClick:()=>window.location.reload(),className:"px-6 py-2 bg-dash-accent text-dash-bg rounded-lg font-bold hover:bg-dash-accent-hover transition-colors",children:r?.t("tryAgain")??"Try Again"})]}):u.jsxs(u.Fragment,{children:[u.jsx("h1",{className:"text-2xl font-bold text-red-500",children:r?.t("somethingWentWrong")??"Something went wrong"}),u.jsx("p",{className:"text-dash-text-muted",children:this.state.error?.message}),u.jsx("button",{onClick:()=>window.location.reload(),className:"px-4 py-2 bg-dash-accent text-white rounded-md hover:opacity-90",children:r?.t("reloadApp")??"Reload App"})]})})})})}return this.props.children}}const Ci=({direction:n="horizontal",isDragging:e=!1,onMouseDown:t})=>{const r=n==="horizontal";return u.jsx("div",{onMouseDown:t,className:`
22
22
  group flex items-center justify-center shrink-0
23
23
  ${r?"w-2 cursor-col-resize":"h-2 cursor-row-resize"}
24
24
  ${e?"bg-dash-accent/20":"hover:bg-dash-surface-hover/50"}
@@ -71,7 +71,7 @@
71
71
  background: var(--dash-text-muted);
72
72
  }
73
73
  </style>
74
- <script type="module" crossorigin src="/assets/index-Bfnll20K.js"></script>
74
+ <script type="module" crossorigin src="/assets/index-Ct51I-3k.js"></script>
75
75
  <link rel="modulepreload" crossorigin href="/assets/vendor-DNUgy55u.js">
76
76
  <link rel="stylesheet" crossorigin href="/assets/index-BQE1sjky.css">
77
77
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "3.35.0-dev.8",
3
+ "version": "3.35.0-dev.9",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {