claudekit-cli 3.36.0-dev.24 → 3.36.0-dev.26
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/dist/index.js
CHANGED
|
@@ -6905,6 +6905,65 @@ var init_checksum_utils = __esm(() => {
|
|
|
6905
6905
|
BINARY_DETECTION_SAMPLE_BYTES = 8 * 1024;
|
|
6906
6906
|
});
|
|
6907
6907
|
|
|
6908
|
+
// src/commands/portable/model-taxonomy.ts
|
|
6909
|
+
function setTaxonomyOverrides(overrides) {
|
|
6910
|
+
userOverrides = overrides;
|
|
6911
|
+
}
|
|
6912
|
+
function resolveModel(sourceModel, targetProvider) {
|
|
6913
|
+
if (sourceModel === undefined || sourceModel === null) {
|
|
6914
|
+
return { resolved: null };
|
|
6915
|
+
}
|
|
6916
|
+
if (typeof sourceModel !== "string") {
|
|
6917
|
+
return {
|
|
6918
|
+
resolved: null,
|
|
6919
|
+
warning: `Ignored non-string model frontmatter (${typeof sourceModel})`
|
|
6920
|
+
};
|
|
6921
|
+
}
|
|
6922
|
+
const trimmed = sourceModel.trim();
|
|
6923
|
+
if (!trimmed || trimmed === "inherit") {
|
|
6924
|
+
return { resolved: null };
|
|
6925
|
+
}
|
|
6926
|
+
const tier = SOURCE_TIER_MAP[trimmed];
|
|
6927
|
+
if (!tier) {
|
|
6928
|
+
return {
|
|
6929
|
+
resolved: null,
|
|
6930
|
+
warning: `Unknown model "${trimmed}" — not in taxonomy, commented out`
|
|
6931
|
+
};
|
|
6932
|
+
}
|
|
6933
|
+
const overrideMap = userOverrides?.[targetProvider];
|
|
6934
|
+
if (overrideMap) {
|
|
6935
|
+
const override = overrideMap[tier];
|
|
6936
|
+
if (override) {
|
|
6937
|
+
return { resolved: override };
|
|
6938
|
+
}
|
|
6939
|
+
}
|
|
6940
|
+
const providerMap = DEFAULT_PROVIDER_MODEL_MAP[targetProvider];
|
|
6941
|
+
if (!providerMap) {
|
|
6942
|
+
return { resolved: null };
|
|
6943
|
+
}
|
|
6944
|
+
return { resolved: providerMap[tier] };
|
|
6945
|
+
}
|
|
6946
|
+
var SOURCE_TIER_MAP, DEFAULT_PROVIDER_MODEL_MAP, userOverrides;
|
|
6947
|
+
var init_model_taxonomy = __esm(() => {
|
|
6948
|
+
SOURCE_TIER_MAP = {
|
|
6949
|
+
opus: "heavy",
|
|
6950
|
+
sonnet: "balanced",
|
|
6951
|
+
haiku: "light"
|
|
6952
|
+
};
|
|
6953
|
+
DEFAULT_PROVIDER_MODEL_MAP = {
|
|
6954
|
+
codex: {
|
|
6955
|
+
heavy: { model: "gpt-5.4", effort: "xhigh" },
|
|
6956
|
+
balanced: { model: "gpt-5.4", effort: "high" },
|
|
6957
|
+
light: { model: "gpt-5.4-mini", effort: "medium" }
|
|
6958
|
+
},
|
|
6959
|
+
"gemini-cli": {
|
|
6960
|
+
heavy: { model: "gemini-3.1-pro-preview" },
|
|
6961
|
+
balanced: { model: "gemini-3.1-pro-preview" },
|
|
6962
|
+
light: { model: "gemini-3-flash-preview" }
|
|
6963
|
+
}
|
|
6964
|
+
};
|
|
6965
|
+
});
|
|
6966
|
+
|
|
6908
6967
|
// src/commands/portable/converters/md-to-toml.ts
|
|
6909
6968
|
function escapeTomlMultiline(str2) {
|
|
6910
6969
|
let escaped = str2.replace(/\\/g, "\\\\");
|
|
@@ -6987,12 +7046,17 @@ function convertFmToCodexToml(item) {
|
|
|
6987
7046
|
const warnings = [];
|
|
6988
7047
|
const slug = toCodexSlug(item.name);
|
|
6989
7048
|
const lines = [];
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
7049
|
+
const modelResult = resolveModel(item.frontmatter.model, "codex");
|
|
7050
|
+
if (modelResult.warning) {
|
|
7051
|
+
warnings.push(modelResult.warning);
|
|
7052
|
+
}
|
|
7053
|
+
if (modelResult.resolved) {
|
|
7054
|
+
lines.push(`model = ${JSON.stringify(modelResult.resolved.model)}`);
|
|
7055
|
+
if (modelResult.resolved.effort) {
|
|
7056
|
+
lines.push(`effort = ${JSON.stringify(modelResult.resolved.effort)}`);
|
|
6995
7057
|
}
|
|
7058
|
+
} else if (typeof item.frontmatter.model === "string" && item.frontmatter.model.trim().length > 0 && item.frontmatter.model.trim() !== "inherit") {
|
|
7059
|
+
lines.push(`# model = ${JSON.stringify(item.frontmatter.model.trim())}`);
|
|
6996
7060
|
}
|
|
6997
7061
|
const sandboxResult = deriveSandboxMode(item.frontmatter.tools);
|
|
6998
7062
|
if (sandboxResult.warning) {
|
|
@@ -7030,7 +7094,9 @@ function buildCodexConfigEntry(name, description) {
|
|
|
7030
7094
|
`);
|
|
7031
7095
|
}
|
|
7032
7096
|
var MAX_CODEX_SLUG_LENGTH = 96;
|
|
7033
|
-
var init_fm_to_codex_toml = () => {
|
|
7097
|
+
var init_fm_to_codex_toml = __esm(() => {
|
|
7098
|
+
init_model_taxonomy();
|
|
7099
|
+
});
|
|
7034
7100
|
|
|
7035
7101
|
// node_modules/kind-of/index.js
|
|
7036
7102
|
var require_kind_of = __commonJS((exports, module) => {
|
|
@@ -38991,7 +39057,7 @@ var init_claudekit_data = __esm(() => {
|
|
|
38991
39057
|
});
|
|
38992
39058
|
|
|
38993
39059
|
// src/types/ck-config.ts
|
|
38994
|
-
var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GeminiModelSchema, StatuslineModeSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, CkPlanConfigSchema, CkDocsConfigSchema, CkPathsConfigSchema, CkLocaleConfigSchema, CkTrustConfigSchema, CkProjectConfigSchema, CkGeminiConfigSchema, CkSkillsConfigSchema, CkAssertionSchema, CkHooksConfigSchema, CkConfigSchema, DEFAULT_CK_CONFIG, CK_HOOK_NAMES;
|
|
39060
|
+
var PlanValidationModeSchema, PlanFocusAreaSchema, PlanResolutionOrderSchema, ProjectTypeSchema, PackageManagerSchema, FrameworkSchema, GeminiModelSchema, StatuslineModeSchema, CodingLevelSchema, PlanResolutionSchema, PlanValidationSchema, CkPlanConfigSchema, CkDocsConfigSchema, CkPathsConfigSchema, CkLocaleConfigSchema, CkTrustConfigSchema, CkProjectConfigSchema, CkGeminiConfigSchema, CkSkillsConfigSchema, ResolvedModelConfigSchema, ModelTierMapSchema, CkModelTaxonomySchema, CkAssertionSchema, CkHooksConfigSchema, CkConfigSchema, DEFAULT_CK_CONFIG, CK_HOOK_NAMES;
|
|
38995
39061
|
var init_ck_config = __esm(() => {
|
|
38996
39062
|
init_zod();
|
|
38997
39063
|
PlanValidationModeSchema = exports_external.enum(["prompt", "auto", "strict", "none"]);
|
|
@@ -39084,6 +39150,16 @@ var init_ck_config = __esm(() => {
|
|
|
39084
39150
|
useGemini: exports_external.boolean().optional()
|
|
39085
39151
|
}).passthrough().optional()
|
|
39086
39152
|
}).passthrough();
|
|
39153
|
+
ResolvedModelConfigSchema = exports_external.object({
|
|
39154
|
+
model: exports_external.string(),
|
|
39155
|
+
effort: exports_external.string().optional()
|
|
39156
|
+
});
|
|
39157
|
+
ModelTierMapSchema = exports_external.object({
|
|
39158
|
+
heavy: ResolvedModelConfigSchema.optional(),
|
|
39159
|
+
balanced: ResolvedModelConfigSchema.optional(),
|
|
39160
|
+
light: ResolvedModelConfigSchema.optional()
|
|
39161
|
+
});
|
|
39162
|
+
CkModelTaxonomySchema = exports_external.record(exports_external.string(), ModelTierMapSchema);
|
|
39087
39163
|
CkAssertionSchema = exports_external.object({
|
|
39088
39164
|
pattern: exports_external.string().optional(),
|
|
39089
39165
|
rule: exports_external.string().optional(),
|
|
@@ -39115,7 +39191,8 @@ var init_ck_config = __esm(() => {
|
|
|
39115
39191
|
gemini: CkGeminiConfigSchema.optional(),
|
|
39116
39192
|
skills: CkSkillsConfigSchema.optional(),
|
|
39117
39193
|
assertions: exports_external.array(CkAssertionSchema).optional(),
|
|
39118
|
-
hooks: CkHooksConfigSchema.optional()
|
|
39194
|
+
hooks: CkHooksConfigSchema.optional(),
|
|
39195
|
+
modelTaxonomy: CkModelTaxonomySchema.optional()
|
|
39119
39196
|
}).passthrough();
|
|
39120
39197
|
DEFAULT_CK_CONFIG = {
|
|
39121
39198
|
codingLevel: -1,
|
|
@@ -39447,6 +39524,10 @@ var init_config_manager = __esm(() => {
|
|
|
39447
39524
|
});
|
|
39448
39525
|
|
|
39449
39526
|
// src/domains/config/ck-config-manager.ts
|
|
39527
|
+
var exports_ck_config_manager = {};
|
|
39528
|
+
__export(exports_ck_config_manager, {
|
|
39529
|
+
CkConfigManager: () => CkConfigManager
|
|
39530
|
+
});
|
|
39450
39531
|
import { existsSync as existsSync11 } from "node:fs";
|
|
39451
39532
|
import { mkdir as mkdir5, readFile as readFile8, writeFile as writeFile6 } from "node:fs/promises";
|
|
39452
39533
|
import { homedir as homedir9 } from "node:os";
|
|
@@ -48138,6 +48219,48 @@ var init_ck_config_schema = __esm(() => {
|
|
|
48138
48219
|
}
|
|
48139
48220
|
},
|
|
48140
48221
|
additionalProperties: false
|
|
48222
|
+
},
|
|
48223
|
+
modelTaxonomy: {
|
|
48224
|
+
type: "object",
|
|
48225
|
+
description: "Custom model mappings for portable migration. Keys are provider names (e.g., 'codex', 'gemini-cli'), values map tiers to model config.",
|
|
48226
|
+
additionalProperties: {
|
|
48227
|
+
type: "object",
|
|
48228
|
+
properties: {
|
|
48229
|
+
heavy: {
|
|
48230
|
+
type: "object",
|
|
48231
|
+
properties: {
|
|
48232
|
+
model: { type: "string", description: "Target model name" },
|
|
48233
|
+
effort: {
|
|
48234
|
+
type: "string",
|
|
48235
|
+
description: "Effort/reasoning level (provider-specific)"
|
|
48236
|
+
}
|
|
48237
|
+
},
|
|
48238
|
+
required: ["model"]
|
|
48239
|
+
},
|
|
48240
|
+
balanced: {
|
|
48241
|
+
type: "object",
|
|
48242
|
+
properties: {
|
|
48243
|
+
model: { type: "string", description: "Target model name" },
|
|
48244
|
+
effort: {
|
|
48245
|
+
type: "string",
|
|
48246
|
+
description: "Effort/reasoning level (provider-specific)"
|
|
48247
|
+
}
|
|
48248
|
+
},
|
|
48249
|
+
required: ["model"]
|
|
48250
|
+
},
|
|
48251
|
+
light: {
|
|
48252
|
+
type: "object",
|
|
48253
|
+
properties: {
|
|
48254
|
+
model: { type: "string", description: "Target model name" },
|
|
48255
|
+
effort: {
|
|
48256
|
+
type: "string",
|
|
48257
|
+
description: "Effort/reasoning level (provider-specific)"
|
|
48258
|
+
}
|
|
48259
|
+
},
|
|
48260
|
+
required: ["model"]
|
|
48261
|
+
}
|
|
48262
|
+
}
|
|
48263
|
+
}
|
|
48141
48264
|
}
|
|
48142
48265
|
},
|
|
48143
48266
|
additionalProperties: true
|
|
@@ -56416,7 +56539,7 @@ var package_default;
|
|
|
56416
56539
|
var init_package = __esm(() => {
|
|
56417
56540
|
package_default = {
|
|
56418
56541
|
name: "claudekit-cli",
|
|
56419
|
-
version: "3.36.0-dev.
|
|
56542
|
+
version: "3.36.0-dev.26",
|
|
56420
56543
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
56421
56544
|
type: "module",
|
|
56422
56545
|
repository: {
|
|
@@ -92908,6 +93031,7 @@ async function resolveConflict(action, options2) {
|
|
|
92908
93031
|
// src/commands/migrate/migrate-command.ts
|
|
92909
93032
|
init_converters();
|
|
92910
93033
|
init_hooks_settings_merger();
|
|
93034
|
+
init_model_taxonomy();
|
|
92911
93035
|
|
|
92912
93036
|
// src/commands/portable/plan-display.ts
|
|
92913
93037
|
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
@@ -93404,6 +93528,9 @@ async function migrateCommand(options2) {
|
|
|
93404
93528
|
if (hookItems.length > 0 && unsupportedHooks.length > 0) {
|
|
93405
93529
|
f2.info(import_picocolors25.default.dim(` [i] Hooks skipped for: ${unsupportedHooks.map((pv) => providers[pv].displayName).join(", ")} (unsupported)`));
|
|
93406
93530
|
}
|
|
93531
|
+
const { CkConfigManager: CkConfigManager2 } = await Promise.resolve().then(() => (init_ck_config_manager(), exports_ck_config_manager));
|
|
93532
|
+
const ckConfigResult = await CkConfigManager2.loadFull(process.cwd());
|
|
93533
|
+
setTaxonomyOverrides(ckConfigResult.config.modelTaxonomy);
|
|
93407
93534
|
const reconcileSpinner = de();
|
|
93408
93535
|
reconcileSpinner.start("Computing migration plan...");
|
|
93409
93536
|
const sourceStates = await computeSourceStates({
|
|
@@ -18,7 +18,7 @@ var Tx=Object.defineProperty;var Ex=(n,e,t)=>e in n?Tx(n,e,{enumerable:!0,config
|
|
|
18
18
|
*/var cm=n=>{throw TypeError(n)},_x=(n,e,t)=>e.has(n)||cm("Cannot "+t),Za=(n,e,t)=>(_x(n,e,"read from private field"),t?t.call(n):e.get(n)),Hx=(n,e,t)=>e.has(n)?cm("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),Pd="popstate";function Wx(n={}){function e(r,i){let{pathname:s,search:o,hash:a}=r.location;return Di("",{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:on(i)}return Kx(e,t,null,n)}function he(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function Ee(n,e){if(!n){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function Ux(){return Math.random().toString(36).substring(2,10)}function Nd(n,e){return{usr:n.state,key:n.key,idx:e}}function Di(n,e,t=null,r){return{pathname:typeof n=="string"?n:n.pathname,search:"",hash:"",...typeof e=="string"?Vn(e):e,state:t,key:e&&e.key||r||Ux()}}function on({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 Vn(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 Kx(n,e,t,r={}){let{window:i=document.defaultView,v5Compat:s=!1}=r,o=i.history,a="POP",l=null,c=d();c==null&&(c=0,o.replaceState({...o.state,idx:c},""));function d(){return(o.state||{idx:null}).idx}function u(){a="POP";let x=d(),w=x==null?null:x-c;c=x,l&&l({action:a,location:b.location,delta:w})}function f(x,w){a="PUSH";let v=Di(b.location,x,w);c=d()+1;let k=Nd(v,c),j=b.createHref(v);try{o.pushState(k,"",j)}catch(S){if(S instanceof DOMException&&S.name==="DataCloneError")throw S;i.location.assign(j)}s&&l&&l({action:a,location:b.location,delta:1})}function p(x,w){a="REPLACE";let v=Di(b.location,x,w);c=d();let k=Nd(v,c),j=b.createHref(v);o.replaceState(k,"",j),s&&l&&l({action:a,location:b.location,delta:0})}function m(x){return hm(x)}let b={get action(){return a},get location(){return n(i,o)},listen(x){if(l)throw new Error("A history only accepts one active listener");return i.addEventListener(Pd,u),l=x,()=>{i.removeEventListener(Pd,u),l=null}},createHref(x){return e(i,x)},createURL:m,encodeLocation(x){let w=m(x);return{pathname:w.pathname,search:w.search,hash:w.hash}},push:f,replace:p,go(x){return o.go(x)}};return b}function hm(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:on(n);return r=r.replace(/ $/,"%20"),!e&&r.startsWith("//")&&(r=t+r),new URL(r,t)}var gi,Ad=class{constructor(n){if(Hx(this,gi,new Map),n)for(let[e,t]of n)this.set(e,t)}get(n){if(Za(this,gi).has(n))return Za(this,gi).get(n);if(n.defaultValue!==void 0)return n.defaultValue;throw new Error("No value found for context")}set(n,e){Za(this,gi).set(n,e)}};gi=new WeakMap;var Gx=new Set(["lazy","caseSensitive","path","id","index","children"]);function qx(n){return Gx.has(n)}var Yx=new Set(["lazy","caseSensitive","path","id","index","middleware","children"]);function Jx(n){return Yx.has(n)}function Qx(n){return n.index===!0}function Ti(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`),Qx(s)){let c={...s,id:l};return r[l]=Md(c,e(c)),c}else{let c={...s,id:l,children:void 0};return r[l]=Md(c,e(c)),s.children&&(c.children=Ti(s.children,e,a,r,i)),c}})}function Md(n,e){return Object.assign(n,{...e,...typeof e.lazy=="object"&&e.lazy!=null?{lazy:{...n.lazy,...e.lazy}}:{}})}function jn(n,e,t="/"){return bi(n,e,t,!1)}function bi(n,e,t,r){let i=typeof e=="string"?Vn(e):e,s=Rt(i.pathname||"/",t);if(s==null)return null;let o=dm(n);Zx(o);let a=null;for(let l=0;a==null&&l<o.length;++l){let c=hy(s);a=ly(o[l],c,r)}return a}function Xx(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 dm(n,e=[],t=[],r="",i=!1){let s=(o,a,l=i,c)=>{let d={relativePath:c===void 0?o.path||"":c,caseSensitive:o.caseSensitive===!0,childrenIndex:a,route:o};if(d.relativePath.startsWith("/")){if(!d.relativePath.startsWith(r)&&l)return;he(d.relativePath.startsWith(r),`Absolute route path "${d.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),d.relativePath=d.relativePath.slice(r.length)}let u=rn([r,d.relativePath]),f=t.concat(d);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 "${u}".`),dm(o.children,e,f,u,l)),!(o.path==null&&!o.index)&&e.push({path:u,score:oy(u,o.index),routesMeta:f})};return n.forEach((o,a)=>{if(o.path===""||!o.path?.includes("?"))s(o,a);else for(let l of um(o.path))s(o,a,!0,l)}),e}function um(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=um(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 Zx(n){n.sort((e,t)=>e.score!==t.score?t.score-e.score:ay(e.routesMeta.map(r=>r.childrenIndex),t.routesMeta.map(r=>r.childrenIndex)))}var ey=/^:[\w-]+$/,ty=3,ny=2,ry=1,iy=10,sy=-2,Dd=n=>n==="*";function oy(n,e){let t=n.split("/"),r=t.length;return t.some(Dd)&&(r+=sy),e&&(r+=ny),t.filter(i=>!Dd(i)).reduce((i,s)=>i+(ey.test(s)?ty:s===""?ry:iy),r)}function ay(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 ly(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,d=s==="/"?e:e.slice(s.length)||"/",u=Zo({path:l.relativePath,caseSensitive:l.caseSensitive,end:c},d),f=l.route;if(!u&&c&&t&&!r[r.length-1].route.index&&(u=Zo({path:l.relativePath,caseSensitive:l.caseSensitive,end:!1},d)),!u)return null;Object.assign(i,u.params),o.push({params:i,pathname:rn([s,u.pathname]),pathnameBase:fy(rn([s,u.pathnameBase])),route:f}),u.pathnameBase!=="/"&&(s=rn([s,u.pathnameBase]))}return o}function Zo(n,e){typeof n=="string"&&(n={path:n,caseSensitive:!1,end:!0});let[t,r]=cy(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:d,isOptional:u},f)=>{if(d==="*"){let m=a[f]||"";o=s.slice(0,s.length-m.length).replace(/(.)\/+$/,"$1")}const p=a[f];return u&&!p?c[d]=void 0:c[d]=(p||"").replace(/%2F/g,"/"),c},{}),pathname:s,pathnameBase:o,pattern:n}}function cy(n,e=!1,t=!0){Ee(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 hy(n){try{return n.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return Ee(!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 Rt(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 dy({basename:n,pathname:e}){return e==="/"?n:rn([n,e])}var fm=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Na=n=>fm.test(n);function uy(n,e="/"){let{pathname:t,search:r="",hash:i=""}=typeof n=="string"?Vn(n):n,s;if(t)if(Na(t))s=t;else{if(t.includes("//")){let o=t;t=t.replace(/\/\/+/g,"/"),Ee(!1,`Pathnames cannot have embedded double slashes - normalizing ${o} -> ${t}`)}t.startsWith("/")?s=Td(t.substring(1),"/"):s=Td(t,e)}else s=e;return{pathname:s,search:py(r),hash:my(i)}}function Td(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 el(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 pm(n){return n.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function Aa(n){let e=pm(n);return e.map((t,r)=>r===e.length-1?t.pathname:t.pathnameBase)}function Ma(n,e,t,r=!1){let i;typeof n=="string"?i=Vn(n):(i={...n},he(!i.pathname||!i.pathname.includes("?"),el("?","pathname","search",i)),he(!i.pathname||!i.pathname.includes("#"),el("#","pathname","hash",i)),he(!i.search||!i.search.includes("#"),el("#","search","hash",i)));let s=n===""||i.pathname==="",o=s?"/":i.pathname,a;if(o==null)a=t;else{let u=e.length-1;if(!r&&o.startsWith("..")){let f=o.split("/");for(;f[0]==="..";)f.shift(),u-=1;i.pathname=f.join("/")}a=u>=0?e[u]:"/"}let l=uy(i,a),c=o&&o!=="/"&&o.endsWith("/"),d=(s||o===".")&&t.endsWith("/");return!l.pathname.endsWith("/")&&(c||d)&&(l.pathname+="/"),l}var rn=n=>n.join("/").replace(/\/\/+/g,"/"),fy=n=>n.replace(/\/+$/,"").replace(/^\/*/,"/"),py=n=>!n||n==="?"?"":n.startsWith("?")?n:"?"+n,my=n=>!n||n==="#"?"":n.startsWith("#")?n:"#"+n,Is=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 Ei(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.internal=="boolean"&&"data"in n}function $s(n){return n.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var mm=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function gm(n,e){let t=n;if(typeof t!="string"||!fm.test(t))return{absoluteURL:void 0,isExternal:!1,to:t};let r=t,i=!1;if(mm)try{let s=new URL(window.location.href),o=t.startsWith("//")?new URL(s.protocol+t):new URL(t),a=Rt(o.pathname,e);o.origin===s.origin&&a!=null?t=a+o.search+o.hash:i=!0}catch{Ee(!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 An=Symbol("Uninstrumented");function gy(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=wr(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=wr(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[An]??s,a=wr(t[i],o,(...l)=>Ed(l[0]));a&&(a[An]=o,r[i]=a)}}),e.middleware&&e.middleware.length>0&&t.middleware.length>0&&(r.middleware=e.middleware.map(i=>{let s=i[An]??i,o=wr(t.middleware,s,(...a)=>Ed(a[0]));return o?(o[An]=s,o):i})),r}function by(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[An]??n.navigate,i=wr(t.navigate,r,(...s)=>{let[o,a]=s;return{to:typeof o=="number"||typeof o=="string"?o:o?on(o):".",...Rd(n,a??{})}});i&&(i[An]=r,n.navigate=i)}if(t.fetch.length>0){let r=n.fetch[An]??n.fetch,i=wr(t.fetch,r,(...s)=>{let[o,,a,l]=s;return{href:a??".",fetcherKey:o,...Rd(n,l??{})}});i&&(i[An]=r,n.fetch=i)}return n}function wr(n,e,t){return n.length===0?null:async(...r)=>{let i=await bm(n,t(...r),()=>e(...r),n.length-1);if(i.type==="error")throw i.value;return i.value}}async function bm(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=bm(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 Ed(n){let{request:e,context:t,params:r,unstable_pattern:i}=n;return{request:xy(e),params:{...r},unstable_pattern:i,context:yy(t)}}function Rd(n,e){return{currentUrl:on(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 xy(n){return{method:n.method,url:n.url,headers:{get:(...e)=>n.headers.get(...e)}}}function yy(n){if(wy(n)){let e={...n};return Object.freeze(e),e}else return{get:e=>n.get(e)}}var vy=Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function wy(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")===vy}var xm=["POST","PUT","PATCH","DELETE"],ky=new Set(xm),Sy=["GET",...xm],Cy=new Set(Sy),ym=new Set([301,302,303,307,308]),jy=new Set([307,308]),tl={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},Oy={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},si={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},Py=n=>({hasErrorBoundary:!!n.hasErrorBoundary}),vm="remix-router-transitions",wm=Symbol("ResetLoaderData");function Ny(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||Py,s=i;if(n.unstable_instrumentations){let C=n.unstable_instrumentations;s=P=>({...i(P),...gy(C.map(M=>M.route).filter(Boolean),P)})}let o={},a=Ti(n.routes,s,void 0,o),l,c=n.basename||"/";c.startsWith("/")||(c=`/${c}`);let d=n.dataStrategy||Ey,u={...n.future},f=null,p=new Set,m=null,b=null,x=null,w=n.hydrationData!=null,v=jn(a,n.history.location,c),k=!1,j=null,S;if(v==null&&!n.patchRoutesOnNavigation){let C=Pt(404,{pathname:n.history.location.pathname}),{matches:P,route:M}=oo(a);S=!0,v=P,j={[M.id]:C}}else if(v&&!n.hydrationData&&to(v,a,n.history.location.pathname).active&&(v=null),v)if(v.some(C=>C.route.lazy))S=!1;else if(!v.some(C=>hh(C.route)))S=!0;else{let C=n.hydrationData?n.hydrationData.loaderData:null,P=n.hydrationData?n.hydrationData.errors:null;if(P){let M=v.findIndex($=>P[$.route.id]!==void 0);S=v.slice(0,M+1).every($=>!cc($.route,C,P))}else S=v.every(M=>!cc(M.route,C,P))}else{S=!1,v=[];let C=to(null,a,n.history.location.pathname);C.active&&C.matches&&(k=!0,v=C.matches)}let O,y={historyAction:n.history.action,location:n.history.location,matches:v,initialized:S,navigation:tl,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||j,fetchers:new Map,blockers:new Map},D="POP",A=null,R=!1,N,L=!1,W=new Map,F=null,B=!1,q=!1,de=new Set,z=new Map,Y=0,ie=-1,le=new Map,fe=new Set,we=new Map,ke=new Map,Ae=new Set,Qe=new Map,mt,J=null;function Me(){if(f=n.history.listen(({action:C,location:P,delta:M})=>{if(mt){mt(),mt=void 0;return}Ee(Qe.size===0||M!=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 $=vd({currentLocation:y.location,nextLocation:P,historyAction:C});if($&&M!=null){let V=new Promise(Z=>{mt=Z});n.history.go(M*-1),eo($,{state:"blocked",location:P,proceed(){eo($,{state:"proceeding",proceed:void 0,reset:void 0,location:P}),V.then(()=>n.history.go(M))},reset(){let Z=new Map(y.blockers);Z.set($,si),ve({blockers:Z})}}),A?.resolve(),A=null;return}return oe(C,P)}),t){Qy(e,W);let C=()=>Xy(e,W);e.addEventListener("pagehide",C),F=()=>e.removeEventListener("pagehide",C)}return y.initialized||oe("POP",y.location,{initialHydration:!0}),O}function Se(){f&&f(),F&&F(),p.clear(),N&&N.abort(),y.fetchers.forEach((C,P)=>Ja(P)),y.blockers.forEach((C,P)=>yd(P))}function Ie(C){return p.add(C),()=>p.delete(C)}function ve(C,P={}){C.matches&&(C.matches=C.matches.map(V=>{let Z=o[V.route.id],Q=V.route;return Q.element!==Z.element||Q.errorElement!==Z.errorElement||Q.hydrateFallbackElement!==Z.hydrateFallbackElement?{...V,route:Z}:V})),y={...y,...C};let M=[],$=[];y.fetchers.forEach((V,Z)=>{V.state==="idle"&&(Ae.has(Z)?M.push(Z):$.push(Z))}),Ae.forEach(V=>{!y.fetchers.has(V)&&!z.has(V)&&M.push(V)}),[...p].forEach(V=>V(y,{deletedFetchers:M,newErrors:C.errors??null,viewTransitionOpts:P.viewTransitionOpts,flushSync:P.flushSync===!0})),M.forEach(V=>Ja(V)),$.forEach(V=>y.fetchers.delete(V))}function gt(C,P,{flushSync:M}={}){let $=y.actionData!=null&&y.navigation.formMethod!=null&&Ze(y.navigation.formMethod)&&y.navigation.state==="loading"&&C.state?._isRedirect!==!0,V;P.actionData?Object.keys(P.actionData).length>0?V=P.actionData:V=null:$?V=y.actionData:V=null;let Z=P.loaderData?Wd(y.loaderData,P.loaderData,P.matches||[],P.errors):y.loaderData,Q=y.blockers;Q.size>0&&(Q=new Map(Q),Q.forEach((se,te)=>Q.set(te,si)));let X=B?!1:kd(C,P.matches||y.matches),ee=R===!0||y.navigation.formMethod!=null&&Ze(y.navigation.formMethod)&&C.state?._isRedirect!==!0;l&&(a=l,l=void 0),B||D==="POP"||(D==="PUSH"?n.history.push(C,C.state):D==="REPLACE"&&n.history.replace(C,C.state));let re;if(D==="POP"){let se=W.get(y.location.pathname);se&&se.has(C.pathname)?re={currentLocation:y.location,nextLocation:C}:W.has(C.pathname)&&(re={currentLocation:C,nextLocation:y.location})}else if(L){let se=W.get(y.location.pathname);se?se.add(C.pathname):(se=new Set([C.pathname]),W.set(y.location.pathname,se)),re={currentLocation:y.location,nextLocation:C}}ve({...P,actionData:V,loaderData:Z,historyAction:D,location:C,initialized:!0,navigation:tl,revalidation:"idle",restoreScrollPosition:X,preventScrollReset:ee,blockers:Q},{viewTransitionOpts:re,flushSync:M===!0}),D="POP",R=!1,L=!1,B=!1,q=!1,A?.resolve(),A=null,J?.resolve(),J=null}async function I(C,P){if(A?.resolve(),A=null,typeof C=="number"){A||(A=qd());let xe=A.promise;return n.history.go(C),xe}let M=lc(y.location,y.matches,c,C,P?.fromRouteId,P?.relative),{path:$,submission:V,error:Z}=Ld(!1,M,P),Q=y.location,X=Di(y.location,$,P&&P.state);X={...X,...n.history.encodeLocation(X)};let ee=P&&P.replace!=null?P.replace:void 0,re="PUSH";ee===!0?re="REPLACE":ee===!1||V!=null&&Ze(V.formMethod)&&V.formAction===y.location.pathname+y.location.search&&(re="REPLACE");let se=P&&"preventScrollReset"in P?P.preventScrollReset===!0:void 0,te=(P&&P.flushSync)===!0,be=vd({currentLocation:Q,nextLocation:X,historyAction:re});if(be){eo(be,{state:"blocked",location:X,proceed(){eo(be,{state:"proceeding",proceed:void 0,reset:void 0,location:X}),I(C,P)},reset(){let xe=new Map(y.blockers);xe.set(be,si),ve({blockers:xe})}});return}await oe(re,X,{submission:V,pendingError:Z,preventScrollReset:se,replace:P&&P.replace,enableViewTransition:P&&P.viewTransition,flushSync:te,callSiteDefaultShouldRevalidate:P&&P.unstable_defaultShouldRevalidate})}function G(){J||(J=qd()),Ya(),ve({revalidation:"loading"});let C=J.promise;return y.navigation.state==="submitting"?C:y.navigation.state==="idle"?(oe(y.historyAction,y.location,{startUninterruptedRevalidation:!0}),C):(oe(D||y.historyAction,y.navigation.location,{overrideNavigation:y.navigation,enableViewTransition:L===!0}),C)}async function oe(C,P,M){N&&N.abort(),N=null,D=C,B=(M&&M.startUninterruptedRevalidation)===!0,Nx(y.location,y.matches),R=(M&&M.preventScrollReset)===!0,L=(M&&M.enableViewTransition)===!0;let $=l||a,V=M&&M.overrideNavigation,Z=M?.initialHydration&&y.matches&&y.matches.length>0&&!k?y.matches:jn($,P,c),Q=(M&&M.flushSync)===!0;if(Z&&y.initialized&&!q&&zy(y.location,P)&&!(M&&M.submission&&Ze(M.submission.formMethod))){gt(P,{matches:Z},{flushSync:Q});return}let X=to(Z,$,P.pathname);if(X.active&&X.matches&&(Z=X.matches),!Z){let{error:We,notFoundMatches:it,route:Ce}=Qa(P.pathname);gt(P,{matches:it,loaderData:{},errors:{[Ce.id]:We}},{flushSync:Q});return}N=new AbortController;let ee=xr(n.history,P,N.signal,M&&M.submission),re=n.getContext?await n.getContext():new Ad,se;if(M&&M.pendingError)se=[On(Z).route.id,{type:"error",error:M.pendingError}];else if(M&&M.submission&&Ze(M.submission.formMethod)){let We=await De(ee,P,M.submission,Z,re,X.active,M&&M.initialHydration===!0,{replace:M.replace,flushSync:Q});if(We.shortCircuited)return;if(We.pendingActionResult){let[it,Ce]=We.pendingActionResult;if(vt(Ce)&&Ei(Ce.error)&&Ce.error.status===404){N=null,gt(P,{matches:We.matches,loaderData:{},errors:{[it]:Ce.error}});return}}Z=We.matches||Z,se=We.pendingActionResult,V=nl(P,M.submission),Q=!1,X.active=!1,ee=xr(n.history,ee.url,ee.signal)}let{shortCircuited:te,matches:be,loaderData:xe,errors:Ke}=await Ut(ee,P,Z,re,X.active,V,M&&M.submission,M&&M.fetcherSubmission,M&&M.replace,M&&M.initialHydration===!0,Q,se,M&&M.callSiteDefaultShouldRevalidate);te||(N=null,gt(P,{matches:be||Z,...Ud(se),loaderData:xe,errors:Ke}))}async function De(C,P,M,$,V,Z,Q,X={}){Ya();let ee=Yy(P,M);if(ve({navigation:ee},{flushSync:X.flushSync===!0}),Z){let te=await no($,P.pathname,C.signal);if(te.type==="aborted")return{shortCircuited:!0};if(te.type==="error"){if(te.partialMatches.length===0){let{matches:xe,route:Ke}=oo(a);return{matches:xe,pendingActionResult:[Ke.id,{type:"error",error:te.error}]}}let be=On(te.partialMatches).route.id;return{matches:te.partialMatches,pendingActionResult:[be,{type:"error",error:te.error}]}}else if(te.matches)$=te.matches;else{let{notFoundMatches:be,error:xe,route:Ke}=Qa(P.pathname);return{matches:be,pendingActionResult:[Ke.id,{type:"error",error:xe}]}}}let re,se=Vo($,P);if(!se.route.action&&!se.route.lazy)re={type:"error",error:Pt(405,{method:C.method,pathname:P.pathname,routeId:se.route.id})};else{let te=Pr(s,o,C,$,se,Q?[]:r,V),be=await ni(C,te,V,null);if(re=be[se.route.id],!re){for(let xe of $)if(be[xe.route.id]){re=be[xe.route.id];break}}if(C.signal.aborted)return{shortCircuited:!0}}if(er(re)){let te;return X&&X.replace!=null?te=X.replace:te=zd(re.response.headers.get("Location"),new URL(C.url),c)===y.location.pathname+y.location.search,await Wn(C,re,!0,{submission:M,replace:te}),{shortCircuited:!0}}if(vt(re)){let te=On($,se.route.id);return(X&&X.replace)!==!0&&(D="PUSH"),{matches:$,pendingActionResult:[te.route.id,re,se.route.id]}}return{matches:$,pendingActionResult:[se.route.id,re]}}async function Ut(C,P,M,$,V,Z,Q,X,ee,re,se,te,be){let xe=Z||nl(P,Q),Ke=Q||X||Gd(xe),We=!B&&!re;if(V){if(We){let Xe=Zs(te);ve({navigation:xe,...Xe!==void 0?{actionData:Xe}:{}},{flushSync:se})}let ge=await no(M,P.pathname,C.signal);if(ge.type==="aborted")return{shortCircuited:!0};if(ge.type==="error"){if(ge.partialMatches.length===0){let{matches:mr,route:Gn}=oo(a);return{matches:mr,loaderData:{},errors:{[Gn.id]:ge.error}}}let Xe=On(ge.partialMatches).route.id;return{matches:ge.partialMatches,loaderData:{},errors:{[Xe]:ge.error}}}else if(ge.matches)M=ge.matches;else{let{error:Xe,notFoundMatches:mr,route:Gn}=Qa(P.pathname);return{matches:mr,loaderData:{},errors:{[Gn.id]:Xe}}}}let it=l||a,{dsMatches:Ce,revalidatingFetchers:jt}=Id(C,$,s,o,n.history,y,M,Ke,P,re?[]:r,re===!0,q,de,Ae,we,fe,it,c,n.patchRoutesOnNavigation!=null,te,be);if(ie=++Y,!n.dataStrategy&&!Ce.some(ge=>ge.shouldLoad)&&!Ce.some(ge=>ge.route.middleware&&ge.route.middleware.length>0)&&jt.length===0){let ge=bd();return gt(P,{matches:M,loaderData:{},errors:te&&vt(te[1])?{[te[0]]:te[1].error}:null,...Ud(te),...ge?{fetchers:new Map(y.fetchers)}:{}},{flushSync:se}),{shortCircuited:!0}}if(We){let ge={};if(!V){ge.navigation=xe;let Xe=Zs(te);Xe!==void 0&&(ge.actionData=Xe)}jt.length>0&&(ge.fetchers=ti(jt)),ve(ge,{flushSync:se})}jt.forEach(ge=>{fn(ge.key),ge.controller&&z.set(ge.key,ge.controller)});let Un=()=>jt.forEach(ge=>fn(ge.key));N&&N.signal.addEventListener("abort",Un);let{loaderResults:ri,fetcherResults:wn}=await pd(Ce,jt,C,$);if(C.signal.aborted)return{shortCircuited:!0};N&&N.signal.removeEventListener("abort",Un),jt.forEach(ge=>z.delete(ge.key));let Kt=ao(ri);if(Kt)return await Wn(C,Kt.result,!0,{replace:ee}),{shortCircuited:!0};if(Kt=ao(wn),Kt)return fe.add(Kt.key),await Wn(C,Kt.result,!0,{replace:ee}),{shortCircuited:!0};let{loaderData:Xa,errors:ii}=Hd(y,M,ri,te,jt,wn);re&&y.errors&&(ii={...y.errors,...ii});let Kn=bd(),ro=xd(ie),io=Kn||ro||jt.length>0;return{matches:M,loaderData:Xa,errors:ii,...io?{fetchers:new Map(y.fetchers)}:{}}}function Zs(C){if(C&&!vt(C[1]))return{[C[0]]:C[1].data};if(y.actionData)return Object.keys(y.actionData).length===0?null:y.actionData}function ti(C){return C.forEach(P=>{let M=y.fetchers.get(P.key),$=oi(void 0,M?M.data:void 0);y.fetchers.set(P.key,$)}),new Map(y.fetchers)}async function wx(C,P,M,$){fn(C);let V=($&&$.flushSync)===!0,Z=l||a,Q=lc(y.location,y.matches,c,M,P,$?.relative),X=jn(Z,Q,c),ee=to(X,Z,Q);if(ee.active&&ee.matches&&(X=ee.matches),!X){un(C,P,Pt(404,{pathname:Q}),{flushSync:V});return}let{path:re,submission:se,error:te}=Ld(!0,Q,$);if(te){un(C,P,te,{flushSync:V});return}let be=n.getContext?await n.getContext():new Ad,xe=($&&$.preventScrollReset)===!0;if(se&&Ze(se.formMethod)){await kx(C,P,re,X,be,ee.active,V,xe,se,$&&$.unstable_defaultShouldRevalidate);return}we.set(C,{routeId:P,path:re}),await Sx(C,P,re,X,be,ee.active,V,xe,se)}async function kx(C,P,M,$,V,Z,Q,X,ee,re){Ya(),we.delete(C);let se=y.fetchers.get(C);dn(C,Jy(ee,se),{flushSync:Q});let te=new AbortController,be=xr(n.history,M,te.signal,ee);if(Z){let Re=await no($,new URL(be.url).pathname,be.signal,C);if(Re.type==="aborted")return;if(Re.type==="error"){un(C,P,Re.error,{flushSync:Q});return}else if(Re.matches)$=Re.matches;else{un(C,P,Pt(404,{pathname:M}),{flushSync:Q});return}}let xe=Vo($,M);if(!xe.route.action&&!xe.route.lazy){let Re=Pt(405,{method:ee.formMethod,pathname:M,routeId:P});un(C,P,Re,{flushSync:Q});return}z.set(C,te);let Ke=Y,We=Pr(s,o,be,$,xe,r,V),it=await ni(be,We,V,C),Ce=it[xe.route.id];if(!Ce){for(let Re of We)if(it[Re.route.id]){Ce=it[Re.route.id];break}}if(be.signal.aborted){z.get(C)===te&&z.delete(C);return}if(Ae.has(C)){if(er(Ce)||vt(Ce)){dn(C,pn(void 0));return}}else{if(er(Ce))if(z.delete(C),ie>Ke){dn(C,pn(void 0));return}else return fe.add(C),dn(C,oi(ee)),Wn(be,Ce,!1,{fetcherSubmission:ee,preventScrollReset:X});if(vt(Ce)){un(C,P,Ce.error);return}}let jt=y.navigation.location||y.location,Un=xr(n.history,jt,te.signal),ri=l||a,wn=y.navigation.state!=="idle"?jn(ri,y.navigation.location,c):y.matches;he(wn,"Didn't find any matches after fetcher action");let Kt=++Y;le.set(C,Kt);let Xa=oi(ee,Ce.data);y.fetchers.set(C,Xa);let{dsMatches:ii,revalidatingFetchers:Kn}=Id(Un,V,s,o,n.history,y,wn,ee,jt,r,!1,q,de,Ae,we,fe,ri,c,n.patchRoutesOnNavigation!=null,[xe.route.id,Ce],re);Kn.filter(Re=>Re.key!==C).forEach(Re=>{let so=Re.key,Cd=y.fetchers.get(so),Dx=oi(void 0,Cd?Cd.data:void 0);y.fetchers.set(so,Dx),fn(so),Re.controller&&z.set(so,Re.controller)}),ve({fetchers:new Map(y.fetchers)});let ro=()=>Kn.forEach(Re=>fn(Re.key));te.signal.addEventListener("abort",ro);let{loaderResults:io,fetcherResults:ge}=await pd(ii,Kn,Un,V);if(te.signal.aborted)return;if(te.signal.removeEventListener("abort",ro),le.delete(C),z.delete(C),Kn.forEach(Re=>z.delete(Re.key)),y.fetchers.has(C)){let Re=pn(Ce.data);y.fetchers.set(C,Re)}let Xe=ao(io);if(Xe)return Wn(Un,Xe.result,!1,{preventScrollReset:X});if(Xe=ao(ge),Xe)return fe.add(Xe.key),Wn(Un,Xe.result,!1,{preventScrollReset:X});let{loaderData:mr,errors:Gn}=Hd(y,wn,io,void 0,Kn,ge);xd(Kt),y.navigation.state==="loading"&&Kt>ie?(he(D,"Expected pending action"),N&&N.abort(),gt(y.navigation.location,{matches:wn,loaderData:mr,errors:Gn,fetchers:new Map(y.fetchers)})):(ve({errors:Gn,loaderData:Wd(y.loaderData,mr,wn,Gn),fetchers:new Map(y.fetchers)}),q=!1)}async function Sx(C,P,M,$,V,Z,Q,X,ee){let re=y.fetchers.get(C);dn(C,oi(ee,re?re.data:void 0),{flushSync:Q});let se=new AbortController,te=xr(n.history,M,se.signal);if(Z){let Ce=await no($,new URL(te.url).pathname,te.signal,C);if(Ce.type==="aborted")return;if(Ce.type==="error"){un(C,P,Ce.error,{flushSync:Q});return}else if(Ce.matches)$=Ce.matches;else{un(C,P,Pt(404,{pathname:M}),{flushSync:Q});return}}let be=Vo($,M);z.set(C,se);let xe=Y,Ke=Pr(s,o,te,$,be,r,V),it=(await ni(te,Ke,V,C))[be.route.id];if(z.get(C)===se&&z.delete(C),!te.signal.aborted){if(Ae.has(C)){dn(C,pn(void 0));return}if(er(it))if(ie>xe){dn(C,pn(void 0));return}else{fe.add(C),await Wn(te,it,!1,{preventScrollReset:X});return}if(vt(it)){un(C,P,it.error);return}dn(C,pn(it.data))}}async function Wn(C,P,M,{submission:$,fetcherSubmission:V,preventScrollReset:Z,replace:Q}={}){M||(A?.resolve(),A=null),P.response.headers.has("X-Remix-Revalidate")&&(q=!0);let X=P.response.headers.get("Location");he(X,"Expected a Location header on the redirect Response"),X=zd(X,new URL(C.url),c);let ee=Di(y.location,X,{_isRedirect:!0});if(t){let Ke=!1;if(P.response.headers.has("X-Remix-Reload-Document"))Ke=!0;else if(Na(X)){const We=hm(X,!0);Ke=We.origin!==e.location.origin||Rt(We.pathname,c)==null}if(Ke){Q?e.location.replace(X):e.location.assign(X);return}}N=null;let re=Q===!0||P.response.headers.has("X-Remix-Replace")?"REPLACE":"PUSH",{formMethod:se,formAction:te,formEncType:be}=y.navigation;!$&&!V&&se&&te&&be&&($=Gd(y.navigation));let xe=$||V;if(jy.has(P.response.status)&&xe&&Ze(xe.formMethod))await oe(re,ee,{submission:{...xe,formAction:X},preventScrollReset:Z||R,enableViewTransition:M?L:void 0});else{let Ke=nl(ee,$);await oe(re,ee,{overrideNavigation:Ke,fetcherSubmission:V,preventScrollReset:Z||R,enableViewTransition:M?L:void 0})}}async function ni(C,P,M,$){let V,Z={};try{V=await Ly(d,C,P,$,M,!1)}catch(Q){return P.filter(X=>X.shouldLoad).forEach(X=>{Z[X.route.id]={type:"error",error:Q}}),Z}if(C.signal.aborted)return Z;if(!Ze(C.method))for(let Q of P){if(V[Q.route.id]?.type==="error")break;!V.hasOwnProperty(Q.route.id)&&!y.loaderData.hasOwnProperty(Q.route.id)&&(!y.errors||!y.errors.hasOwnProperty(Q.route.id))&&Q.shouldCallHandler()&&(V[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(V))if(Uy(X)){let ee=X.result;Z[Q]={type:"redirect",response:Fy(ee,C,Q,P,c)}}else Z[Q]=await By(X);return Z}async function pd(C,P,M,$){let V=ni(M,C,$,null),Z=Promise.all(P.map(async ee=>{if(ee.matches&&ee.match&&ee.request&&ee.controller){let se=(await ni(ee.request,ee.matches,$,ee.key))[ee.match.route.id];return{[ee.key]:se}}else return Promise.resolve({[ee.key]:{type:"error",error:Pt(404,{pathname:ee.path})}})})),Q=await V,X=(await Z).reduce((ee,re)=>Object.assign(ee,re),{});return{loaderResults:Q,fetcherResults:X}}function Ya(){q=!0,we.forEach((C,P)=>{z.has(P)&&de.add(P),fn(P)})}function dn(C,P,M={}){y.fetchers.set(C,P),ve({fetchers:new Map(y.fetchers)},{flushSync:(M&&M.flushSync)===!0})}function un(C,P,M,$={}){let V=On(y.matches,P);Ja(C),ve({errors:{[V.route.id]:M},fetchers:new Map(y.fetchers)},{flushSync:($&&$.flushSync)===!0})}function md(C){return ke.set(C,(ke.get(C)||0)+1),Ae.has(C)&&Ae.delete(C),y.fetchers.get(C)||Oy}function Cx(C,P){fn(C,P?.reason),dn(C,pn(null))}function Ja(C){let P=y.fetchers.get(C);z.has(C)&&!(P&&P.state==="loading"&&le.has(C))&&fn(C),we.delete(C),le.delete(C),fe.delete(C),Ae.delete(C),de.delete(C),y.fetchers.delete(C)}function jx(C){let P=(ke.get(C)||0)-1;P<=0?(ke.delete(C),Ae.add(C)):ke.set(C,P),ve({fetchers:new Map(y.fetchers)})}function fn(C,P){let M=z.get(C);M&&(M.abort(P),z.delete(C))}function gd(C){for(let P of C){let M=md(P),$=pn(M.data);y.fetchers.set(P,$)}}function bd(){let C=[],P=!1;for(let M of fe){let $=y.fetchers.get(M);he($,`Expected fetcher: ${M}`),$.state==="loading"&&(fe.delete(M),C.push(M),P=!0)}return gd(C),P}function xd(C){let P=[];for(let[M,$]of le)if($<C){let V=y.fetchers.get(M);he(V,`Expected fetcher: ${M}`),V.state==="loading"&&(fn(M),le.delete(M),P.push(M))}return gd(P),P.length>0}function Ox(C,P){let M=y.blockers.get(C)||si;return Qe.get(C)!==P&&Qe.set(C,P),M}function yd(C){y.blockers.delete(C),Qe.delete(C)}function eo(C,P){let M=y.blockers.get(C)||si;he(M.state==="unblocked"&&P.state==="blocked"||M.state==="blocked"&&P.state==="blocked"||M.state==="blocked"&&P.state==="proceeding"||M.state==="blocked"&&P.state==="unblocked"||M.state==="proceeding"&&P.state==="unblocked",`Invalid blocker state transition: ${M.state} -> ${P.state}`);let $=new Map(y.blockers);$.set(C,P),ve({blockers:$})}function vd({currentLocation:C,nextLocation:P,historyAction:M}){if(Qe.size===0)return;Qe.size>1&&Ee(!1,"A router only supports one blocker at a time");let $=Array.from(Qe.entries()),[V,Z]=$[$.length-1],Q=y.blockers.get(V);if(!(Q&&Q.state==="proceeding")&&Z({currentLocation:C,nextLocation:P,historyAction:M}))return V}function Qa(C){let P=Pt(404,{pathname:C}),M=l||a,{matches:$,route:V}=oo(M);return{notFoundMatches:$,route:V,error:P}}function Px(C,P,M){if(m=C,x=P,b=M||null,!w&&y.navigation===tl){w=!0;let $=kd(y.location,y.matches);$!=null&&ve({restoreScrollPosition:$})}return()=>{m=null,x=null,b=null}}function wd(C,P){return b&&b(C,P.map($=>Xx($,y.loaderData)))||C.key}function Nx(C,P){if(m&&x){let M=wd(C,P);m[M]=x()}}function kd(C,P){if(m){let M=wd(C,P),$=m[M];if(typeof $=="number")return $}return null}function to(C,P,M){if(n.patchRoutesOnNavigation)if(C){if(Object.keys(C[0].params).length>0)return{active:!0,matches:bi(P,M,c,!0)}}else return{active:!0,matches:bi(P,M,c,!0)||[]};return{active:!1,matches:null}}async function no(C,P,M,$){if(!n.patchRoutesOnNavigation)return{type:"success",matches:C};let V=C;for(;;){let Z=l==null,Q=l||a,X=o;try{await n.patchRoutesOnNavigation({signal:M,path:P,matches:V,fetcherKey:$,patch:(se,te)=>{M.aborted||$d(se,te,Q,X,s,!1)}})}catch(se){return{type:"error",error:se,partialMatches:V}}finally{Z&&!M.aborted&&(a=[...a])}if(M.aborted)return{type:"aborted"};let ee=jn(Q,P,c),re=null;if(ee){if(Object.keys(ee[0].params).length===0)return{type:"success",matches:ee};if(re=bi(Q,P,c,!0),!(re&&V.length<re.length&&Sd(V,re.slice(0,V.length))))return{type:"success",matches:ee}}if(re||(re=bi(Q,P,c,!0)),!re||Sd(V,re))return{type:"success",matches:null};V=re}}function Sd(C,P){return C.length===P.length&&C.every((M,$)=>M.route.id===P[$].route.id)}function Ax(C){o={},l=Ti(C,s,void 0,o)}function Mx(C,P,M=!1){let $=l==null;$d(C,P,l||a,o,s,M),$&&(a=[...a],ve({}))}return O={get basename(){return c},get future(){return u},get state(){return y},get routes(){return a},get window(){return e},initialize:Me,subscribe:Ie,enableScrollRestoration:Px,navigate:I,fetch:wx,revalidate:G,createHref:C=>n.history.createHref(C),encodeLocation:C=>n.history.encodeLocation(C),getFetcher:md,resetFetcher:Cx,deleteFetcher:jx,dispose:Se,getBlocker:Ox,deleteBlocker:yd,patchRoutes:Mx,_internalFetchControllers:z,_internalSetRoutes:Ax,_internalSetStateDoNotUseOrYouWillBreakYourApp(C){ve(C)}},n.unstable_instrumentations&&(O=by(O,n.unstable_instrumentations.map(C=>C.router).filter(Boolean))),O}function Ay(n){return n!=null&&("formData"in n&&n.formData!=null||"body"in n&&n.body!==void 0)}function lc(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=Ma(r||".",Aa(o),Rt(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=uh(l.search);if(a.route.index&&!c)l.search=l.search?l.search.replace(/^\?/,"?index&"):"?index";else if(!a.route.index&&c){let d=new URLSearchParams(l.search),u=d.getAll("index");d.delete("index"),u.filter(p=>p).forEach(p=>d.append("index",p));let f=d.toString();l.search=f?`?${f}`:""}}return t!=="/"&&(l.pathname=dy({basename:t,pathname:l.pathname})),on(l)}function Ld(n,e,t){if(!t||!Ay(t))return{path:e};if(t.formMethod&&!qy(t.formMethod))return{path:e,error:Pt(405,{method:t.formMethod})};let r=()=>({path:e,error:Pt(400,{type:"invalid-body"})}),s=(t.formMethod||"get").toUpperCase(),o=Pm(e);if(t.body!==void 0){if(t.formEncType==="text/plain"){if(!Ze(s))return r();let u=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:u}}}else if(t.formEncType==="application/json"){if(!Ze(s))return r();try{let u=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:u,text:void 0}}}catch{return r()}}}he(typeof FormData=="function","FormData is not available in this environment");let a,l;if(t.formData)a=dc(t.formData),l=t.formData;else if(t.body instanceof FormData)a=dc(t.body),l=t.body;else if(t.body instanceof URLSearchParams)a=t.body,l=_d(a);else if(t.body==null)a=new URLSearchParams,l=new FormData;else try{a=new URLSearchParams(t.body),l=_d(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(Ze(c.formMethod))return{path:e,submission:c};let d=Vn(e);return n&&d.search&&uh(d.search)&&a.append("index",""),d.search=`?${a}`,{path:on(d),submission:c}}function Id(n,e,t,r,i,s,o,a,l,c,d,u,f,p,m,b,x,w,v,k,j){let S=k?vt(k[1])?k[1].error:k[1].data:void 0,O=i.createURL(s.location),y=i.createURL(l),D;if(d&&s.errors){let B=Object.keys(s.errors)[0];D=o.findIndex(q=>q.route.id===B)}else if(k&&vt(k[1])){let B=k[0];D=o.findIndex(q=>q.route.id===B)-1}let A=k?k[1].statusCode:void 0,R=A&&A>=400,N={currentUrl:O,currentParams:s.matches[0]?.params||{},nextUrl:y,nextParams:o[0].params,...a,actionResult:S,actionStatus:A},L=$s(o),W=o.map((B,q)=>{let{route:de}=B,z=null;if(D!=null&&q>D?z=!1:de.lazy?z=!0:hh(de)?d?z=cc(de,s.loaderData,s.errors):My(s.loaderData,s.matches[q],B)&&(z=!0):z=!1,z!==null)return hc(t,r,n,L,B,c,e,z);let Y=!1;typeof j=="boolean"?Y=j:R?Y=!1:(u||O.pathname+O.search===y.pathname+y.search||O.search!==y.search||Dy(s.matches[q],B))&&(Y=!0);let ie={...N,defaultShouldRevalidate:Y},le=ki(B,ie);return hc(t,r,n,L,B,c,e,le,ie,j)}),F=[];return m.forEach((B,q)=>{if(d||!o.some(ke=>ke.route.id===B.routeId)||p.has(q))return;let de=s.fetchers.get(q),z=de&&de.state!=="idle"&&de.data===void 0,Y=jn(x,B.path,w);if(!Y){if(v&&z)return;F.push({key:q,routeId:B.routeId,path:B.path,matches:null,match:null,request:null,controller:null});return}if(b.has(q))return;let ie=Vo(Y,B.path),le=new AbortController,fe=xr(i,B.path,le.signal),we=null;if(f.has(q))f.delete(q),we=Pr(t,r,fe,Y,ie,c,e);else if(z)u&&(we=Pr(t,r,fe,Y,ie,c,e));else{let ke;typeof j=="boolean"?ke=j:R?ke=!1:ke=u;let Ae={...N,defaultShouldRevalidate:ke};ki(ie,Ae)&&(we=Pr(t,r,fe,Y,ie,c,e,Ae))}we&&F.push({key:q,routeId:B.routeId,path:B.path,matches:we,match:ie,request:fe,controller:le})}),{dsMatches:W,revalidatingFetchers:F}}function hh(n){return n.loader!=null||n.middleware!=null&&n.middleware.length>0}function cc(n,e,t){if(n.lazy)return!0;if(!hh(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 My(n,e,t){let r=!e||t.route.id!==e.route.id,i=!n.hasOwnProperty(t.route.id);return r||i}function Dy(n,e){let t=n.route.path;return n.pathname!==e.pathname||t!=null&&t.endsWith("*")&&n.params["*"]!==e.params["*"]}function ki(n,e){if(n.route.shouldRevalidate){let t=n.route.shouldRevalidate(e);if(typeof t=="boolean")return t}return e.defaultShouldRevalidate}function $d(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 d=o.find(u=>km(c,u));d?l.push({existingRoute:d,newRoute:c}):a.push(c)}),a.length>0){let c=Ti(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:d,newRoute:u}=l[c],f=d,[p]=Ti([u],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 km(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=>km(t,i))):!1}var Bd=new WeakMap,Sm=({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=Bd.get(i);o||(o={},Bd.set(i,o));let a=o[n];if(a)return a;let l=(async()=>{let c=qx(n),u=i[n]!==void 0&&n!=="hasErrorBoundary";if(c)Ee(!c,"Route property "+n+" is not a supported lazy route property. This property will be ignored."),o[n]=Promise.resolve();else if(u)Ee(!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},Fd=new WeakMap;function Ty(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 d=Fd.get(s);if(d)return{lazyRoutePromise:d,lazyHandlerPromise:d};let u=(async()=>{he(typeof n.lazy=="function","No lazy route function found");let f=await n.lazy(),p={};for(let m in f){let b=f[m];if(b===void 0)continue;let x=Jx(m),v=s[m]!==void 0&&m!=="hasErrorBoundary";x?Ee(!x,"Route property "+m+" is not a supported property to be returned from a lazy route function. This property will be ignored."):v?Ee(!v,`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]=b}Object.assign(s,p),Object.assign(s,{...r(s),lazy:void 0})})();return Fd.set(s,u),u.catch(()=>{}),{lazyRoutePromise:u,lazyHandlerPromise:u}}let o=Object.keys(n.lazy),a=[],l;for(let d of o){if(i&&i.includes(d))continue;let u=Sm({key:d,route:n,manifest:t,mapRouteProperties:r});u&&(a.push(u),d===e&&(l=u))}let c=a.length>0?Promise.all(a).then(()=>{}):void 0;return c?.catch(()=>{}),l?.catch(()=>{}),{lazyRoutePromise:c,lazyHandlerPromise:l}}async function Vd(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 Ey(n){return n.matches.some(e=>e.route.middleware)?Cm(n,()=>Vd(n)):Vd(n)}function Cm(n,e){return Ry(n,e,r=>{if(Gy(r))throw r;return r},Hy,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=On(o,o[a].route.id).route.id;return Promise.resolve({[l]:{type:"error",result:r}})}}}async function Ry(n,e,t,r,i){let{matches:s,request:o,params:a,context:l,unstable_pattern:c}=n,d=s.flatMap(f=>f.route.middleware?f.route.middleware.map(p=>[f.route.id,p]):[]);return await jm({request:o,params:a,context:l,unstable_pattern:c},d,e,t,r,i)}async function jm(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,d]=l,u,f=async()=>{if(u)throw new Error("You may only call `next()` once per middleware");try{return u={value:await jm(n,e,t,r,i,s,o+1)},u.value}catch(p){return u={value:await s(p,c,u)},u.value}};try{let p=await d(n,f),m=p!=null?r(p):void 0;return i(m)?m:u?m??u.value:(u={value:await f()},u.value)}catch(p){return await s(p,c,u)}}function Om(n,e,t,r,i){let s=Sm({key:"middleware",route:r.route,manifest:e,mapRouteProperties:n}),o=Ty(r.route,Ze(t.method)?"action":"loader",e,n,i);return{middleware:s,route:o.lazyRoutePromise,handler:o.lazyHandlerPromise}}function hc(n,e,t,r,i,s,o,a,l=null,c){let d=!1,u=Om(n,e,t,i,s);return{...i,_lazyPromises:u,shouldLoad:a,shouldRevalidateArgs:l,shouldCallHandler(f){return d=!0,l?typeof c=="boolean"?ki(i,{...l,defaultShouldRevalidate:c}):typeof f=="boolean"?ki(i,{...l,defaultShouldRevalidate:f}):ki(i,l):a},resolve(f){let{lazy:p,loader:m,middleware:b}=i.route,x=d||a||f&&!Ze(t.method)&&(p||m),w=b&&b.length>0&&!m&&!p;return x&&(Ze(t.method)||!w)?Iy({request:t,unstable_pattern:r,match:i,lazyHandlerPromise:u?.handler,lazyRoutePromise:u?.route,handlerOverride:f,scopedContext:o}):Promise.resolve({type:"data",result:void 0})}}}function Pr(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:Om(n,e,t,l,s),resolve:()=>Promise.resolve({type:"data",result:void 0})}:hc(n,e,t,$s(r),l,s,o,!0,a))}async function Ly(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:$s(t),params:t[0].params,context:i,matches:t},l=await n({...o,fetcherKey:r,runClientMiddleware:c=>{let d=o;return Cm(d,()=>c({...d,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 Iy({request:n,unstable_pattern:e,match:t,lazyHandlerPromise:r,lazyRoutePromise:i,handlerOverride:s,scopedContext:o}){let a,l,c=Ze(n.method),d=c?"action":"loader",u=f=>{let p,m=new Promise((w,v)=>p=v);l=()=>p(),n.signal.addEventListener("abort",l);let b=w=>typeof f!="function"?Promise.reject(new Error(`You cannot call the handler for a route which defines a boolean "${d}" [routeId: ${t.route.id}]`)):f({request:n,unstable_pattern:e,params:t.params,context:o},...w!==void 0?[w]:[]),x=(async()=>{try{return{type:"data",result:await(s?s(v=>b(v)):b())}}catch(w){return{type:"error",result:w}}})();return Promise.race([x,m])};try{let f=c?t.route.action:t.route.loader;if(r||i)if(f){let p,[m]=await Promise.all([u(f).catch(b=>{p=b}),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([u(p),i]);else if(d==="action"){let m=new URL(n.url),b=m.pathname+m.search;throw Pt(405,{method:n.method,pathname:b,routeId:t.route.id})}else return{type:"data",result:void 0}}else if(f)a=await u(f);else{let p=new URL(n.url),m=p.pathname+p.search;throw Pt(404,{pathname:m})}}catch(f){return{type:"error",result:f}}finally{l&&n.signal.removeEventListener("abort",l)}return a}async function $y(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 By(n){let{result:e,type:t}=n;if(dh(e)){let r;try{r=await $y(e)}catch(i){return{type:"error",error:i}}return t==="error"?{type:"error",error:new Is(e.status,e.statusText,r),statusCode:e.status,headers:e.headers}:{type:"data",data:r,statusCode:e.status,headers:e.headers}}return t==="error"?Kd(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:_y(e),statusCode:Ei(e)?e.status:void 0,headers:e.init?.headers?new Headers(e.init.headers):void 0}:{type:"error",error:e,statusCode:Ei(e)?e.status:void 0}:Kd(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 Fy(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"),!Na(s)){let o=r.slice(0,r.findIndex(a=>a.route.id===t)+1);s=lc(new URL(e.url),o,i,s),n.headers.set("Location",s)}return n}function zd(n,e,t){if(Na(n)){let r=n,i=r.startsWith("//")?new URL(e.protocol+r):new URL(r),s=Rt(i.pathname,t)!=null;if(i.origin===e.origin&&s)return i.pathname+i.search+i.hash}return n}function xr(n,e,t,r){let i=n.createURL(Pm(e)).toString(),s={signal:t};if(r&&Ze(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=dc(r.formData):s.body=r.formData}return new Request(i,s)}function dc(n){let e=new URLSearchParams;for(let[t,r]of n.entries())e.append(t,typeof r=="string"?r:r.name);return e}function _d(n){let e=new FormData;for(let[t,r]of n.entries())e.append(t,r);return e}function Vy(n,e,t,r=!1,i=!1){let s={},o=null,a,l=!1,c={},d=t&&vt(t[1])?t[1].error:void 0;return n.forEach(u=>{if(!(u.route.id in e))return;let f=u.route.id,p=e[f];if(he(!er(p),"Cannot handle redirect results in processLoaderData"),vt(p)){let m=p.error;if(d!==void 0&&(m=d,d=void 0),o=o||{},i)o[f]=m;else{let b=On(n,f);o[b.route.id]==null&&(o[b.route.id]=m)}r||(s[f]=wm),l||(l=!0,a=Ei(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)}),d!==void 0&&t&&(o={[t[0]]:d},t[2]&&(s[t[2]]=void 0)),{loaderData:s,errors:o,statusCode:a||200,loaderHeaders:c}}function Hd(n,e,t,r,i,s){let{loaderData:o,errors:a}=Vy(e,t,r);return i.filter(l=>!l.matches||l.matches.some(c=>c.shouldLoad)).forEach(l=>{let{key:c,match:d,controller:u}=l;if(u&&u.signal.aborted)return;let f=s[c];if(he(f,"Did not find corresponding fetcher result"),vt(f)){let p=On(n.matches,d?.route.id);a&&a[p.route.id]||(a={...a,[p.route.id]:f.error}),n.fetchers.delete(c)}else if(er(f))he(!1,"Unhandled fetcher revalidation redirect");else{let p=pn(f.data);n.fetchers.set(c,p)}}),{loaderData:o,errors:a}}function Wd(n,e,t,r){let i=Object.entries(e).filter(([,s])=>s!==wm).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 Ud(n){return n?vt(n[1])?{actionData:{}}:{actionData:{[n[0]]:n[1].data}}:{}}function On(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 oo(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 Pt(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 Is(n||500,o,new Error(a),!0)}function ao(n){let e=Object.entries(n);for(let t=e.length-1;t>=0;t--){let[r,i]=e[t];if(er(i))return{key:r,result:i}}}function Pm(n){let e=typeof n=="string"?Vn(n):n;return on({...e,hash:""})}function zy(n,e){return n.pathname!==e.pathname||n.search!==e.search?!1:n.hash===""?e.hash!=="":n.hash===e.hash?!0:e.hash!==""}function _y(n){return new Is(n.init?.status??500,n.init?.statusText??"Internal Server Error",n.data)}function Hy(n){return n!=null&&typeof n=="object"&&Object.entries(n).every(([e,t])=>typeof e=="string"&&Wy(t))}function Wy(n){return n!=null&&typeof n=="object"&&"type"in n&&"result"in n&&(n.type==="data"||n.type==="error")}function Uy(n){return dh(n.result)&&ym.has(n.result.status)}function vt(n){return n.type==="error"}function er(n){return(n&&n.type)==="redirect"}function Kd(n){return typeof n=="object"&&n!=null&&"type"in n&&"data"in n&&"init"in n&&n.type==="DataWithResponseInit"}function dh(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.headers=="object"&&typeof n.body<"u"}function Ky(n){return ym.has(n)}function Gy(n){return dh(n)&&Ky(n.status)&&n.headers.has("Location")}function qy(n){return Cy.has(n.toUpperCase())}function Ze(n){return ky.has(n.toUpperCase())}function uh(n){return new URLSearchParams(n).getAll("index").some(e=>e==="")}function Vo(n,e){let t=typeof e=="string"?Vn(e).search:e.search;if(n[n.length-1].route.index&&uh(t||""))return n[n.length-1];let r=pm(n);return r[r.length-1]}function Gd(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 nl(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 Yy(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 oi(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 Jy(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 pn(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 Qy(n,e){try{let t=n.sessionStorage.getItem(vm);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 Xy(n,e){if(e.size>0){let t={};for(let[r,i]of e)t[r]=[...i];try{n.sessionStorage.setItem(vm,JSON.stringify(t))}catch(r){Ee(!1,`Failed to save applied view transitions in sessionStorage (${r}).`)}}}function qd(){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 dr=g.createContext(null);dr.displayName="DataRouter";var Bs=g.createContext(null);Bs.displayName="DataRouterState";var Nm=g.createContext(!1);function Zy(){return g.useContext(Nm)}var fh=g.createContext({isTransitioning:!1});fh.displayName="ViewTransition";var Am=g.createContext(new Map);Am.displayName="Fetchers";var e1=g.createContext(null);e1.displayName="Await";var kt=g.createContext(null);kt.displayName="Navigation";var Da=g.createContext(null);Da.displayName="Location";var It=g.createContext({outlet:null,matches:[],isDataRoute:!1});It.displayName="Route";var ph=g.createContext(null);ph.displayName="RouteError";var Mm="REACT_ROUTER_ERROR",t1="REDIRECT",n1="ROUTE_ERROR_RESPONSE";function r1(n){if(n.startsWith(`${Mm}:${t1}:{`))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 i1(n){if(n.startsWith(`${Mm}:${n1}:{`))try{let e=JSON.parse(n.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new Is(e.status,e.statusText,e.data)}catch{}}function s1(n,{relative:e}={}){he(Wr(),"useHref() may be used only in the context of a <Router> component.");let{basename:t,navigator:r}=g.useContext(kt),{hash:i,pathname:s,search:o}=Fs(n,{relative:e}),a=s;return t!=="/"&&(a=s==="/"?t:rn([t,s])),r.createHref({pathname:a,search:o,hash:i})}function Wr(){return g.useContext(Da)!=null}function _t(){return he(Wr(),"useLocation() may be used only in the context of a <Router> component."),g.useContext(Da).location}var Dm="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Tm(n){g.useContext(kt).static||g.useLayoutEffect(n)}function an(){let{isDataRoute:n}=g.useContext(It);return n?v1():o1()}function o1(){he(Wr(),"useNavigate() may be used only in the context of a <Router> component.");let n=g.useContext(dr),{basename:e,navigator:t}=g.useContext(kt),{matches:r}=g.useContext(It),{pathname:i}=_t(),s=JSON.stringify(Aa(r)),o=g.useRef(!1);return Tm(()=>{o.current=!0}),g.useCallback((l,c={})=>{if(Ee(o.current,Dm),!o.current)return;if(typeof l=="number"){t.go(l);return}let d=Ma(l,JSON.parse(s),i,c.relative==="path");n==null&&e!=="/"&&(d.pathname=d.pathname==="/"?e:rn([e,d.pathname])),(c.replace?t.replace:t.push)(d,c.state,c)},[e,t,s,i,n])}var Em=g.createContext(null);function a1(){return g.useContext(Em)}function l1(n){let e=g.useContext(It).outlet;return g.useMemo(()=>e&&g.createElement(Em.Provider,{value:n},e),[e,n])}function Rm(){let{matches:n}=g.useContext(It),e=n[n.length-1];return e?e.params:{}}function Fs(n,{relative:e}={}){let{matches:t}=g.useContext(It),{pathname:r}=_t(),i=JSON.stringify(Aa(t));return g.useMemo(()=>Ma(n,JSON.parse(i),r,e==="path"),[n,i,r,e])}function c1(n,e,t,r,i){he(Wr(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:s}=g.useContext(kt),{matches:o}=g.useContext(It),a=o[o.length-1],l=a?a.params:{},c=a?a.pathname:"/",d=a?a.pathnameBase:"/",u=a&&a.route;{let v=u&&u.path||"";Im(c,!u||v.endsWith("*")||v.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${c}" (under <Route path="${v}">) 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="${v}"> to <Route path="${v==="/"?"*":`${v}/*`}">.`)}let f=_t(),p;p=f;let m=p.pathname||"/",b=m;if(d!=="/"){let v=d.replace(/^\//,"").split("/");b="/"+m.replace(/^\//,"").split("/").slice(v.length).join("/")}let x=jn(n,{pathname:b});return Ee(u||x!=null,`No routes matched location "${p.pathname}${p.search}${p.hash}" `),Ee(x==null||x[x.length-1].route.element!==void 0||x[x.length-1].route.Component!==void 0||x[x.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.`),p1(x&&x.map(v=>Object.assign({},v,{params:Object.assign({},l,v.params),pathname:rn([d,s.encodeLocation?s.encodeLocation(v.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:v.pathname]),pathnameBase:v.pathnameBase==="/"?d:rn([d,s.encodeLocation?s.encodeLocation(v.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:v.pathnameBase])})),o,t,r,i)}function h1(){let n=y1(),e=Ei(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=g.createElement(g.Fragment,null,g.createElement("p",null,"💿 Hey developer 👋"),g.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",g.createElement("code",{style:s},"ErrorBoundary")," or"," ",g.createElement("code",{style:s},"errorElement")," prop on your route.")),g.createElement(g.Fragment,null,g.createElement("h2",null,"Unexpected Application Error!"),g.createElement("h3",{style:{fontStyle:"italic"}},e),t?g.createElement("pre",{style:i},t):null,o)}var d1=g.createElement(h1,null),Lm=class extends g.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=i1(n.digest);t&&(n=t)}let e=n!==void 0?g.createElement(It.Provider,{value:this.props.routeContext},g.createElement(ph.Provider,{value:n,children:this.props.component})):this.props.children;return this.context?g.createElement(u1,{error:n},e):e}};Lm.contextType=Nm;var rl=new WeakMap;function u1({children:n,error:e}){let{basename:t}=g.useContext(kt);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let r=r1(e.digest);if(r){let i=rl.get(e);if(i)throw i;let s=gm(r.location,t);if(mm&&!rl.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 rl.set(e,o),o}return g.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return n}function f1({routeContext:n,match:e,children:t}){let r=g.useContext(dr);return r&&r.static&&r.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=e.route.id),g.createElement(It.Provider,{value:n},t)}function p1(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 d=s.findIndex(u=>u.route.id&&o?.[u.route.id]!==void 0);he(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,d+1))}let a=!1,l=-1;if(t)for(let d=0;d<s.length;d++){let u=s[d];if((u.route.HydrateFallback||u.route.hydrateFallbackElement)&&(l=d),u.route.id){let{loaderData:f,errors:p}=t,m=u.route.loader&&!f.hasOwnProperty(u.route.id)&&(!p||p[u.route.id]===void 0);if(u.route.lazy||m){a=!0,l>=0?s=s.slice(0,l+1):s=[s[0]];break}}}let c=t&&r?(d,u)=>{r(d,{location:t.location,params:t.matches?.[0]?.params??{},unstable_pattern:$s(t.matches),errorInfo:u})}:void 0;return s.reduceRight((d,u,f)=>{let p,m=!1,b=null,x=null;t&&(p=o&&u.route.id?o[u.route.id]:void 0,b=u.route.errorElement||d1,a&&(l<0&&f===0?(Im("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,x=null):l===f&&(m=!0,x=u.route.hydrateFallbackElement||null)));let w=e.concat(s.slice(0,f+1)),v=()=>{let k;return p?k=b:m?k=x:u.route.Component?k=g.createElement(u.route.Component,null):u.route.element?k=u.route.element:k=d,g.createElement(f1,{match:u,routeContext:{outlet:d,matches:w,isDataRoute:t!=null},children:k})};return t&&(u.route.ErrorBoundary||u.route.errorElement||f===0)?g.createElement(Lm,{location:t.location,revalidation:t.revalidation,component:b,error:p,children:v(),routeContext:{outlet:null,matches:w,isDataRoute:!0},onError:c}):v()},null)}function mh(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function m1(n){let e=g.useContext(dr);return he(e,mh(n)),e}function g1(n){let e=g.useContext(Bs);return he(e,mh(n)),e}function b1(n){let e=g.useContext(It);return he(e,mh(n)),e}function gh(n){let e=b1(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 x1(){return gh("useRouteId")}function y1(){let n=g.useContext(ph),e=g1("useRouteError"),t=gh("useRouteError");return n!==void 0?n:e.errors?.[t]}function v1(){let{router:n}=m1("useNavigate"),e=gh("useNavigate"),t=g.useRef(!1);return Tm(()=>{t.current=!0}),g.useCallback(async(i,s={})=>{Ee(t.current,Dm),t.current&&(typeof i=="number"?await n.navigate(i):await n.navigate(i,{fromRouteId:e,...s}))},[n,e])}var Yd={};function Im(n,e,t){!e&&!Yd[n]&&(Yd[n]=!0,Ee(!1,t))}var Jd={};function Qd(n,e){!n&&!Jd[e]&&(Jd[e]=!0,console.warn(e))}var w1="useOptimistic",Xd=Rx[w1],k1=()=>{};function S1(n){return Xd?Xd(n):[n,k1]}function C1(n){let e={hasErrorBoundary:n.hasErrorBoundary||n.ErrorBoundary!=null||n.errorElement!=null};return n.Component&&(n.element&&Ee(!1,"You should not include both `Component` and `element` on your route - `Component` will be used."),Object.assign(e,{element:g.createElement(n.Component),Component:void 0})),n.HydrateFallback&&(n.hydrateFallbackElement&&Ee(!1,"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."),Object.assign(e,{hydrateFallbackElement:g.createElement(n.HydrateFallback),HydrateFallback:void 0})),n.ErrorBoundary&&(n.errorElement&&Ee(!1,"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."),Object.assign(e,{errorElement:g.createElement(n.ErrorBoundary),ErrorBoundary:void 0})),e}var j1=["HydrateFallback","hydrateFallbackElement"],O1=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 P1({router:n,flushSync:e,onError:t,unstable_useTransitions:r}){r=Zy()||r;let[s,o]=g.useState(n.state),[a,l]=S1(s),[c,d]=g.useState(),[u,f]=g.useState({isTransitioning:!1}),[p,m]=g.useState(),[b,x]=g.useState(),[w,v]=g.useState(),k=g.useRef(new Map),j=g.useCallback((D,{deletedFetchers:A,newErrors:R,flushSync:N,viewTransitionOpts:L})=>{R&&t&&Object.values(R).forEach(F=>t(F,{location:D.location,params:D.matches[0]?.params??{},unstable_pattern:$s(D.matches)})),D.fetchers.forEach((F,B)=>{F.data!==void 0&&k.current.set(B,F.data)}),A.forEach(F=>k.current.delete(F)),Qd(N===!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 W=n.window!=null&&n.window.document!=null&&typeof n.window.document.startViewTransition=="function";if(Qd(L==null||W,"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."),!L||!W){e&&N?e(()=>o(D)):r===!1?o(D):g.startTransition(()=>{r===!0&&l(F=>Zd(F,D)),o(D)});return}if(e&&N){e(()=>{b&&(p?.resolve(),b.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:L.currentLocation,nextLocation:L.nextLocation})});let F=n.window.document.startViewTransition(()=>{e(()=>o(D))});F.finished.finally(()=>{e(()=>{m(void 0),x(void 0),d(void 0),f({isTransitioning:!1})})}),e(()=>x(F));return}b?(p?.resolve(),b.skipTransition(),v({state:D,currentLocation:L.currentLocation,nextLocation:L.nextLocation})):(d(D),f({isTransitioning:!0,flushSync:!1,currentLocation:L.currentLocation,nextLocation:L.nextLocation}))},[n.window,e,b,p,r,l,t]);g.useLayoutEffect(()=>n.subscribe(j),[n,j]),g.useEffect(()=>{u.isTransitioning&&!u.flushSync&&m(new O1)},[u]),g.useEffect(()=>{if(p&&c&&n.window){let D=c,A=p.promise,R=n.window.document.startViewTransition(async()=>{r===!1?o(D):g.startTransition(()=>{r===!0&&l(N=>Zd(N,D)),o(D)}),await A});R.finished.finally(()=>{m(void 0),x(void 0),d(void 0),f({isTransitioning:!1})}),x(R)}},[c,p,n.window,r,l]),g.useEffect(()=>{p&&c&&a.location.key===c.location.key&&p.resolve()},[p,b,a.location,c]),g.useEffect(()=>{!u.isTransitioning&&w&&(d(w.state),f({isTransitioning:!0,flushSync:!1,currentLocation:w.currentLocation,nextLocation:w.nextLocation}),v(void 0))},[u.isTransitioning,w]);let S=g.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:D=>n.navigate(D),push:(D,A,R)=>n.navigate(D,{state:A,preventScrollReset:R?.preventScrollReset}),replace:(D,A,R)=>n.navigate(D,{replace:!0,state:A,preventScrollReset:R?.preventScrollReset})}),[n]),O=n.basename||"/",y=g.useMemo(()=>({router:n,navigator:S,static:!1,basename:O,onError:t}),[n,S,O,t]);return g.createElement(g.Fragment,null,g.createElement(dr.Provider,{value:y},g.createElement(Bs.Provider,{value:a},g.createElement(Am.Provider,{value:k.current},g.createElement(fh.Provider,{value:u},g.createElement(D1,{basename:O,location:a.location,navigationType:a.historyAction,navigator:S,unstable_useTransitions:r},g.createElement(N1,{routes:n.routes,future:n.future,state:a,onError:t})))))),null)}function Zd(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 N1=g.memo(A1);function A1({routes:n,future:e,state:t,onError:r}){return c1(n,void 0,t,r,e)}function il({to:n,replace:e,state:t,relative:r}){he(Wr(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=g.useContext(kt);Ee(!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}=g.useContext(It),{pathname:o}=_t(),a=an(),l=Ma(n,Aa(s),o,r==="path"),c=JSON.stringify(l);return g.useEffect(()=>{a(JSON.parse(c),{replace:e,state:t,relative:r})},[a,c,r,e,t]),null}function M1(n){return l1(n.context)}function D1({basename:n="/",children:e=null,location:t,navigationType:r="POP",navigator:i,static:s=!1,unstable_useTransitions:o}){he(!Wr(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let a=n.replace(/^\/*/,"/"),l=g.useMemo(()=>({basename:a,navigator:i,static:s,unstable_useTransitions:o,future:{}}),[a,i,s,o]);typeof t=="string"&&(t=Vn(t));let{pathname:c="/",search:d="",hash:u="",state:f=null,key:p="default"}=t,m=g.useMemo(()=>{let b=Rt(c,a);return b==null?null:{location:{pathname:b,search:d,hash:u,state:f,key:p},navigationType:r}},[a,c,d,u,f,p,r]);return Ee(m!=null,`<Router basename="${a}"> is not able to match the URL "${c}${d}${u}" because it does not start with the basename, so the <Router> won't render anything.`),m==null?null:g.createElement(kt.Provider,{value:l},g.createElement(Da.Provider,{children:e,value:m}))}var zo="get",_o="application/x-www-form-urlencoded";function Ta(n){return typeof HTMLElement<"u"&&n instanceof HTMLElement}function T1(n){return Ta(n)&&n.tagName.toLowerCase()==="button"}function E1(n){return Ta(n)&&n.tagName.toLowerCase()==="form"}function R1(n){return Ta(n)&&n.tagName.toLowerCase()==="input"}function L1(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function I1(n,e){return n.button===0&&(!e||e==="_self")&&!L1(n)}function uc(n=""){return new URLSearchParams(typeof n=="string"||Array.isArray(n)||n instanceof URLSearchParams?n:Object.keys(n).reduce((e,t)=>{let r=n[t];return e.concat(Array.isArray(r)?r.map(i=>[t,i]):[[t,r]])},[]))}function $1(n,e){let t=uc(n);return e&&e.forEach((r,i)=>{t.has(i)||e.getAll(i).forEach(s=>{t.append(i,s)})}),t}var lo=null;function B1(){if(lo===null)try{new FormData(document.createElement("form"),0),lo=!1}catch{lo=!0}return lo}var F1=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function sl(n){return n!=null&&!F1.has(n)?(Ee(!1,`"${n}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${_o}"`),null):n}function V1(n,e){let t,r,i,s,o;if(E1(n)){let a=n.getAttribute("action");r=a?Rt(a,e):null,t=n.getAttribute("method")||zo,i=sl(n.getAttribute("enctype"))||_o,s=new FormData(n)}else if(T1(n)||R1(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?Rt(l,e):null,t=n.getAttribute("formmethod")||a.getAttribute("method")||zo,i=sl(n.getAttribute("formenctype"))||sl(a.getAttribute("enctype"))||_o,s=new FormData(a,n),!B1()){let{name:c,type:d,value:u}=n;if(d==="image"){let f=c?`${c}.`:"";s.append(`${f}x`,"0"),s.append(`${f}y`,"0")}else c&&s.append(c,u)}}else{if(Ta(n))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');t=zo,r=null,i=_o,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 bh(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function z1(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&&Rt(r.pathname,e)==="/"?r.pathname=`${e.replace(/\/$/,"")}/_root.${t}`:r.pathname=`${r.pathname.replace(/\/$/,"")}.${t}`,r}async function _1(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 H1(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 W1(n,e,t){let r=await Promise.all(n.map(async i=>{let s=e.routes[i.route.id];if(s){let o=await _1(s,t);return o.links?o.links():[]}return[]}));return q1(r.flat(1).filter(H1).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function eu(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 d=r.routes[l.route.id];if(!d||!d.hasLoader)return!1;if(o(l,c)||a(l,c))return!0;if(l.route.shouldRevalidate){let u=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 u=="boolean")return u}return!0}):[]}function U1(n,e,{includeHydrateFallback:t}={}){return K1(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 K1(n){return[...new Set(n)]}function G1(n){let e={},t=Object.keys(n).sort();for(let r of t)e[r]=n[r];return e}function q1(n,e){let t=new Set;return new Set(e),n.reduce((r,i)=>{let s=JSON.stringify(G1(i));return t.has(s)||(t.add(s),r.push({key:s,link:i})),r},[])}function $m(){let n=g.useContext(dr);return bh(n,"You must render this element inside a <DataRouterContext.Provider> element"),n}function Y1(){let n=g.useContext(Bs);return bh(n,"You must render this element inside a <DataRouterStateContext.Provider> element"),n}var xh=g.createContext(void 0);xh.displayName="FrameworkContext";function Bm(){let n=g.useContext(xh);return bh(n,"You must render this element inside a <HydratedRouter> element"),n}function J1(n,e){let t=g.useContext(xh),[r,i]=g.useState(!1),[s,o]=g.useState(!1),{onFocus:a,onBlur:l,onMouseEnter:c,onMouseLeave:d,onTouchStart:u}=e,f=g.useRef(null);g.useEffect(()=>{if(n==="render"&&o(!0),n==="viewport"){let b=w=>{w.forEach(v=>{o(v.isIntersecting)})},x=new IntersectionObserver(b,{threshold:.5});return f.current&&x.observe(f.current),()=>{x.disconnect()}}},[n]),g.useEffect(()=>{if(r){let b=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(b)}}},[r]);let p=()=>{i(!0)},m=()=>{i(!1),o(!1)};return t?n!=="intent"?[s,f,{}]:[s,f,{onFocus:ai(a,p),onBlur:ai(l,m),onMouseEnter:ai(c,p),onMouseLeave:ai(d,m),onTouchStart:ai(u,p)}]:[!1,f,{}]}function ai(n,e){return t=>{n&&n(t),t.defaultPrevented||e(t)}}function Q1({page:n,...e}){let{router:t}=$m(),r=g.useMemo(()=>jn(t.routes,n,t.basename),[t.routes,n,t.basename]);return r?g.createElement(Z1,{page:n,matches:r,...e}):null}function X1(n){let{manifest:e,routeModules:t}=Bm(),[r,i]=g.useState([]);return g.useEffect(()=>{let s=!1;return W1(n,e,t).then(o=>{s||i(o)}),()=>{s=!0}},[n,e,t]),r}function Z1({page:n,matches:e,...t}){let r=_t(),{manifest:i,routeModules:s}=Bm(),{basename:o}=$m(),{loaderData:a,matches:l}=Y1(),c=g.useMemo(()=>eu(n,e,l,i,r,"data"),[n,e,l,i,r]),d=g.useMemo(()=>eu(n,e,l,i,r,"assets"),[n,e,l,i,r]),u=g.useMemo(()=>{if(n===r.pathname+r.search+r.hash)return[];let m=new Set,b=!1;if(e.forEach(w=>{let v=i.routes[w.route.id];!v||!v.hasLoader||(!c.some(k=>k.route.id===w.route.id)&&w.route.id in a&&s[w.route.id]?.shouldRevalidate||v.hasClientLoader?b=!0:m.add(w.route.id))}),m.size===0)return[];let x=z1(n,o,"data");return b&&m.size>0&&x.searchParams.set("_routes",e.filter(w=>m.has(w.route.id)).map(w=>w.route.id).join(",")),[x.pathname+x.search]},[o,a,r,i,c,e,n,s]),f=g.useMemo(()=>U1(d,i),[d,i]),p=X1(d);return g.createElement(g.Fragment,null,u.map(m=>g.createElement("link",{key:m,rel:"prefetch",as:"fetch",href:m,...t})),f.map(m=>g.createElement("link",{key:m,rel:"modulepreload",href:m,...t})),p.map(({key:m,link:b})=>g.createElement("link",{key:m,nonce:t.nonce,...b})))}function ev(...n){return e=>{n.forEach(t=>{typeof t=="function"?t(e):t!=null&&(t.current=e)})}}var tv=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{tv&&(window.__reactRouterVersion="7.11.0")}catch{}function nv(n,e){return Ny({basename:e?.basename,getContext:e?.getContext,future:e?.future,history:Wx({window:e?.window}),hydrationData:rv(),routes:n,mapRouteProperties:C1,hydrationRouteProperties:j1,dataStrategy:e?.dataStrategy,patchRoutesOnNavigation:e?.patchRoutesOnNavigation,window:e?.window,unstable_instrumentations:e?.unstable_instrumentations}).initialize()}function rv(){let n=window?.__staticRouterHydrationData;return n&&n.errors&&(n={...n,errors:iv(n.errors)}),n}function iv(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 Is(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,Vm=g.forwardRef(function({onClick:e,discover:t="render",prefetch:r="none",relative:i,reloadDocument:s,replace:o,state:a,target:l,to:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f,...p},m){let{basename:b,unstable_useTransitions:x}=g.useContext(kt),w=typeof c=="string"&&Fm.test(c),v=gm(c,b);c=v.to;let k=s1(c,{relative:i}),[j,S,O]=J1(r,p),y=lv(c,{replace:o,state:a,target:l,preventScrollReset:d,relative:i,viewTransition:u,unstable_defaultShouldRevalidate:f,unstable_useTransitions:x});function D(R){e&&e(R),R.defaultPrevented||y(R)}let A=g.createElement("a",{...p,...O,href:v.absoluteURL||k,onClick:v.isExternal||s?e:D,ref:ev(m,S),target:l,"data-discover":!w&&t==="render"?"true":void 0});return j&&!w?g.createElement(g.Fragment,null,A,g.createElement(Q1,{page:k})):A});Vm.displayName="Link";var sv=g.forwardRef(function({"aria-current":e="page",caseSensitive:t=!1,className:r="",end:i=!1,style:s,to:o,viewTransition:a,children:l,...c},d){let u=Fs(o,{relative:c.relative}),f=_t(),p=g.useContext(Bs),{navigator:m,basename:b}=g.useContext(kt),x=p!=null&&pv(u)&&a===!0,w=m.encodeLocation?m.encodeLocation(u).pathname:u.pathname,v=f.pathname,k=p&&p.navigation&&p.navigation.location?p.navigation.location.pathname:null;t||(v=v.toLowerCase(),k=k?k.toLowerCase():null,w=w.toLowerCase()),k&&b&&(k=Rt(k,b)||k);const j=w!=="/"&&w.endsWith("/")?w.length-1:w.length;let S=v===w||!i&&v.startsWith(w)&&v.charAt(j)==="/",O=k!=null&&(k===w||!i&&k.startsWith(w)&&k.charAt(w.length)==="/"),y={isActive:S,isPending:O,isTransitioning:x},D=S?e:void 0,A;typeof r=="function"?A=r(y):A=[r,S?"active":null,O?"pending":null,x?"transitioning":null].filter(Boolean).join(" ");let R=typeof s=="function"?s(y):s;return g.createElement(Vm,{...c,"aria-current":D,className:A,ref:d,style:R,to:o,viewTransition:a},typeof l=="function"?l(y):l)});sv.displayName="NavLink";var ov=g.forwardRef(({discover:n="render",fetcherKey:e,navigate:t,reloadDocument:r,replace:i,state:s,method:o=zo,action:a,onSubmit:l,relative:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f,...p},m)=>{let{unstable_useTransitions:b}=g.useContext(kt),x=uv(),w=fv(a,{relative:c}),v=o.toLowerCase()==="get"?"get":"post",k=typeof a=="string"&&Fm.test(a),j=S=>{if(l&&l(S),S.defaultPrevented)return;S.preventDefault();let O=S.nativeEvent.submitter,y=O?.getAttribute("formmethod")||o,D=()=>x(O||S.currentTarget,{fetcherKey:e,method:y,navigate:t,replace:i,state:s,relative:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f});b&&t!==!1?g.startTransition(()=>D()):D()};return g.createElement("form",{ref:m,method:v,action:w,onSubmit:r?l:j,...p,"data-discover":!k&&n==="render"?"true":void 0})});ov.displayName="Form";function av(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function zm(n){let e=g.useContext(dr);return he(e,av(n)),e}function lv(n,{target:e,replace:t,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a,unstable_useTransitions:l}={}){let c=an(),d=_t(),u=Fs(n,{relative:s});return g.useCallback(f=>{if(I1(f,e)){f.preventDefault();let p=t!==void 0?t:on(d)===on(u),m=()=>c(n,{replace:p,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a});l?g.startTransition(()=>m()):m()}},[d,c,u,t,r,e,n,i,s,o,a,l])}function cv(n){Ee(typeof URLSearchParams<"u","You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.");let e=g.useRef(uc(n)),t=g.useRef(!1),r=_t(),i=g.useMemo(()=>$1(r.search,t.current?null:e.current),[r.search]),s=an(),o=g.useCallback((a,l)=>{const c=uc(typeof a=="function"?a(new URLSearchParams(i)):a);t.current=!0,s("?"+c,l)},[s,i]);return[i,o]}var hv=0,dv=()=>`__${String(++hv)}__`;function uv(){let{router:n}=zm("useSubmit"),{basename:e}=g.useContext(kt),t=x1(),r=n.fetch,i=n.navigate;return g.useCallback(async(s,o={})=>{let{action:a,method:l,encType:c,formData:d,body:u}=V1(s,e);if(o.navigate===!1){let f=o.fetcherKey||dv();await r(f,t,o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:d,body:u,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:d,body:u,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 fv(n,{relative:e}={}){let{basename:t}=g.useContext(kt),r=g.useContext(It);he(r,"useFormAction must be used inside a RouteContext");let[i]=r.matches.slice(-1),s={...Fs(n||".",{relative:e})},o=_t();if(n==null){s.search=o.search;let a=new URLSearchParams(s.search),l=a.getAll("index");if(l.some(d=>d==="")){a.delete("index"),l.filter(u=>u).forEach(u=>a.append("index",u));let d=a.toString();s.search=d?`?${d}`:""}}return(!n||n===".")&&i.route.index&&(s.search=s.search?s.search.replace(/^\?/,"?index&"):"?index"),t!=="/"&&(s.pathname=s.pathname==="/"?t:rn([t,s.pathname])),on(s)}function pv(n,{relative:e}={}){let t=g.useContext(fh);he(t!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=zm("useViewTransitionState"),i=Fs(n,{relative:e});if(!t.isTransitioning)return!1;let s=Rt(t.currentLocation.pathname,r)||t.currentLocation.pathname,o=Rt(t.nextLocation.pathname,r)||t.nextLocation.pathname;return Zo(i.pathname,o)!=null||Zo(i.pathname,s)!=null}function mv(n){return g.createElement(P1,{flushSync:om.flushSync,...n})}const gv={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",useGlobalFallback:"Use global fallback",openAtPath:"Open at project path",openAppOnly:"Open app only",actionOptionsLoadFailed:"Could not load editor/terminal options",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",readOnly:"Read-only",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",componentFilterUpdatesCount:"Updates ({count})",componentFilterUpToDate:"Up to date",componentFilterUpToDateCount:"Up to date ({count})",componentFilterCli:"CLI",componentFilterKits:"Kits",noComponentsMatchFilter:"No components match the current filter.",runCheckAllForFilter:"Run Check All to populate this filter.",noUpdatesFound:"No updates found. Checked components are up to date.",noUpToDateYet:"No components are up to date yet.",configWorkspaceHint:"Edit configuration or manage system updates from one workspace.",settingsJsonHeading:"Claude Settings JSON",settingsJsonMissing:"No settings file found at ~/.claude/settings.json.",settingsJsonLoadFailed:"Failed to load ~/.claude/settings.json.",settingsBackupSaved:"Backup saved",hookDiagnosticsTitle:"Hook Diagnostics",hookDiagnosticsDesc:"Inspect recent hook activity and failures without opening JSONL files manually.",hookDiagnosticsPathPending:"Resolving log path...",hookDiagnosticsScopeGlobal:"Global hooks",hookDiagnosticsEntries:"Entries",hookDiagnosticsCrashes:"Crashes",hookDiagnosticsWarnings:"Warnings",hookDiagnosticsBlocks:"Blocks",hookDiagnosticsLastEvent:"Last event",hookDiagnosticsLoading:"Loading hook diagnostics...",hookDiagnosticsLoadFailed:"Failed to load hook diagnostics",hookDiagnosticsMissing:"No hook log file found for this scope yet.",hookDiagnosticsEmpty:"Hook log is present but contains no readable entries.",hookDiagnosticsParseErrorsNotice:"Skipped {count} malformed log line(s) while loading diagnostics.",hookDiagnosticsTruncatedNotice:"Showing a bounded recent window to keep diagnostics responsive on large logs.",hookDiagnosticsToolLabel:"tool",hookDiagnosticsTargetLabel:"target",hookDiagnosticsUnknown:"Unknown",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",fieldStatuslineColors:"Statusline Colors",fieldStatuslineColorsDesc:"Enable ANSI color output in the statusline",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",sectionModelTaxonomy:"Model Taxonomy",taxonomyDescription:"Customize model mappings for portable migration to other coding agents.",taxonomyTierHeavy:"Heavy (opus)",taxonomyTierBalanced:"Balanced (sonnet)",taxonomyTierLight:"Light (haiku)",taxonomyModel:"Model",taxonomyEffort:"Effort",taxonomyResetProvider:"Reset",taxonomyTier:"Tier",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",migratePresetCore:"Codex + Antigravity + Droid",migratePresetDetected:"All Detected",migrateScope:"Scope",migrateScopeProject:"Project",migrateScopeGlobal:"Global",migrateTypes:"Portable Types",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateTypeHooks:"Hooks",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",migrateActionInstall:"Install",migrateActionUpdate:"Update",migrateActionSkip:"Skip",migrateActionConflict:"Conflict",migrateActionDelete:"Delete",migrateUnchanged:"unchanged",migrateConflictSectionTitle:"Conflicts",migrateConflictUseCK:"Use CK",migrateConflictKeepMine:"Keep Mine",migrateConflictSmartMerge:"Smart Merge",migrateConflictShowDiff:"Show Diff",migrateConflictHideDiff:"Hide Diff",migrateConflictResolved:"Resolved",migrateConflictManual:"Manual",migrateConflictOverwriteAll:"Overwrite All",migrateConflictKeepAll:"Keep All",migrateSummaryTitle:"Migration Complete",migrateSummaryNewMigration:"New Migration",migrateType:"Type",migrateItem:"Item",migrateReconciling:"Analyzing changes...",migrateReviewPlan:"Review Plan",migrateExecutePlan:"Execute Migration",migrateExecuting:"Executing migration...",migrateResolveConflicts:"Resolve all conflicts before executing",migrateSummarySubtitle:"items migrated",migrateSummarySearchPlaceholder:"Search items...",migrateSummaryFilterAll:"All",migrateSummaryCollapseAll:"Collapse all",migrateSummaryExpandAll:"Expand all",migrateSummaryNoResults:"No items match your search",migrateSummaryProviders:"Providers",migrateTypeUnknown:"Other",kanbanTitle:"Plan Kanban",kanbanNoFile:"No plan file specified. Use ?file= parameter.",kanbanNoPhases:"No phases detected in this plan",kanbanError400:"Invalid request — missing file parameter",kanbanError403:"Access denied — file is outside the project directory",kanbanError404:"Plan file not found",kanbanComplete:"complete",kanbanStatus_pending:"Pending","kanbanStatus_in-progress":"In Progress",kanbanStatus_completed:"Completed",kanbanPhases:"phases",kanbanProgress:"Progress",kanbanLoadError:"Failed to load plan data",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",useGlobalFallback:"Dùng fallback global",openAtPath:"Mở tại đường dẫn dự án",openAppOnly:"Chỉ mở ứng dụng",actionOptionsLoadFailed:"Không thể tải tùy chọn editor/terminal",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",readOnly:"Chỉ đọc",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",componentFilterUpdatesCount:"Bản cập nhật ({count})",componentFilterUpToDate:"Đã cập nhật",componentFilterUpToDateCount:"Đã cập nhật ({count})",componentFilterCli:"CLI",componentFilterKits:"Kit",noComponentsMatchFilter:"Không có thành phần phù hợp bộ lọc hiện tại.",runCheckAllForFilter:"Hãy chạy Kiểm tra tất cả để nạp dữ liệu cho bộ lọc này.",noUpdatesFound:"Không có bản cập nhật. Các thành phần đã kiểm tra đều mới nhất.",noUpToDateYet:"Chưa có thành phần nào ở trạng thái đã cập nhật.",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.",settingsJsonHeading:"JSON Cài đặt Claude",settingsJsonMissing:"Không tìm thấy tệp ~/.claude/settings.json.",settingsJsonLoadFailed:"Không thể tải ~/.claude/settings.json.",settingsBackupSaved:"Đã lưu bản sao lưu",hookDiagnosticsTitle:"Chẩn đoán Hook",hookDiagnosticsDesc:"Xem hoạt động hook gần đây và lỗi mà không cần mở tệp JSONL thủ công.",hookDiagnosticsPathPending:"Đang xác định đường dẫn log...",hookDiagnosticsScopeGlobal:"Hook toàn cục",hookDiagnosticsEntries:"Bản ghi",hookDiagnosticsCrashes:"Sự cố",hookDiagnosticsWarnings:"Cảnh báo",hookDiagnosticsBlocks:"Chặn",hookDiagnosticsLastEvent:"Sự kiện cuối",hookDiagnosticsLoading:"Đang tải chẩn đoán hook...",hookDiagnosticsLoadFailed:"Không thể tải chẩn đoán hook",hookDiagnosticsMissing:"Chưa tìm thấy tệp log hook cho phạm vi này.",hookDiagnosticsEmpty:"Tệp log hook có tồn tại nhưng không có bản ghi đọc được.",hookDiagnosticsParseErrorsNotice:"Đã bỏ qua {count} dòng log bị lỗi khi tải chẩn đoán.",hookDiagnosticsTruncatedNotice:"Đang hiển thị cửa sổ bản ghi gần đây để giữ giao diện phản hồi tốt với log lớn.",hookDiagnosticsToolLabel:"công cụ",hookDiagnosticsTargetLabel:"mục tiêu",hookDiagnosticsUnknown:"Không rõ",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",fieldStatuslineColors:"Màu thanh trạng thái",fieldStatuslineColorsDesc:"Bật màu ANSI trong 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",sectionModelTaxonomy:"Phân loại mô hình",taxonomyDescription:"Tuỳ chỉnh ánh xạ mô hình cho migration portable sang coding agent khác.",taxonomyTierHeavy:"Nặng (opus)",taxonomyTierBalanced:"Cân bằng (sonnet)",taxonomyTierLight:"Nhẹ (haiku)",taxonomyModel:"Mô hình",taxonomyEffort:"Mức nỗ lực",taxonomyResetProvider:"Đặt lại",taxonomyTier:"Cấp độ",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",migratePresetCore:"Codex + Antigravity + Droid",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",migrateTypeHooks:"Hooks",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",migrateActionInstall:"Cài",migrateActionUpdate:"Cập nhật",migrateActionSkip:"Bỏ qua",migrateActionConflict:"Xung đột",migrateActionDelete:"Xóa",migrateUnchanged:"chưa thay đổi",migrateConflictSectionTitle:"Xung đột",migrateConflictUseCK:"Dùng CK",migrateConflictKeepMine:"Giữ của tôi",migrateConflictSmartMerge:"Merge thông minh",migrateConflictShowDiff:"Hiện diff",migrateConflictHideDiff:"Ẩn diff",migrateConflictResolved:"Đã giải quyết",migrateConflictManual:"Thủ công",migrateConflictOverwriteAll:"Ghi đè tất cả",migrateConflictKeepAll:"Giữ tất cả",migrateSummaryTitle:"Di trú hoàn tất",migrateSummaryNewMigration:"Di trú mới",migrateType:"Loại",migrateItem:"Mục",migrateReconciling:"Đang phân tích thay đổi...",migrateReviewPlan:"Xem kế hoạch",migrateExecutePlan:"Thực hiện di trú",migrateExecuting:"Đang thực hiện di trú...",migrateResolveConflicts:"Giải quyết xung đột trước khi thực hiện",migrateSummarySubtitle:"mục đã di trú",migrateSummarySearchPlaceholder:"Tìm kiếm...",migrateSummaryFilterAll:"Tất cả",migrateSummaryCollapseAll:"Thu gọn",migrateSummaryExpandAll:"Mở rộng",migrateSummaryNoResults:"Không tìm thấy mục nào",migrateSummaryProviders:"Provider",migrateTypeUnknown:"Khác",kanbanTitle:"Bảng Kanban Kế hoạch",kanbanNoFile:"Chưa chọn file kế hoạch. Dùng tham số ?file=.",kanbanNoPhases:"Không phát hiện giai đoạn nào trong kế hoạch này",kanbanError400:"Yêu cầu không hợp lệ — thiếu tham số file",kanbanError403:"Truy cập bị từ chối — file nằm ngoài thư mục dự án",kanbanError404:"Không tìm thấy file kế hoạch",kanbanComplete:"hoàn thành",kanbanStatus_pending:"Chờ xử lý","kanbanStatus_in-progress":"Đang thực hiện",kanbanStatus_completed:"Hoàn thành",kanbanPhases:"giai đoạn",kanbanProgress:"Tiến độ",kanbanLoadError:"Không thể tải dữ liệu kế hoạch",developmentFeature:"Đang phát triển",betaFeature:"Beta",experimentalFeature:"Thử nghiệm"}},yh=g.createContext(null),_m="ck-dashboard-lang";function bv(){const n=localStorage.getItem(_m);return n==="en"||n==="vi"?n:navigator.language.startsWith("vi")?"vi":"en"}function xv({children:n}){const[e,t]=g.useState(bv),r=g.useCallback(o=>{localStorage.setItem(_m,o),t(o)},[]),i=g.useCallback(o=>gv[e][o],[e]),s=g.useMemo(()=>({lang:e,setLang:r,t:i}),[e,r,i]);return h.jsx(yh.Provider,{value:s,children:n})}function ce(){const n=g.useContext(yh);if(!n)throw new Error("useI18n must be used within I18nProvider");return n}class yv extends g.Component{constructor(){super(...arguments);jd(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 h.jsx(yh.Consumer,{children:r=>h.jsx("div",{className:"flex h-screen items-center justify-center bg-dash-bg",children:h.jsx("div",{className:"text-center space-y-4 max-w-md px-6",children:t?h.jsxs(h.Fragment,{children:[h.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:"🔌"}),h.jsx("h1",{className:"text-2xl font-bold text-orange-500",children:r?.t("serverNotRunning")??"Server Not Running"}),h.jsx("p",{className:"text-dash-text-secondary",children:r?.t("startServerMessage")??"The Config UI requires the backend server to be running."}),h.jsxs("div",{className:"bg-dash-surface border border-dash-border rounded-lg p-4",children:[h.jsx("p",{className:"text-xs text-dash-text-muted uppercase tracking-widest mb-2 font-bold",children:r?.t("runThisCommand")??"Run this command"}),h.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"})]}),h.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"})]}):h.jsxs(h.Fragment,{children:[h.jsx("h1",{className:"text-2xl font-bold text-red-500",children:r?.t("somethingWentWrong")??"Something went wrong"}),h.jsx("p",{className:"text-dash-text-muted",children:this.state.error?.message}),h.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 tr=({direction:n="horizontal",isDragging:e=!1,onMouseDown:t})=>{const r=n==="horizontal";return h.jsx("div",{onMouseDown:t,className:`
|
|
21
|
+
Please change the parent <Route path="${v}"> to <Route path="${v==="/"?"*":`${v}/*`}">.`)}let f=_t(),p;p=f;let m=p.pathname||"/",b=m;if(d!=="/"){let v=d.replace(/^\//,"").split("/");b="/"+m.replace(/^\//,"").split("/").slice(v.length).join("/")}let x=jn(n,{pathname:b});return Ee(u||x!=null,`No routes matched location "${p.pathname}${p.search}${p.hash}" `),Ee(x==null||x[x.length-1].route.element!==void 0||x[x.length-1].route.Component!==void 0||x[x.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.`),p1(x&&x.map(v=>Object.assign({},v,{params:Object.assign({},l,v.params),pathname:rn([d,s.encodeLocation?s.encodeLocation(v.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:v.pathname]),pathnameBase:v.pathnameBase==="/"?d:rn([d,s.encodeLocation?s.encodeLocation(v.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:v.pathnameBase])})),o,t,r,i)}function h1(){let n=y1(),e=Ei(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=g.createElement(g.Fragment,null,g.createElement("p",null,"💿 Hey developer 👋"),g.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",g.createElement("code",{style:s},"ErrorBoundary")," or"," ",g.createElement("code",{style:s},"errorElement")," prop on your route.")),g.createElement(g.Fragment,null,g.createElement("h2",null,"Unexpected Application Error!"),g.createElement("h3",{style:{fontStyle:"italic"}},e),t?g.createElement("pre",{style:i},t):null,o)}var d1=g.createElement(h1,null),Lm=class extends g.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=i1(n.digest);t&&(n=t)}let e=n!==void 0?g.createElement(It.Provider,{value:this.props.routeContext},g.createElement(ph.Provider,{value:n,children:this.props.component})):this.props.children;return this.context?g.createElement(u1,{error:n},e):e}};Lm.contextType=Nm;var rl=new WeakMap;function u1({children:n,error:e}){let{basename:t}=g.useContext(kt);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let r=r1(e.digest);if(r){let i=rl.get(e);if(i)throw i;let s=gm(r.location,t);if(mm&&!rl.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 rl.set(e,o),o}return g.createElement("meta",{httpEquiv:"refresh",content:`0;url=${s.absoluteURL||s.to}`})}}return n}function f1({routeContext:n,match:e,children:t}){let r=g.useContext(dr);return r&&r.static&&r.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=e.route.id),g.createElement(It.Provider,{value:n},t)}function p1(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 d=s.findIndex(u=>u.route.id&&o?.[u.route.id]!==void 0);he(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,d+1))}let a=!1,l=-1;if(t)for(let d=0;d<s.length;d++){let u=s[d];if((u.route.HydrateFallback||u.route.hydrateFallbackElement)&&(l=d),u.route.id){let{loaderData:f,errors:p}=t,m=u.route.loader&&!f.hasOwnProperty(u.route.id)&&(!p||p[u.route.id]===void 0);if(u.route.lazy||m){a=!0,l>=0?s=s.slice(0,l+1):s=[s[0]];break}}}let c=t&&r?(d,u)=>{r(d,{location:t.location,params:t.matches?.[0]?.params??{},unstable_pattern:$s(t.matches),errorInfo:u})}:void 0;return s.reduceRight((d,u,f)=>{let p,m=!1,b=null,x=null;t&&(p=o&&u.route.id?o[u.route.id]:void 0,b=u.route.errorElement||d1,a&&(l<0&&f===0?(Im("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,x=null):l===f&&(m=!0,x=u.route.hydrateFallbackElement||null)));let w=e.concat(s.slice(0,f+1)),v=()=>{let k;return p?k=b:m?k=x:u.route.Component?k=g.createElement(u.route.Component,null):u.route.element?k=u.route.element:k=d,g.createElement(f1,{match:u,routeContext:{outlet:d,matches:w,isDataRoute:t!=null},children:k})};return t&&(u.route.ErrorBoundary||u.route.errorElement||f===0)?g.createElement(Lm,{location:t.location,revalidation:t.revalidation,component:b,error:p,children:v(),routeContext:{outlet:null,matches:w,isDataRoute:!0},onError:c}):v()},null)}function mh(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function m1(n){let e=g.useContext(dr);return he(e,mh(n)),e}function g1(n){let e=g.useContext(Bs);return he(e,mh(n)),e}function b1(n){let e=g.useContext(It);return he(e,mh(n)),e}function gh(n){let e=b1(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 x1(){return gh("useRouteId")}function y1(){let n=g.useContext(ph),e=g1("useRouteError"),t=gh("useRouteError");return n!==void 0?n:e.errors?.[t]}function v1(){let{router:n}=m1("useNavigate"),e=gh("useNavigate"),t=g.useRef(!1);return Tm(()=>{t.current=!0}),g.useCallback(async(i,s={})=>{Ee(t.current,Dm),t.current&&(typeof i=="number"?await n.navigate(i):await n.navigate(i,{fromRouteId:e,...s}))},[n,e])}var Yd={};function Im(n,e,t){!e&&!Yd[n]&&(Yd[n]=!0,Ee(!1,t))}var Jd={};function Qd(n,e){!n&&!Jd[e]&&(Jd[e]=!0,console.warn(e))}var w1="useOptimistic",Xd=Rx[w1],k1=()=>{};function S1(n){return Xd?Xd(n):[n,k1]}function C1(n){let e={hasErrorBoundary:n.hasErrorBoundary||n.ErrorBoundary!=null||n.errorElement!=null};return n.Component&&(n.element&&Ee(!1,"You should not include both `Component` and `element` on your route - `Component` will be used."),Object.assign(e,{element:g.createElement(n.Component),Component:void 0})),n.HydrateFallback&&(n.hydrateFallbackElement&&Ee(!1,"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - `HydrateFallback` will be used."),Object.assign(e,{hydrateFallbackElement:g.createElement(n.HydrateFallback),HydrateFallback:void 0})),n.ErrorBoundary&&(n.errorElement&&Ee(!1,"You should not include both `ErrorBoundary` and `errorElement` on your route - `ErrorBoundary` will be used."),Object.assign(e,{errorElement:g.createElement(n.ErrorBoundary),ErrorBoundary:void 0})),e}var j1=["HydrateFallback","hydrateFallbackElement"],O1=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 P1({router:n,flushSync:e,onError:t,unstable_useTransitions:r}){r=Zy()||r;let[s,o]=g.useState(n.state),[a,l]=S1(s),[c,d]=g.useState(),[u,f]=g.useState({isTransitioning:!1}),[p,m]=g.useState(),[b,x]=g.useState(),[w,v]=g.useState(),k=g.useRef(new Map),j=g.useCallback((D,{deletedFetchers:A,newErrors:R,flushSync:N,viewTransitionOpts:L})=>{R&&t&&Object.values(R).forEach(F=>t(F,{location:D.location,params:D.matches[0]?.params??{},unstable_pattern:$s(D.matches)})),D.fetchers.forEach((F,B)=>{F.data!==void 0&&k.current.set(B,F.data)}),A.forEach(F=>k.current.delete(F)),Qd(N===!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 W=n.window!=null&&n.window.document!=null&&typeof n.window.document.startViewTransition=="function";if(Qd(L==null||W,"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."),!L||!W){e&&N?e(()=>o(D)):r===!1?o(D):g.startTransition(()=>{r===!0&&l(F=>Zd(F,D)),o(D)});return}if(e&&N){e(()=>{b&&(p?.resolve(),b.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:L.currentLocation,nextLocation:L.nextLocation})});let F=n.window.document.startViewTransition(()=>{e(()=>o(D))});F.finished.finally(()=>{e(()=>{m(void 0),x(void 0),d(void 0),f({isTransitioning:!1})})}),e(()=>x(F));return}b?(p?.resolve(),b.skipTransition(),v({state:D,currentLocation:L.currentLocation,nextLocation:L.nextLocation})):(d(D),f({isTransitioning:!0,flushSync:!1,currentLocation:L.currentLocation,nextLocation:L.nextLocation}))},[n.window,e,b,p,r,l,t]);g.useLayoutEffect(()=>n.subscribe(j),[n,j]),g.useEffect(()=>{u.isTransitioning&&!u.flushSync&&m(new O1)},[u]),g.useEffect(()=>{if(p&&c&&n.window){let D=c,A=p.promise,R=n.window.document.startViewTransition(async()=>{r===!1?o(D):g.startTransition(()=>{r===!0&&l(N=>Zd(N,D)),o(D)}),await A});R.finished.finally(()=>{m(void 0),x(void 0),d(void 0),f({isTransitioning:!1})}),x(R)}},[c,p,n.window,r,l]),g.useEffect(()=>{p&&c&&a.location.key===c.location.key&&p.resolve()},[p,b,a.location,c]),g.useEffect(()=>{!u.isTransitioning&&w&&(d(w.state),f({isTransitioning:!0,flushSync:!1,currentLocation:w.currentLocation,nextLocation:w.nextLocation}),v(void 0))},[u.isTransitioning,w]);let S=g.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:D=>n.navigate(D),push:(D,A,R)=>n.navigate(D,{state:A,preventScrollReset:R?.preventScrollReset}),replace:(D,A,R)=>n.navigate(D,{replace:!0,state:A,preventScrollReset:R?.preventScrollReset})}),[n]),O=n.basename||"/",y=g.useMemo(()=>({router:n,navigator:S,static:!1,basename:O,onError:t}),[n,S,O,t]);return g.createElement(g.Fragment,null,g.createElement(dr.Provider,{value:y},g.createElement(Bs.Provider,{value:a},g.createElement(Am.Provider,{value:k.current},g.createElement(fh.Provider,{value:u},g.createElement(D1,{basename:O,location:a.location,navigationType:a.historyAction,navigator:S,unstable_useTransitions:r},g.createElement(N1,{routes:n.routes,future:n.future,state:a,onError:t})))))),null)}function Zd(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 N1=g.memo(A1);function A1({routes:n,future:e,state:t,onError:r}){return c1(n,void 0,t,r,e)}function il({to:n,replace:e,state:t,relative:r}){he(Wr(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=g.useContext(kt);Ee(!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}=g.useContext(It),{pathname:o}=_t(),a=an(),l=Ma(n,Aa(s),o,r==="path"),c=JSON.stringify(l);return g.useEffect(()=>{a(JSON.parse(c),{replace:e,state:t,relative:r})},[a,c,r,e,t]),null}function M1(n){return l1(n.context)}function D1({basename:n="/",children:e=null,location:t,navigationType:r="POP",navigator:i,static:s=!1,unstable_useTransitions:o}){he(!Wr(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let a=n.replace(/^\/*/,"/"),l=g.useMemo(()=>({basename:a,navigator:i,static:s,unstable_useTransitions:o,future:{}}),[a,i,s,o]);typeof t=="string"&&(t=Vn(t));let{pathname:c="/",search:d="",hash:u="",state:f=null,key:p="default"}=t,m=g.useMemo(()=>{let b=Rt(c,a);return b==null?null:{location:{pathname:b,search:d,hash:u,state:f,key:p},navigationType:r}},[a,c,d,u,f,p,r]);return Ee(m!=null,`<Router basename="${a}"> is not able to match the URL "${c}${d}${u}" because it does not start with the basename, so the <Router> won't render anything.`),m==null?null:g.createElement(kt.Provider,{value:l},g.createElement(Da.Provider,{children:e,value:m}))}var zo="get",_o="application/x-www-form-urlencoded";function Ta(n){return typeof HTMLElement<"u"&&n instanceof HTMLElement}function T1(n){return Ta(n)&&n.tagName.toLowerCase()==="button"}function E1(n){return Ta(n)&&n.tagName.toLowerCase()==="form"}function R1(n){return Ta(n)&&n.tagName.toLowerCase()==="input"}function L1(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function I1(n,e){return n.button===0&&(!e||e==="_self")&&!L1(n)}function uc(n=""){return new URLSearchParams(typeof n=="string"||Array.isArray(n)||n instanceof URLSearchParams?n:Object.keys(n).reduce((e,t)=>{let r=n[t];return e.concat(Array.isArray(r)?r.map(i=>[t,i]):[[t,r]])},[]))}function $1(n,e){let t=uc(n);return e&&e.forEach((r,i)=>{t.has(i)||e.getAll(i).forEach(s=>{t.append(i,s)})}),t}var lo=null;function B1(){if(lo===null)try{new FormData(document.createElement("form"),0),lo=!1}catch{lo=!0}return lo}var F1=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function sl(n){return n!=null&&!F1.has(n)?(Ee(!1,`"${n}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${_o}"`),null):n}function V1(n,e){let t,r,i,s,o;if(E1(n)){let a=n.getAttribute("action");r=a?Rt(a,e):null,t=n.getAttribute("method")||zo,i=sl(n.getAttribute("enctype"))||_o,s=new FormData(n)}else if(T1(n)||R1(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?Rt(l,e):null,t=n.getAttribute("formmethod")||a.getAttribute("method")||zo,i=sl(n.getAttribute("formenctype"))||sl(a.getAttribute("enctype"))||_o,s=new FormData(a,n),!B1()){let{name:c,type:d,value:u}=n;if(d==="image"){let f=c?`${c}.`:"";s.append(`${f}x`,"0"),s.append(`${f}y`,"0")}else c&&s.append(c,u)}}else{if(Ta(n))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');t=zo,r=null,i=_o,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 bh(n,e){if(n===!1||n===null||typeof n>"u")throw new Error(e)}function z1(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&&Rt(r.pathname,e)==="/"?r.pathname=`${e.replace(/\/$/,"")}/_root.${t}`:r.pathname=`${r.pathname.replace(/\/$/,"")}.${t}`,r}async function _1(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 H1(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 W1(n,e,t){let r=await Promise.all(n.map(async i=>{let s=e.routes[i.route.id];if(s){let o=await _1(s,t);return o.links?o.links():[]}return[]}));return q1(r.flat(1).filter(H1).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function eu(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 d=r.routes[l.route.id];if(!d||!d.hasLoader)return!1;if(o(l,c)||a(l,c))return!0;if(l.route.shouldRevalidate){let u=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 u=="boolean")return u}return!0}):[]}function U1(n,e,{includeHydrateFallback:t}={}){return K1(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 K1(n){return[...new Set(n)]}function G1(n){let e={},t=Object.keys(n).sort();for(let r of t)e[r]=n[r];return e}function q1(n,e){let t=new Set;return new Set(e),n.reduce((r,i)=>{let s=JSON.stringify(G1(i));return t.has(s)||(t.add(s),r.push({key:s,link:i})),r},[])}function $m(){let n=g.useContext(dr);return bh(n,"You must render this element inside a <DataRouterContext.Provider> element"),n}function Y1(){let n=g.useContext(Bs);return bh(n,"You must render this element inside a <DataRouterStateContext.Provider> element"),n}var xh=g.createContext(void 0);xh.displayName="FrameworkContext";function Bm(){let n=g.useContext(xh);return bh(n,"You must render this element inside a <HydratedRouter> element"),n}function J1(n,e){let t=g.useContext(xh),[r,i]=g.useState(!1),[s,o]=g.useState(!1),{onFocus:a,onBlur:l,onMouseEnter:c,onMouseLeave:d,onTouchStart:u}=e,f=g.useRef(null);g.useEffect(()=>{if(n==="render"&&o(!0),n==="viewport"){let b=w=>{w.forEach(v=>{o(v.isIntersecting)})},x=new IntersectionObserver(b,{threshold:.5});return f.current&&x.observe(f.current),()=>{x.disconnect()}}},[n]),g.useEffect(()=>{if(r){let b=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(b)}}},[r]);let p=()=>{i(!0)},m=()=>{i(!1),o(!1)};return t?n!=="intent"?[s,f,{}]:[s,f,{onFocus:ai(a,p),onBlur:ai(l,m),onMouseEnter:ai(c,p),onMouseLeave:ai(d,m),onTouchStart:ai(u,p)}]:[!1,f,{}]}function ai(n,e){return t=>{n&&n(t),t.defaultPrevented||e(t)}}function Q1({page:n,...e}){let{router:t}=$m(),r=g.useMemo(()=>jn(t.routes,n,t.basename),[t.routes,n,t.basename]);return r?g.createElement(Z1,{page:n,matches:r,...e}):null}function X1(n){let{manifest:e,routeModules:t}=Bm(),[r,i]=g.useState([]);return g.useEffect(()=>{let s=!1;return W1(n,e,t).then(o=>{s||i(o)}),()=>{s=!0}},[n,e,t]),r}function Z1({page:n,matches:e,...t}){let r=_t(),{manifest:i,routeModules:s}=Bm(),{basename:o}=$m(),{loaderData:a,matches:l}=Y1(),c=g.useMemo(()=>eu(n,e,l,i,r,"data"),[n,e,l,i,r]),d=g.useMemo(()=>eu(n,e,l,i,r,"assets"),[n,e,l,i,r]),u=g.useMemo(()=>{if(n===r.pathname+r.search+r.hash)return[];let m=new Set,b=!1;if(e.forEach(w=>{let v=i.routes[w.route.id];!v||!v.hasLoader||(!c.some(k=>k.route.id===w.route.id)&&w.route.id in a&&s[w.route.id]?.shouldRevalidate||v.hasClientLoader?b=!0:m.add(w.route.id))}),m.size===0)return[];let x=z1(n,o,"data");return b&&m.size>0&&x.searchParams.set("_routes",e.filter(w=>m.has(w.route.id)).map(w=>w.route.id).join(",")),[x.pathname+x.search]},[o,a,r,i,c,e,n,s]),f=g.useMemo(()=>U1(d,i),[d,i]),p=X1(d);return g.createElement(g.Fragment,null,u.map(m=>g.createElement("link",{key:m,rel:"prefetch",as:"fetch",href:m,...t})),f.map(m=>g.createElement("link",{key:m,rel:"modulepreload",href:m,...t})),p.map(({key:m,link:b})=>g.createElement("link",{key:m,nonce:t.nonce,...b})))}function ev(...n){return e=>{n.forEach(t=>{typeof t=="function"?t(e):t!=null&&(t.current=e)})}}var tv=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{tv&&(window.__reactRouterVersion="7.11.0")}catch{}function nv(n,e){return Ny({basename:e?.basename,getContext:e?.getContext,future:e?.future,history:Wx({window:e?.window}),hydrationData:rv(),routes:n,mapRouteProperties:C1,hydrationRouteProperties:j1,dataStrategy:e?.dataStrategy,patchRoutesOnNavigation:e?.patchRoutesOnNavigation,window:e?.window,unstable_instrumentations:e?.unstable_instrumentations}).initialize()}function rv(){let n=window?.__staticRouterHydrationData;return n&&n.errors&&(n={...n,errors:iv(n.errors)}),n}function iv(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 Is(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,Vm=g.forwardRef(function({onClick:e,discover:t="render",prefetch:r="none",relative:i,reloadDocument:s,replace:o,state:a,target:l,to:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f,...p},m){let{basename:b,unstable_useTransitions:x}=g.useContext(kt),w=typeof c=="string"&&Fm.test(c),v=gm(c,b);c=v.to;let k=s1(c,{relative:i}),[j,S,O]=J1(r,p),y=lv(c,{replace:o,state:a,target:l,preventScrollReset:d,relative:i,viewTransition:u,unstable_defaultShouldRevalidate:f,unstable_useTransitions:x});function D(R){e&&e(R),R.defaultPrevented||y(R)}let A=g.createElement("a",{...p,...O,href:v.absoluteURL||k,onClick:v.isExternal||s?e:D,ref:ev(m,S),target:l,"data-discover":!w&&t==="render"?"true":void 0});return j&&!w?g.createElement(g.Fragment,null,A,g.createElement(Q1,{page:k})):A});Vm.displayName="Link";var sv=g.forwardRef(function({"aria-current":e="page",caseSensitive:t=!1,className:r="",end:i=!1,style:s,to:o,viewTransition:a,children:l,...c},d){let u=Fs(o,{relative:c.relative}),f=_t(),p=g.useContext(Bs),{navigator:m,basename:b}=g.useContext(kt),x=p!=null&&pv(u)&&a===!0,w=m.encodeLocation?m.encodeLocation(u).pathname:u.pathname,v=f.pathname,k=p&&p.navigation&&p.navigation.location?p.navigation.location.pathname:null;t||(v=v.toLowerCase(),k=k?k.toLowerCase():null,w=w.toLowerCase()),k&&b&&(k=Rt(k,b)||k);const j=w!=="/"&&w.endsWith("/")?w.length-1:w.length;let S=v===w||!i&&v.startsWith(w)&&v.charAt(j)==="/",O=k!=null&&(k===w||!i&&k.startsWith(w)&&k.charAt(w.length)==="/"),y={isActive:S,isPending:O,isTransitioning:x},D=S?e:void 0,A;typeof r=="function"?A=r(y):A=[r,S?"active":null,O?"pending":null,x?"transitioning":null].filter(Boolean).join(" ");let R=typeof s=="function"?s(y):s;return g.createElement(Vm,{...c,"aria-current":D,className:A,ref:d,style:R,to:o,viewTransition:a},typeof l=="function"?l(y):l)});sv.displayName="NavLink";var ov=g.forwardRef(({discover:n="render",fetcherKey:e,navigate:t,reloadDocument:r,replace:i,state:s,method:o=zo,action:a,onSubmit:l,relative:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f,...p},m)=>{let{unstable_useTransitions:b}=g.useContext(kt),x=uv(),w=fv(a,{relative:c}),v=o.toLowerCase()==="get"?"get":"post",k=typeof a=="string"&&Fm.test(a),j=S=>{if(l&&l(S),S.defaultPrevented)return;S.preventDefault();let O=S.nativeEvent.submitter,y=O?.getAttribute("formmethod")||o,D=()=>x(O||S.currentTarget,{fetcherKey:e,method:y,navigate:t,replace:i,state:s,relative:c,preventScrollReset:d,viewTransition:u,unstable_defaultShouldRevalidate:f});b&&t!==!1?g.startTransition(()=>D()):D()};return g.createElement("form",{ref:m,method:v,action:w,onSubmit:r?l:j,...p,"data-discover":!k&&n==="render"?"true":void 0})});ov.displayName="Form";function av(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function zm(n){let e=g.useContext(dr);return he(e,av(n)),e}function lv(n,{target:e,replace:t,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a,unstable_useTransitions:l}={}){let c=an(),d=_t(),u=Fs(n,{relative:s});return g.useCallback(f=>{if(I1(f,e)){f.preventDefault();let p=t!==void 0?t:on(d)===on(u),m=()=>c(n,{replace:p,state:r,preventScrollReset:i,relative:s,viewTransition:o,unstable_defaultShouldRevalidate:a});l?g.startTransition(()=>m()):m()}},[d,c,u,t,r,e,n,i,s,o,a,l])}function cv(n){Ee(typeof URLSearchParams<"u","You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.");let e=g.useRef(uc(n)),t=g.useRef(!1),r=_t(),i=g.useMemo(()=>$1(r.search,t.current?null:e.current),[r.search]),s=an(),o=g.useCallback((a,l)=>{const c=uc(typeof a=="function"?a(new URLSearchParams(i)):a);t.current=!0,s("?"+c,l)},[s,i]);return[i,o]}var hv=0,dv=()=>`__${String(++hv)}__`;function uv(){let{router:n}=zm("useSubmit"),{basename:e}=g.useContext(kt),t=x1(),r=n.fetch,i=n.navigate;return g.useCallback(async(s,o={})=>{let{action:a,method:l,encType:c,formData:d,body:u}=V1(s,e);if(o.navigate===!1){let f=o.fetcherKey||dv();await r(f,t,o.action||a,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:d,body:u,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:d,body:u,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 fv(n,{relative:e}={}){let{basename:t}=g.useContext(kt),r=g.useContext(It);he(r,"useFormAction must be used inside a RouteContext");let[i]=r.matches.slice(-1),s={...Fs(n||".",{relative:e})},o=_t();if(n==null){s.search=o.search;let a=new URLSearchParams(s.search),l=a.getAll("index");if(l.some(d=>d==="")){a.delete("index"),l.filter(u=>u).forEach(u=>a.append("index",u));let d=a.toString();s.search=d?`?${d}`:""}}return(!n||n===".")&&i.route.index&&(s.search=s.search?s.search.replace(/^\?/,"?index&"):"?index"),t!=="/"&&(s.pathname=s.pathname==="/"?t:rn([t,s.pathname])),on(s)}function pv(n,{relative:e}={}){let t=g.useContext(fh);he(t!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=zm("useViewTransitionState"),i=Fs(n,{relative:e});if(!t.isTransitioning)return!1;let s=Rt(t.currentLocation.pathname,r)||t.currentLocation.pathname,o=Rt(t.nextLocation.pathname,r)||t.nextLocation.pathname;return Zo(i.pathname,o)!=null||Zo(i.pathname,s)!=null}function mv(n){return g.createElement(P1,{flushSync:om.flushSync,...n})}const gv={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",useGlobalFallback:"Use global fallback",openAtPath:"Open at project path",openAppOnly:"Open app only",actionOptionsLoadFailed:"Could not load editor/terminal options",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",readOnly:"Read-only",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",componentFilterUpdatesCount:"Updates ({count})",componentFilterUpToDate:"Up to date",componentFilterUpToDateCount:"Up to date ({count})",componentFilterCli:"CLI",componentFilterKits:"Kits",noComponentsMatchFilter:"No components match the current filter.",runCheckAllForFilter:"Run Check All to populate this filter.",noUpdatesFound:"No updates found. Checked components are up to date.",noUpToDateYet:"No components are up to date yet.",configWorkspaceHint:"Edit configuration or manage system updates from one workspace.",settingsJsonHeading:"Claude Settings JSON",settingsJsonMissing:"No settings file found at ~/.claude/settings.json.",settingsJsonLoadFailed:"Failed to load ~/.claude/settings.json.",settingsBackupSaved:"Backup saved",hookDiagnosticsTitle:"Hook Diagnostics",hookDiagnosticsDesc:"Inspect recent hook activity and failures without opening JSONL files manually.",hookDiagnosticsPathPending:"Resolving log path...",hookDiagnosticsScopeGlobal:"Global hooks",hookDiagnosticsEntries:"Entries",hookDiagnosticsCrashes:"Crashes",hookDiagnosticsWarnings:"Warnings",hookDiagnosticsBlocks:"Blocks",hookDiagnosticsLastEvent:"Last event",hookDiagnosticsLoading:"Loading hook diagnostics...",hookDiagnosticsLoadFailed:"Failed to load hook diagnostics",hookDiagnosticsMissing:"No hook log file found for this scope yet.",hookDiagnosticsEmpty:"Hook log is present but contains no readable entries.",hookDiagnosticsParseErrorsNotice:"Skipped {count} malformed log line(s) while loading diagnostics.",hookDiagnosticsTruncatedNotice:"Showing a bounded recent window to keep diagnostics responsive on large logs.",hookDiagnosticsToolLabel:"tool",hookDiagnosticsTargetLabel:"target",hookDiagnosticsUnknown:"Unknown",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",fieldStatuslineColors:"Statusline Colors",fieldStatuslineColorsDesc:"Enable ANSI color output in the statusline",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",migratePresetCore:"Codex + Antigravity + Droid",migratePresetDetected:"All Detected",migrateScope:"Scope",migrateScopeProject:"Project",migrateScopeGlobal:"Global",migrateTypes:"Portable Types",migrateTypeAgents:"Subagents",migrateTypeCommands:"Commands",migrateTypeSkills:"Skills",migrateTypeConfig:"Config",migrateTypeRules:"Rules",migrateTypeHooks:"Hooks",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",migrateActionInstall:"Install",migrateActionUpdate:"Update",migrateActionSkip:"Skip",migrateActionConflict:"Conflict",migrateActionDelete:"Delete",migrateUnchanged:"unchanged",migrateConflictSectionTitle:"Conflicts",migrateConflictUseCK:"Use CK",migrateConflictKeepMine:"Keep Mine",migrateConflictSmartMerge:"Smart Merge",migrateConflictShowDiff:"Show Diff",migrateConflictHideDiff:"Hide Diff",migrateConflictResolved:"Resolved",migrateConflictManual:"Manual",migrateConflictOverwriteAll:"Overwrite All",migrateConflictKeepAll:"Keep All",migrateSummaryTitle:"Migration Complete",migrateSummaryNewMigration:"New Migration",migrateType:"Type",migrateItem:"Item",migrateReconciling:"Analyzing changes...",migrateReviewPlan:"Review Plan",migrateExecutePlan:"Execute Migration",migrateExecuting:"Executing migration...",migrateResolveConflicts:"Resolve all conflicts before executing",migrateSummarySubtitle:"items migrated",migrateSummarySearchPlaceholder:"Search items...",migrateSummaryFilterAll:"All",migrateSummaryCollapseAll:"Collapse all",migrateSummaryExpandAll:"Expand all",migrateSummaryNoResults:"No items match your search",migrateSummaryProviders:"Providers",migrateTypeUnknown:"Other",kanbanTitle:"Plan Kanban",kanbanNoFile:"No plan file specified. Use ?file= parameter.",kanbanNoPhases:"No phases detected in this plan",kanbanError400:"Invalid request — missing file parameter",kanbanError403:"Access denied — file is outside the project directory",kanbanError404:"Plan file not found",kanbanComplete:"complete",kanbanStatus_pending:"Pending","kanbanStatus_in-progress":"In Progress",kanbanStatus_completed:"Completed",kanbanPhases:"phases",kanbanProgress:"Progress",kanbanLoadError:"Failed to load plan data",developmentFeature:"Development",betaFeature:"Beta",experimentalFeature:"Experimental",sectionModelTaxonomy:"Model Taxonomy",taxonomyDescription:"Customize model mappings for portable migration to other coding agents.",taxonomyTierHeavy:"Heavy (opus)",taxonomyTierBalanced:"Balanced (sonnet)",taxonomyTierLight:"Light (haiku)",taxonomyModel:"Model",taxonomyEffort:"Effort",taxonomyResetProvider:"Reset",taxonomyTier:"Tier"},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",useGlobalFallback:"Dùng fallback global",openAtPath:"Mở tại đường dẫn dự án",openAppOnly:"Chỉ mở ứng dụng",actionOptionsLoadFailed:"Không thể tải tùy chọn editor/terminal",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",readOnly:"Chỉ đọc",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",componentFilterUpdatesCount:"Bản cập nhật ({count})",componentFilterUpToDate:"Đã cập nhật",componentFilterUpToDateCount:"Đã cập nhật ({count})",componentFilterCli:"CLI",componentFilterKits:"Kit",noComponentsMatchFilter:"Không có thành phần phù hợp bộ lọc hiện tại.",runCheckAllForFilter:"Hãy chạy Kiểm tra tất cả để nạp dữ liệu cho bộ lọc này.",noUpdatesFound:"Không có bản cập nhật. Các thành phần đã kiểm tra đều mới nhất.",noUpToDateYet:"Chưa có thành phần nào ở trạng thái đã cập nhật.",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.",settingsJsonHeading:"JSON Cài đặt Claude",settingsJsonMissing:"Không tìm thấy tệp ~/.claude/settings.json.",settingsJsonLoadFailed:"Không thể tải ~/.claude/settings.json.",settingsBackupSaved:"Đã lưu bản sao lưu",hookDiagnosticsTitle:"Chẩn đoán Hook",hookDiagnosticsDesc:"Xem hoạt động hook gần đây và lỗi mà không cần mở tệp JSONL thủ công.",hookDiagnosticsPathPending:"Đang xác định đường dẫn log...",hookDiagnosticsScopeGlobal:"Hook toàn cục",hookDiagnosticsEntries:"Bản ghi",hookDiagnosticsCrashes:"Sự cố",hookDiagnosticsWarnings:"Cảnh báo",hookDiagnosticsBlocks:"Chặn",hookDiagnosticsLastEvent:"Sự kiện cuối",hookDiagnosticsLoading:"Đang tải chẩn đoán hook...",hookDiagnosticsLoadFailed:"Không thể tải chẩn đoán hook",hookDiagnosticsMissing:"Chưa tìm thấy tệp log hook cho phạm vi này.",hookDiagnosticsEmpty:"Tệp log hook có tồn tại nhưng không có bản ghi đọc được.",hookDiagnosticsParseErrorsNotice:"Đã bỏ qua {count} dòng log bị lỗi khi tải chẩn đoán.",hookDiagnosticsTruncatedNotice:"Đang hiển thị cửa sổ bản ghi gần đây để giữ giao diện phản hồi tốt với log lớn.",hookDiagnosticsToolLabel:"công cụ",hookDiagnosticsTargetLabel:"mục tiêu",hookDiagnosticsUnknown:"Không rõ",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",fieldStatuslineColors:"Màu thanh trạng thái",fieldStatuslineColorsDesc:"Bật màu ANSI trong 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",migratePresetCore:"Codex + Antigravity + Droid",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",migrateTypeHooks:"Hooks",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",migrateActionInstall:"Cài",migrateActionUpdate:"Cập nhật",migrateActionSkip:"Bỏ qua",migrateActionConflict:"Xung đột",migrateActionDelete:"Xóa",migrateUnchanged:"chưa thay đổi",migrateConflictSectionTitle:"Xung đột",migrateConflictUseCK:"Dùng CK",migrateConflictKeepMine:"Giữ của tôi",migrateConflictSmartMerge:"Merge thông minh",migrateConflictShowDiff:"Hiện diff",migrateConflictHideDiff:"Ẩn diff",migrateConflictResolved:"Đã giải quyết",migrateConflictManual:"Thủ công",migrateConflictOverwriteAll:"Ghi đè tất cả",migrateConflictKeepAll:"Giữ tất cả",migrateSummaryTitle:"Di trú hoàn tất",migrateSummaryNewMigration:"Di trú mới",migrateType:"Loại",migrateItem:"Mục",migrateReconciling:"Đang phân tích thay đổi...",migrateReviewPlan:"Xem kế hoạch",migrateExecutePlan:"Thực hiện di trú",migrateExecuting:"Đang thực hiện di trú...",migrateResolveConflicts:"Giải quyết xung đột trước khi thực hiện",migrateSummarySubtitle:"mục đã di trú",migrateSummarySearchPlaceholder:"Tìm kiếm...",migrateSummaryFilterAll:"Tất cả",migrateSummaryCollapseAll:"Thu gọn",migrateSummaryExpandAll:"Mở rộng",migrateSummaryNoResults:"Không tìm thấy mục nào",migrateSummaryProviders:"Provider",migrateTypeUnknown:"Khác",kanbanTitle:"Bảng Kanban Kế hoạch",kanbanNoFile:"Chưa chọn file kế hoạch. Dùng tham số ?file=.",kanbanNoPhases:"Không phát hiện giai đoạn nào trong kế hoạch này",kanbanError400:"Yêu cầu không hợp lệ — thiếu tham số file",kanbanError403:"Truy cập bị từ chối — file nằm ngoài thư mục dự án",kanbanError404:"Không tìm thấy file kế hoạch",kanbanComplete:"hoàn thành",kanbanStatus_pending:"Chờ xử lý","kanbanStatus_in-progress":"Đang thực hiện",kanbanStatus_completed:"Hoàn thành",kanbanPhases:"giai đoạn",kanbanProgress:"Tiến độ",kanbanLoadError:"Không thể tải dữ liệu kế hoạch",developmentFeature:"Đang phát triển",betaFeature:"Beta",experimentalFeature:"Thử nghiệm",sectionModelTaxonomy:"Phân loại mô hình",taxonomyDescription:"Tuỳ chỉnh ánh xạ mô hình cho migration portable sang coding agent khác.",taxonomyTierHeavy:"Nặng (opus)",taxonomyTierBalanced:"Cân bằng (sonnet)",taxonomyTierLight:"Nhẹ (haiku)",taxonomyModel:"Mô hình",taxonomyEffort:"Mức nỗ lực",taxonomyResetProvider:"Đặt lại",taxonomyTier:"Cấp độ"}},yh=g.createContext(null),_m="ck-dashboard-lang";function bv(){const n=localStorage.getItem(_m);return n==="en"||n==="vi"?n:navigator.language.startsWith("vi")?"vi":"en"}function xv({children:n}){const[e,t]=g.useState(bv),r=g.useCallback(o=>{localStorage.setItem(_m,o),t(o)},[]),i=g.useCallback(o=>gv[e][o],[e]),s=g.useMemo(()=>({lang:e,setLang:r,t:i}),[e,r,i]);return h.jsx(yh.Provider,{value:s,children:n})}function ce(){const n=g.useContext(yh);if(!n)throw new Error("useI18n must be used within I18nProvider");return n}class yv extends g.Component{constructor(){super(...arguments);jd(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 h.jsx(yh.Consumer,{children:r=>h.jsx("div",{className:"flex h-screen items-center justify-center bg-dash-bg",children:h.jsx("div",{className:"text-center space-y-4 max-w-md px-6",children:t?h.jsxs(h.Fragment,{children:[h.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:"🔌"}),h.jsx("h1",{className:"text-2xl font-bold text-orange-500",children:r?.t("serverNotRunning")??"Server Not Running"}),h.jsx("p",{className:"text-dash-text-secondary",children:r?.t("startServerMessage")??"The Config UI requires the backend server to be running."}),h.jsxs("div",{className:"bg-dash-surface border border-dash-border rounded-lg p-4",children:[h.jsx("p",{className:"text-xs text-dash-text-muted uppercase tracking-widest mb-2 font-bold",children:r?.t("runThisCommand")??"Run this command"}),h.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"})]}),h.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"})]}):h.jsxs(h.Fragment,{children:[h.jsx("h1",{className:"text-2xl font-bold text-red-500",children:r?.t("somethingWentWrong")??"Something went wrong"}),h.jsx("p",{className:"text-dash-text-muted",children:this.state.error?.message}),h.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 tr=({direction:n="horizontal",isDragging:e=!1,onMouseDown:t})=>{const r=n==="horizontal";return h.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"}
|
package/dist/ui/index.html
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
background: var(--dash-text-muted);
|
|
72
72
|
}
|
|
73
73
|
</style>
|
|
74
|
-
<script type="module" crossorigin src="/assets/index-
|
|
74
|
+
<script type="module" crossorigin src="/assets/index-80yNiC3Q.js"></script>
|
|
75
75
|
<link rel="modulepreload" crossorigin href="/assets/vendor-DNUgy55u.js">
|
|
76
76
|
<link rel="stylesheet" crossorigin href="/assets/index-C0iI_9s2.css">
|
|
77
77
|
</head>
|