@lobehub/i18n-cli
Version:
Lobe i18n is a CLI tool that automate translate your i18n localization with AI
22 lines (18 loc) • 41.3 kB
JavaScript
;var De=Object.defineProperty;var c=(t,e)=>De(t,"name",{value:e,configurable:!0});var S=require("react/jsx-runtime"),h=require("@lobehub/cli-ui"),_=require("commander"),Be=require("update-notifier"),Ge=require("conf"),Ue=require("cosmiconfig"),L=require("react"),g=require("chalk"),ze=require("dotenv"),A=require("lodash-es"),p=require("consola"),b=require("node:path"),ie=require("@yutengjing/eld"),P=require("ink"),ae=require("p-map"),ce=require("gpt-tokenizer"),le=require("remark-frontmatter"),ue=require("remark-gfm"),Je=require("remark-parse"),qe=require("remark-stringify"),fe=require("unified"),ge=require("unist-util-visit"),Ke=require("just-diff"),He=require("json-stable-stringify"),M=require("node:fs"),Ve=require("dirty-json"),We=require("openai"),de=require("glob"),Qe=require("node:process"),pe=require("gray-matter");function Xe(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(n){if(n!=="default"){var r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:c(function(){return t[n]},"get")})}}),e.default=t,Object.freeze(e)}c(Xe,"_interopNamespaceDefault");var Ye=Xe(Qe),Ze="@lobehub/i18n-cli",et="1.25.0",tt="Lobe i18n is a CLI tool that automate translate your i18n localization with AI",nt=["ai","i18n","openai","gpt"],rt="https://github.comlobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n",ot={url:"https://github.com/lobehub/lobe-cli-toolbox/issues/new"},st={type:"git",url:"https://github.com/lobehub/lobe-cli-toolbox.git"},it="MIT",at="LobeHub <i@lobehub.com>",ct=!1,lt="module",ut={"@":"./src"},ft={require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"}},gt="./dist/index.cjs",dt="./dist/index.mjs",pt="./dist/index.d.cts",ht={"lobe-i18n":"dist/cli.js"},mt=["dist"],yt={build:"npm run type-check && pkgroll --minify -p tsconfig.prod.json --env.NODE_ENV=production && npm run shebang",dev:"pkgroll -p tsconfig.prod.json --env.NODE_ENV=development --watch",link:"npm run build && npm link -f",prepack:"clean-package",postpack:"clean-package restore",shebang:"lobe-shebang -t ./dist/cli.js",start:"node ./dist/cli.js",test:"vitest --passWithNoTests","test:coverage":"vitest run --coverage --passWithNoTests","type-check":"tsc --noEmit"},kt={"@lobehub/cli-ui":"1.13.0","@yutengjing/eld":"^0.0.2",chalk:"^5.4.1",commander:"^13.0.0",conf:"^13.1.0",consola:"^3.3.3",cosmiconfig:"^9.0.0","dirty-json":"^0.9.2",dotenv:"^16.4.7","fast-deep-equal":"^3.1.3",glob:"^10.4.5","gpt-tokenizer":"^2.8.1","gray-matter":"^4.0.3",ink:"^6.0.0","json-stable-stringify":"^1.2.1","just-diff":"^6.0.2","lodash-es":"^4.17.21",openai:"^4.103.0","p-map":"^7.0.3",pangu:"^4.0.7",react:"^19.0.0","remark-frontmatter":"^5.0.0","remark-gfm":"^4.0.0","remark-parse":"^11.0.0","remark-stringify":"^11.0.0",swr:"^2.3.0",unified:"^11.0.5","unist-util-visit":"^5.0.0","update-notifier":"^7.3.1",zustand:"^5.0.3"},St={"@types/json-stable-stringify":"^1.1.0","@types/lodash-es":"^4.17.12","@types/node":"^22.10.5","@types/unist":"^3.0.3","clean-package":"^2.2.0"},wt="pnpm@10.10.0",bt={node:">=18"},vt={access:"public",registry:"https://registry.npmjs.org/"},K={name:Ze,version:et,description:tt,keywords:nt,homepage:rt,bugs:ot,repository:st,license:it,author:at,sideEffects:ct,type:lt,imports:ut,exports:ft,main:gt,module:dt,types:pt,bin:ht,files:mt,scripts:yt,dependencies:kt,devDependencies:St,packageManager:wt,engines:bt,publishConfig:vt},R=(t=>(t.MDAST="mdast",t.STRING="string",t))(R||{});const H=c(t=>`.${t}.md`,"getDefaultExtension"),At={o3:2e5,"o4-mini":2e5,"gpt-4.1":1047576,"gpt-4.1-mini":1047576,"gpt-4.1-nano":1047576,"o3-mini":2e5,"o1-mini":128e3,o1:2e5,"o1-preview":128e3,"gpt-4.5-preview":128e3,"gpt-4o-mini":128e3,"gpt-4o-2024-11-20":128e3,"gpt-4o":128e3,"gpt-4o-2024-05-13":128e3,"chatgpt-4o-latest":128e3,"gpt-4-turbo":128e3,"gpt-4-turbo-2024-04-09":128e3,"gpt-4-turbo-preview":128e3,"gpt-4-0125-preview":128e3,"gpt-4-1106-preview":128e3,"gpt-4":8192,"gpt-4-0613":8192,"gpt-4-32k":32768,"gpt-3.5-turbo":16384,"gpt-3.5-turbo-0125":16384,"gpt-3.5-turbo-1106":16384},he="o4-mini",Tt={concurrency:5,markdown:{entry:[],mode:R.STRING,outputExtensions:H},modelName:he,temperature:0},I=c((t,e)=>{t[e]||h.alert.error(`Can't find ${g.bold.yellow("outputLocales")} in config`)},"checkOptionKeys"),me={apiBaseUrl:{default:"",type:"string"},openaiToken:{default:"",type:"string"}},V=new Ge({projectName:"lobe-i18n",schema:me});class Mt{static{c(this,"ExplorerConfig")}explorer;customConfig;constructor(){this.explorer=Ue.cosmiconfigSync("i18n")}loadCustomConfig(e){this.customConfig=e}getConfigFile(){return this.customConfig?this.explorer.load(this.customConfig)?.config:this.explorer.search()?.config}}const j=new Mt;ze.config();const W=c(t=>V.get(t),"getConfig"),Ct=c(t=>me[t].default,"getDefulatConfig"),Nt=c((t,e)=>V.set(t,e),"setConfig"),Lt=c(()=>process.env.OPENAI_API_KEY||W("openaiToken"),"getOpenAIApiKey"),xt=c(()=>process.env.OPENAI_PROXY_URL||W("apiBaseUrl"),"getOpenAIProxyUrl"),Q=c(()=>{const t=j.getConfigFile();return t?A.merge(Tt,t):h.alert.error(`Can't find ${g.bold.yellow("config")}`,!0)},"getConfigFile"),Et=c(()=>{const t=Q();return I(t,"entry"),I(t,"entryLocale"),I(t,"output"),I(t,"outputLocales"),t},"getLocaleConfig"),It=c(()=>{const t=Q();if(!t.markdown)return h.alert.error(`Can't find ${g.bold.yellow("config.markdown")}`,!0);const e=A.merge(t?.markdown||{},{entryLocale:t?.markdown?.entryLocale||t.entryLocale,outputLocales:t?.markdown?.outputLocales||t.outputLocales});return I(e,"entry"),I(e,"entryLocale"),I(e,"outputLocales"),e},"getMarkdownConfigFile");var C={getConfig:W,getConfigFile:Q,getDefulatConfig:Ct,getLocaleConfig:Et,getMarkdownConfigFile:It,getOpenAIApiKey:Lt,getOpenAIProxyUrl:xt,setConfig:Nt};const _t=c(()=>{const t=V.store;return{get:C.getConfig,getDefault:C.getDefulatConfig,set:C.setConfig,store:t}},"useConfStore"),Pt=L.memo(()=>{const[t,e]=L.useState(),{store:n,set:r,getDefault:o}=_t(),i=c((a,l)=>{r(a,l),e("")},"setConfig"),s=L.useMemo(()=>[{children:S.jsx(h.TextInput,{defaultValue:n.openaiToken,onSubmit:c(a=>i("openaiToken",a),"onSubmit"),placeholder:"Input OpenAI token..."}),defaultValue:o("openaiToken"),key:"openaiToken",label:"OpenAI token",showValue:!1,value:n.openaiToken},{children:S.jsx(h.TextInput,{defaultValue:n.apiBaseUrl,onSubmit:c(a=>i("apiBaseUrl",a),"onSubmit"),placeholder:"Set openAI API proxy, default value: https://api.openai.com/v1/..."}),defaultValue:o("apiBaseUrl"),desc:"OpenAI API proxy, default value: https://api.openai.com/v1/",key:"apiBaseUrl",label:"OpenAI API proxy",showValue:!1,value:n.apiBaseUrl}],[n]);return S.jsx(h.ConfigPanel,{active:t,items:s,logo:"\u{1F92F}",setActive:e,title:"Lobe I18N Config"})}),Ft={af:"af_ZA",am:"am_ET",ar:"ar_SA",as:"as_IN",az:"az_AZ",bg:"bg_BG",bn:"bn_BD",bo:"bo_CN",br:"br_FR",ca:"ca_ES",cs:"cs_CZ",cy:"cy_GB",da:"da_DK",de:"de_DE",el:"el_GR",en:"en_US",es:"es_ES",et:"et_EE",eu:"eu_ES",fa:"fa_IR",fi:"fi_FI",fr:"fr_FR",ga:"ga_IE",gd:"gd_GB",gl:"gl_ES",gu:"gu_IN",he:"he_IL",hi:"hi_IN",hr:"hr_HR",hu:"hu_HU",hy:"hy_AM",is:"is_IS",it:"it_IT",ja:"ja_JP",ka:"ka_GE",kk:"kk_KZ",km:"km_KH",kn:"kn_IN",ko:"ko_KR",kw:"kw_GB",ky:"ky_KG",lo:"lo_LA",lt:"lt_LT",lv:"lv_LV",ml:"ml_IN",mn:"mn_MN",mt:"mt_MT",my:"my_MM",nb:"nb_NO",ne:"ne_NP",nl:"nl_NL",or:"or_IN",pa:"pa_IN",pl:"pl_PL",pt:"pt_BR",ro:"ro_RO",ru:"ru_RU",si:"si_LK",sk:"sk_SK",sl:"sl_SI",sv:"sv_SE",ta:"ta_IN",te:"te_IN",tg:"tg_TJ",th:"th_TH",tr:"tr_TR",ug:"ug_CN",uk:"uk_UA",ur:"ur_PK",uz:"uz_UZ",vi:"vi_VN",zh:"zh_CN"},X=Object.fromEntries(Object.entries(Ft).map(([t,e])=>[e,t]));X.zh_TW="zh",X.zh_CN="zh";const Ot={"ar-EG":"ar","ar-MA":"ar","ar-SA":"ar","as-IN":"as","az-AZ":"az","bg-BG":"bg","bn-BD":"bn","bo-CN":"bo","br-FR":"br","ca-ES":"ca","cs-CZ":"cs","cy-GB":"cy","da-DK":"da","de-AT":"de","de-CH":"de","de-DE":"de","el-GR":"el","en-GB":"en","en-US":"en","es-AR":"es","es-ES":"es","es-MX":"es","et-EE":"et","eu-ES":"eu","fa-IR":"fa","fi-FI":"fi","fr-BE":"fr","fr-CA":"fr","fr-FR":"fr","ga-IE":"ga","gd-GB":"gd","gl-ES":"gl","gu-IN":"gu","he-IL":"he","hi-IN":"hi","hr-HR":"hr","hu-HU":"hu","hy-AM":"hy","is-IS":"is","it-CH":"it","it-IT":"it","ja-JP":"ja","ka-GE":"ka","kk-KZ":"kk","km-KH":"km","kn-IN":"kn","ko-KR":"ko","kw-GB":"kw","ky-KG":"ky","lo-LA":"lo","lt-LT":"lt","lv-LV":"lv","ml-IN":"ml","mn-MN":"mn","mt-MT":"mt","my-MM":"my","nb-NO":"nb","ne-NP":"ne","nl-BE":"nl","nl-NL":"nl","or-IN":"or","pa-IN":"pa","pl-PL":"pl","pt-BR":"pt","pt-PT":"pt","ro-RO":"ro","ru-RU":"ru","si-LK":"si","sk-SK":"sk","sl-SI":"sl","sv-SE":"sv","ta-IN":"ta","te-IN":"te","tg-TJ":"tg","th-TH":"th","tr-TR":"tr","ug-CN":"ug","uk-UA":"uk","ur-PK":"ur","uz-UZ":"uz","vi-VN":"vi","zh-CN":"zh","zh-HK":"zh","zh-SG":"zh","zh-TW":"zh"},ye=new Set(["ar","fa","ur","ku"]),$={EAST_ASIAN:new Set(["zh","ja","ko","vi","th","my","km","lo","mn","bo","ug"]),GERMANIC:new Set(["de","nl","da","no","sv","is","fo","af"]),MALAY:new Set(["id","ms"]),ROMANCE:new Set(["es","pt","ca","it","fr","ro","gl"]),SEMITIC:new Set(["ar","he","fa","ur","tg","am","ti","om","so","aa","mt"]),SLAVIC:new Set(["bg","sr","ru","uk","be","hr","sl","mk","bs","me","pl","cs","sk"]),SOUTH_ASIAN:new Set(["hi","bn","ne","gu","pa","ta","ml","te","kn","si","as","or"]),TURKIC:new Set(["tr","az","ky","kk","uz"])},Rt=["API","GitHub","Cloud","Community","Enterprise","Ultimate","Starter","ChatGPT","OLLaMA","LobeHub","LobeChat","OpenAI","Microsoft","Google","Facebook","Twitter","Instagram","LinkedIn","YouTube","Discord","Slack","React","Vue","Angular","Node.js","TypeScript","JavaScript","Python","Java","C++","C#","PHP","Ruby","Go","Rust","Swift","Kotlin","Docker","Kubernetes","AWS","Azure","GCP","Firebase","MongoDB","PostgreSQL","MySQL","Redis","Elasticsearch","Kafka","RabbitMQ","GraphQL","REST","OAuth","JWT","SSL","TLS","HTTPS","HTTP","JSON","XML","YAML","CSV","PDF","PNG","JPG","MP4","MP3","AI","ML","NLP","CV","RL","DL","CNN","RNN","LSTM","BERT","GPT","Transformer","Neural","Network","Algorithm","Model","Database","Server","Client","Frontend","Backend","Fullstack","DevOps","CI/CD","Agile","Scrum","Kanban","Waterfall","Microservices","Monolith","Serverless","Container","Virtual","Machine","Learning","Deep","Natural","Language","Processing","Computer","Vision","Reinforcement","Supervised","Unsupervised","Classification","Regression","Clustering","Recommendation","System","Framework","Library","Package","Module","Component","Interface","Abstract","Inheritance","Polymorphism","Encapsulation","Abstraction","Design","Pattern","Architecture","Structure","Algorithm","Complexity","Optimization","Performance","Scalability","Reliability","Availability","Consistency","Durability","Atomicity","Isolation","Transaction","Concurrency","Parallelism","Asynchronous","Synchronous","Callback","Promise","Async","Await","Generator","Iterator","Stream","Buffer","Cache","Memory","Storage","Disk","Network","Protocol","Socket","Port","IP","DNS","CDN","VPN","Proxy","Load","Balancer","Gateway","Router","Switch","Hub","Firewall","Security","Authentication","Authorization","Encryption","Decryption","Hash","Salt","Token","Session","Cookie","Header","Body","Request","Response","Status","Code","Error","Exception","Log","Debug","Trace","Monitor","Alert","Metric","Dashboard","Analytics","Reporting","Business","Intelligence","Data","Warehouse","Lake","Pipeline","ETL","ELT","Batch","Real-time","Streaming","Event","Message","Queue","Topic","Publisher","Subscriber","Producer","Consumer","Broker","Middleware","Orchestration","Choreography","Saga","CQRS","Event","Sourcing","Domain","Driven","Design","Test","Driven","Development","Behavior","Driven","Acceptance","Unit","Integration","End-to-end","Performance","Load","Stress","Security","Penetration","Vulnerability","Threat","Risk","Compliance","Governance","Audit","Backup","Recovery","Disaster","High","Availability","Fault","Tolerance","Redundancy","Replication","Sharding","Partitioning","Indexing","Query","Optimization","Execution","Plan","Statistics","Histogram","Cardinality","Selectivity","Join","Union","Intersection","Difference","Aggregation","Group","Order","Limit","Offset","Filter","Where","Having","Select","Insert","Update","Delete","Create","Drop","Alter","Grant","Revoke","Commit","Rollback","Savepoint","Checkpoint","Snapshot","Version","Control","Git","SVN","Mercurial","Branch","Merge","Rebase","Cherry-pick","Stash","Tag","Release","Deploy","Build","Compile","Link","Package","Bundle","Minify","Uglify","Transpile","Babel","Webpack","Rollup","Vite","Parcel","Gulp","Grunt","NPM","Yarn","PNPM","Bower","Composer","Pip","Conda","Maven","Gradle","Ant","Make","CMake","Ninja","Bazel","Buck","Pants","Scons","Waf","Autotools","Meson","Conan","Vcpkg","Hunter","FetchContent","ExternalProject","FindPackage","Target","Source","Include","Library","Executable","Static","Shared","Dynamic","Plugin","Extension","Addon","Widget","Gadget","Applet","Snippet","Template","Skeleton","Boilerplate","Scaffold","Generator","CLI","GUI","TUI","Web","Mobile","Desktop","Server","Embedded","IoT","Edge","Fog","Cloud","Hybrid","Native","Cross-platform","Universal","Progressive","Single-page","Multi-page","Isomorphic","Universal","SSR","CSR","SPA","MPA","PWA","AMP","JAMstack","MERN","MEAN","LAMP","LEMP","WAMP","XAMPP","MAMP","LAPP","LEAP","MEAP","SEAP","TEAP","UEAP","VEAP","WEAP","XEAP","YEAP","ZEAP"],F={ARABIC_SIMILAR:.9,ARRAY_TEXT:.65,LONG_TEXT:.7,SHORT_TEXT:.7,SIMILAR_LANGUAGES:.8};function O(t,e,n){try{const i=require("node:fs").readFileSync(t,"utf8").split(`
`),s=new RegExp(`"${e.split(".").pop()}"\\s*:\\s*"${n.replaceAll(/[$()*+.?[\\\]^{|}]/g,"\\$&")}"`);for(const[a,l]of i.entries())if(s.test(l))return a+1;return}catch{return}}c(O,"findLineNumber");async function ke(t,e,n){try{const o=require("node:fs").readFileSync(t,"utf8"),i=JSON.parse(o),{extractMainLanguageFromLocale:s}=await Promise.resolve().then(function(){return Gt}),a=s(e);return await n(i,"",a,t)}catch(r){return[{errorMessage:`Failed to process file: ${r instanceof Error?r.message:"Unknown error"}`,key:"file_error",severity:"error",type:"eld_error"}]}}c(ke,"processLintFile");function jt(t){return t.replace(process.cwd()+"/","")}c(jt,"getRelativePath");function $t(t){return b.resolve(t)}c($t,"getAbsolutePath");function Dt(t,e){const n=t.severity==="error"?g.red("error"):g.yellow("warning"),r=t.severity==="error"?n+" ":n+" ",o=t.lineNumber?.toString().padStart(4," ")||"";let i="";switch(t.type){case"field_language_mismatch":{const a=`${g.green(t.expectedLanguage)} \u2192 ${g.red(t.detectedLanguage)}`,l=t.confidence?g.gray(`(confidence ${(t.confidence*100).toFixed(0)}%)`):"",f=`\x1B]8;;${t.lineNumber?`file://${e}:${t.lineNumber}`:`file://${e}`}\x07${t.fieldPath}\x1B]8;;\x07`;i=`${a} at ${g.cyan(f)}: ${g.white(`"${t.text}"`)} ${l}`.trim();break}case"empty_string":{const l=`\x1B]8;;${t.lineNumber?`file://${e}:${t.lineNumber}`:`file://${e}`}\x07${t.fieldPath}\x1B]8;;\x07`;i=`Empty string at ${g.cyan(l)}`;break}case"eld_error":{const l=`\x1B]8;;${t.lineNumber?`file://${e}:${t.lineNumber}`:`file://${e}`}\x07${t.fieldPath}\x1B]8;;\x07`;i=`Detection failed at ${g.cyan(l)}: ${g.red(t.errorMessage)}`;break}}const s=`${g.gray(`${o}:1`)} ${r} ${i}`;console.log(s)}c(Dt,"displayIssue");function Se(t,e){if(t.length===0){p.consola.success("\u2705 All translation files passed linting!");return}let n=0,r=0;for(const s of t)for(const a of s.issues)a.severity==="error"?n++:e||r++;if(e&&n===0){p.consola.success("\u2705 No errors found in translation files!");return}const o=n+r,i=[];n>0&&i.push(g.red(`${n} error${n!==1?"s":""}`)),r>0&&i.push(g.yellow(`${r} warning${r!==1?"s":""}`)),console.log(`${g.bold("\u2716")} ${o} problem${o!==1?"s":""} (${i.join(", ")})`);for(const s of t){const a=jt(s.file),l=$t(s.file),u=e?s.issues.filter(f=>f.severity==="error"):s.issues;if(u.length!==0){console.log(`
${g.white.underline(a)}`);for(const f of u)Dt(f,l)}}n>0&&p.consola.error(`${g.bold.red("\u2716")} Found ${n} error${n!==1?"s":""}`),r>0&&p.consola.warn(`${g.bold.yellow("\u26A0")} Found ${r} warning${r!==1?"s":""}`)}c(Se,"displayResults");let Y=null;async function we(){return Y||(Y=(async()=>{console.log("\u{1F527} Initializing ELD language detector..."),await ie.eld.init("L"),console.log("\u2705 ELD language detector initialized")})()),Y}c(we,"initializeELD");async function Z(t){if(!t?.trim())return{confidence:0,detected:"",isReliable:!1,scores:{}};await we();const e=ie.eld.detect(t),n=e.getScores(),r=Math.max(...Object.values(n));return{confidence:Math.min(r,1),detected:e.language,isReliable:e.isReliable(),scores:n}}c(Z,"detectLanguage");function Bt(t){return t.includes("_")?t.split("_")[0]||t:t.includes("-")&&t.split("-")[0]||t}c(Bt,"extractMainLanguageFromLocale");var Gt=Object.freeze({__proto__:null,detectLanguage:Z,extractMainLanguageFromLocale:Bt,initializeELD:we});function be(t,e,n){if(ye.has(t)&&ye.has(e)&&n<F.ARABIC_SIMILAR)return!0;for(const r of Object.values($))if(r.has(t)&&r.has(e)&&n<F.SIMILAR_LANGUAGES)return!0;return!!(t==="tl"&&["es","pt"].includes(e)&&n<F.SIMILAR_LANGUAGES)}c(be,"isSimilarLanguage");function Ut(t){return Rt.some(e=>t.includes(e))}c(Ut,"containsEnglishTerms");function zt(t,e,n,r,o){let i="warning";t>3&&e>F.LONG_TEXT&&(i="error"),t<=3&&e>F.SHORT_TEXT&&(i="error");const s=$.EAST_ASIAN.has(n),a=$.EAST_ASIAN.has(r);s!==a&&e>.5&&(i="error");const l=Object.values($).find(f=>f.has(r)),u=Object.values($).find(f=>f.has(n));return l&&u&&l!==u&&e>.6&&(i="error"),n==="en"&&r!=="en"&&Ut(o)&&e>.5&&(i="error"),i}c(zt,"determineSeverity");function ve(t,e,n,r,o,i){const s=zt(o.trim().length,r,e,n,o);return{confidence:r,detectedLanguage:e,expectedLanguage:n,fieldPath:t,key:"field_language_mismatch",lineNumber:i,severity:s,text:o,type:"field_language_mismatch"}}c(ve,"createLanguageMismatchIssue");function Ae(t,e){return{fieldPath:t,key:"empty_string",lineNumber:e,severity:"warning",type:"empty_string"}}c(Ae,"createEmptyStringIssue");function Te(t,e,n){return{errorMessage:e,fieldPath:t,key:"eld_error",lineNumber:n,severity:"warning",type:"eld_error"}}c(Te,"createELDErrorIssue");async function ee(t,e="",n,r){const o=[];for(const[i,s]of Object.entries(t)){const a=e?`${e}.${i}`:i;if(typeof s=="string"){if(s.trim().length>0){if(s.trim()===""){const l=O(r,a,s);o.push(Ae(a,l));continue}try{const l=await Z(s),u=l.detected,f=l.confidence;if(u&&u!==n&&f>.5){if(be(n,u,f))continue;const d=O(r,a,s);o.push(ve(a,u,n,f,s,d))}}catch(l){const u=O(r,a,s);o.push(Te(a,l instanceof Error?l.message:"Unknown error",u))}}}else if(Array.isArray(s))for(const[l,u]of s.entries()){const f=`${a}[${l}]`;if(typeof u=="string"&&u.trim().length>0){if(u.trim()===""){const d=O(r,f,u);o.push(Ae(f,d));continue}try{const d=await Z(u),k=d.detected,m=d.confidence;if(k&&k!==n&&m>F.ARRAY_TEXT){if(be(n,k,m))continue;const N=O(r,f,u);o.push(ve(f,k,n,m,u,N))}}catch(d){const k=O(r,f,u);o.push(Te(f,d instanceof Error?d.message:"Unknown error",k))}}}else if(typeof s=="object"&&s!==null){const l=await ee(s,a,n,r);o.push(...l)}}return o}c(ee,"checkFieldLanguages"),Object.entries(Ot).forEach(([t,e])=>{X[t]=e});class Me{static{c(this,"Lint")}async start(e){try{console.log("\u{1F50D} Linting translation files...");const n=C.getLocaleConfig(),r=b.resolve(n.output);!n.entry.includes(".json")||n.entry.includes("*")?(console.log(`Running in ${g.bold.cyan("\u{1F4C2} Folder Mode")}`),await this.lintFolderMode(n,r,e)):(console.log(`Running in ${g.bold.cyan("\u{1F4C4} Flat Mode")}`),await this.lintFlatMode(n,r,e))}catch(n){p.consola.error("Linting failed:",n),process.exit(1)}}async lintFolderMode(e,n,r){const{getEntryFolderFiles:o}=await Promise.resolve().then(function(){return an}),i=o(e);if(!i){p.consola.error("No entry files found");return}const s=Object.keys(i);p.consola.info(`Found ${g.bold.cyan(s.length)} files.`);const a=[];for(const l of[e.entryLocale,...e.outputLocales])for(const u of s){const f=b.resolve(n,l,u),d=await ke(f,l,ee);d.length>0&&a.push({file:f,issues:d})}Se(a,r)}async lintFlatMode(e,n,r){const o=[];for(const i of[e.entryLocale,...e.outputLocales]){const s=b.resolve(n,i)+".json",a=await ke(s,i,ee);a.length>0&&o.push({file:s,issues:a})}Se(o,r)}}const U=L.memo(({hide:t,filename:e,to:n,from:r,progress:o,maxStep:i,step:s,isLoading:a,needToken:l})=>{const u=h.useTheme(),[f,d]=L.useState(0),k=L.useRef(0),m=L.useRef(null);return L.useEffect(()=>(k.current=o,m.current&&clearInterval(m.current),m.current=setInterval(()=>{d(N=>{const G=k.current,y=G-N;if(Math.abs(y)<1)return m.current&&(clearInterval(m.current),m.current=null),G;const v=Math.sign(y)*Math.max(.2,Math.min(1,Math.abs(y)*.05));return N+v})},300),()=>{m.current&&(clearInterval(m.current),m.current=null)}),[o]),t?null:S.jsxs(h.SplitView,{flexDirection:"column",children:[S.jsx(P.Text,{backgroundColor:u.colorBgLayout,color:u.colorText,children:` \u{1F4DD} ${e} `}),S.jsxs(P.Text,{color:u.colorTextDescription,children:["- from ",S.jsx(P.Text,{bold:!0,color:u.colorInfo,children:r})," to ",S.jsx(P.Text,{bold:!0,color:u.colorInfo,children:n}),S.jsx(P.Text,{color:u.colorTextDescription,children:` [Tokens: ${l}]`})]}),a?S.jsxs(P.Box,{children:[S.jsx(h.Spinner,{label:` ${Math.round(f)}% [${s}/${i} chunks] `}),S.jsx(h.ProgressBar,{value:Math.round(f)})]}):S.jsx(h.StatusMessage,{variant:"success",children:"Success"})]})}),Jt=3,z=2,Ce=2,x=c(t=>ce.encode(t).length,"calcToken"),D=c(t=>ce.encode(String(t)).length,"calcEncodedKeyToken"),Ne=c(t=>D(t)+Jt,"calcPrimitiveValueToken"),Le=c((t,e=0)=>A.sumBy(Object.entries(t),([n,r])=>D(n)+z+(A.isPlainObject(r)?Le(r,e+1):Ne(r)))+Ce+e,"calcJsonToken"),qt=new Set([`
`,`\r
`,"[!NOTE]","[!IMPORTANT]","[!WARNING]","[!CAUTION]","\\[!NOTE]","\\[!IMPORTANT]","\\[!WARNING]","\\[!CAUTION]","\\[!NOTE]\\","\\[!IMPORTANT]\\","\\[!WARNING]\\","\\[!CAUTION]\\"]),Kt=c(t=>qt.has(t)?!0:/^[\s\p{P}\p{S}\u{1F300}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}]*$/u.test(t.replaceAll(" ","")),"checkMdString"),xe=c(async t=>fe.unified().use(Je).use(ue).use(le).parse(t.trim()),"convertMarkdownToMdast"),Ht=c((t,e)=>{const n={};let r=0;return ge.visit(t,e||"text",o=>{n[r]=o.value,r++}),n},"convertMdastToMdastObj"),Vt=c(t=>{const e={};for(const[n,r]of Object.entries(t))Kt(r)||(e[Number(n)]=r);return e},"pickMdastObj"),Wt=c(({mdast:t,entry:e,target:n},r)=>{const o={...e,...n};let i=0;return ge.visit(t,r||"text",s=>{s.value=o[i],i++}),t},"mergeMdastObj"),te=c(async t=>fe.unified().use(qe,{bullet:"-",emphasis:"*",fences:!0,rule:"-",strong:"*",tightDefinitions:!0}).use(le).use(ue).stringify(t).toString(),"convertMdastToMarkdown"),ne=c((t,e)=>{const n=Ke.diff(e,t),r=n.filter(a=>a.op==="add"),o=n.filter(a=>a.op==="remove"),i=A.cloneDeep(e),s={};for(const a of o)A.unset(i,a.path);for(const a of r)A.set(s,a.path,a.value);return{add:r,entry:s,remove:o,target:i}},"diff"),Qt=c((t,e)=>A.reduce(Object.entries(t),(n,[r,o])=>{let[i,s]=n.pop()||[{},Ce];const a=A.isPlainObject(o)?Le(o,1):Ne(o);return s+D(r)+z+a<=e?(i[r]=o,s+=D(r)+z+a,n.push([i,s])):n.push([i,s],[{[r]:o},D(r)+z+a]),n},[]).map(([n])=>n),"splitJSONtoSmallChunks"),Ee=c((t,e)=>{let n=(At[t.modelName||he]-x(e))/3;return t.splitToken&&t.splitToken<n&&(n=t.splitToken),n=Math.floor(n),n},"getSplitToken"),Xt=c((t,e,n,r)=>{const o=ne(e,n).entry,i=Ee(t,r);return Qt(o,i)},"splitJsonToChunks");class se{static{c(this,"RecursiveCharacterTextSplitter")}chunkSize;chunkOverlap;lengthFunction;separators;constructor(e){this.chunkSize=e.chunkSize,this.chunkOverlap=e.chunkOverlap,this.lengthFunction=e.lengthFunction||(n=>n.length),this.separators=[`
`,`
`," ",""]}static fromLanguage(e,n){const r=new se(n);return e==="markdown"&&(r.separators=[`
## `,`
### `,`
#### `,`
##### `,`
###### `,`
`,`
`," ",""]),r}async splitText(e){return this.splitTextRecursively(e,this.separators)}splitTextRecursively(e,n){const r=[];let o=n.at(-1)||"",i=[];for(let u=0;u<n.length;u++){const f=n[u];if(f){if(f===""){o=f;break}if(e.includes(f)){o=f,i=n.slice(u+1);break}}}const s=this.splitTextWithSeparator(e,o);let a=[];const l=o===""?"":o;for(const u of s)if(this.lengthFunction(u)<this.chunkSize)a.push(u);else{if(a.length>0){const f=this.mergeSplits(a,l);r.push(...f),a=[]}if(i.length===0)r.push(u);else{const f=this.splitTextRecursively(u,i);r.push(...f)}}if(a.length>0){const u=this.mergeSplits(a,l);r.push(...u)}return r}splitTextWithSeparator(e,n){let r;return n?r=e.split(n):r=e.split(""),r.filter(o=>o!=="")}mergeSplits(e,n){const r=[],o=[];let i=0;for(const a of e){const l=this.lengthFunction(a);if(i+l+(o.length>0?this.lengthFunction(n):0)>this.chunkSize&&(i>this.chunkSize&&console.warn(`Created a chunk of size ${i}, which is longer than the specified ${this.chunkSize}`),o.length>0)){const u=this.joinDocs(o,n);for(u!==null&&r.push(u);i>this.chunkOverlap||i+l+(o.length>0?this.lengthFunction(n):0)>this.chunkSize&&i>0;){const f=o[0];if(f)i-=this.lengthFunction(f)+(o.length>1?this.lengthFunction(n):0),o.shift();else break}}o.push(a),i+=l+(o.length>1?this.lengthFunction(n):0)}const s=this.joinDocs(o,n);return s!==null&&r.push(s),r}joinDocs(e,n){const r=e.join(n).trim();return r===""?null:r}}let Yt=class{static{c(this,"TranslateMarkdown")}mdast;entry={};config;check;definition;constructor(e){this.config=e,this.check=["text","yaml",e?.markdown?.translateCode&&"code"].filter(Boolean)}async genTarget(e){return this.mdast=await xe(e),this.entry=Ht(this.mdast,this.check),Vt(this.entry)}async genMarkdownByMdast(e){if(!e)return;const n=Wt({entry:this.entry,mdast:this.mdast,target:e},this.check);return te(n)}async clearMarkdownString(e){const n=[],r=await xe(e);return r.children=r.children.map(o=>o.type==="definition"?(n.push(o),!1):o).filter(Boolean),{content:await te(r),definition:await te({children:n,type:"root"})}}async genSplitMarkdown(e,n){this.definition="";const{content:r,definition:o}=await this.clearMarkdownString(e);return this.definition=o,await se.fromLanguage("markdown",{chunkOverlap:0,chunkSize:Ee(this.config,n),lengthFunction:c(s=>x(s),"lengthFunction")}).splitText(r)}async genMarkdownByString(e){return[...e,this.definition].join(`
`)}};const re=c(t=>{const e=M.readFileSync(t,"utf8");return JSON.parse(e)},"readJSON"),B=c((t,e)=>{const n=He(e,{space:" "});M.writeFileSync(t,n+`\r
`,"utf8")},"writeJSON"),Zt=c(t=>M.readFileSync(t,"utf8"),"readMarkdown"),Ie=c((t,e)=>{M.writeFileSync(t,e,"utf8")},"writeMarkdown"),en=c(t=>{let e={};for(const n of t)e=A.merge(e,n);return e},"mergeJsonFromChunks");class J{static{c(this,"ChatPromptTemplate")}messages;constructor(e){this.messages=e}static fromMessages(e){const n=e.map(([r,o])=>({content:o,role:r}));return new J(n)}async formatMessages(e){return this.messages.map(n=>({content:this.formatString(n.content,e),role:n.role}))}formatString(e,n){let r=e;for(const[o,i]of Object.entries(n))if(i!==void 0){const s=new RegExp(`\\{${o}\\}`,"g");r=r.replace(s,i)}return r}}const _e="You can adjust the tone and style, taking into account the cultural connotations and regional differences of certain words. As a translator, you need to translate the original text into a translation that meets the standards of accuracy and elegance.",tn=c((t=_e)=>J.fromMessages([["system",["Translate the i18n JSON file from {from} to {to} according to the BCP 47 standard",`Here are some reference to help with better translation. ---${t}---`,"Keep the keys the same as the original file and make sure the output remains a valid i18n JSON file.","Do not include any additional text or explanations outside the JSON object.Start directly with a left brace and end with a right brace."].filter(Boolean).join(`
`)],["user","{json}"]]),"promptJsonTranslate"),nn=c((t=_e)=>J.fromMessages([["system",["Translate the markdown file from {from} to {to} according to the BCP 47 standard",`Here are some reference to help with better translation. ---${t}---`,"Make sure the output remains a valid markdown file."].filter(Boolean).join(`
`)],["user","{text}"]]),"promptStringTranslate");let rn=class{static{c(this,"TranslateLocale")}client;config;isJsonMode;promptJson;promptString;constructor(e,n,r){this.config=e,this.client=new We({apiKey:n,baseURL:r,maxRetries:4}),this.promptJson=tn(e.reference),this.promptString=nn(e.reference),this.isJsonMode=!!this.config?.experimental?.jsonMode}async runByString({from:e,to:n,text:r}){try{const o=await this.promptString.formatMessages({from:e||this.config.entryLocale,text:r,to:n}),s=(await this.client.chat.completions.create({messages:o,model:this.config.modelName||"gpt-3.5-turbo",temperature:this.config.temperature,top_p:this.config.topP})).choices[0]?.message?.content;return s||this.handleError(),s}catch(o){this.handleError(o)}}async runByJson({from:e,to:n,json:r}){try{const o=await this.promptJson.formatMessages({from:e||this.config.entryLocale,json:JSON.stringify(r),to:n}),s=(await this.client.chat.completions.create({messages:o,model:this.config.modelName||"gpt-3.5-turbo",temperature:this.config.temperature,top_p:this.config.topP,...this.isJsonMode&&{response_format:{type:"json_object"}}})).choices[0]?.message?.content;s||this.handleError();try{return JSON.parse(s)}catch{h.alert.warn("parse fail, try to use dirty json");try{return Ve.parse(s)}catch{h.alert.error("i18n dirty json fail"),h.alert.error(s,!0)}}}catch(o){this.handleError(o)}}handleError(e){h.alert.error(`Translate failed, ${e||"please check your network or try again..."}`,!0)}};class Pe{static{c(this,"I18n")}config;maxStep=1;translateLocaleService;translateMarkdownService;constructor({openAIApiKey:e,openAIProxyUrl:n,config:r}){this.config=r,this.translateLocaleService=new rn(r,e,n),this.translateMarkdownService=new Yt(r)}async translateMarkdown(e){return e.mode===R.STRING?this.translateMarkdownByString(e):this.translateMarkdownByMdast(e)}async translateMarkdownByString({md:e,to:n,onProgress:r,from:o,filename:i,onChunkComplete:s}){const a=await this.translateLocaleService.promptString.formatMessages({from:o||this.config.entryLocale,text:"",to:n}),l=await this.translateMarkdownService.genSplitMarkdown(e,JSON.stringify(a));if(this.maxStep=l.length,l.length===0)return;const u=l.length*x(JSON.stringify(a))+x(JSON.stringify(l)),f=Array.from({length:this.maxStep},()=>0);let d="";const k=Array.from({length:this.maxStep},()=>""),m=c(()=>{const y=f.filter(T=>T===2).length,v=f.filter(T=>T===1).length;let w=0;if(y===this.maxStep)w=100;else if(v>0){const T=y/this.maxStep*100,q=(y+1)/this.maxStep*100;w=Math.floor(Math.max(T,q-1))}else w=Math.floor(y/this.maxStep*100);r?.({isLoading:y<this.maxStep,maxStep:this.maxStep,needToken:u,progress:w,step:y})},"updateProgress");r?.({isLoading:!0,maxStep:this.maxStep,needToken:u,progress:0,step:0});const N=await ae(l,async(y,v)=>{f[v]=1,m(),setTimeout(()=>{m()},800);const w=await this.translateLocaleService.runByString({from:o||this.config.entryLocale,text:y,to:n});return f[v]=2,this.config.saveImmediately&&i&&(k[v]=w,(v===0||f.slice(0,v).every(T=>T===2))&&(d=await this.translateMarkdownService.genMarkdownByString(k.filter(Boolean)),Ie(i,d),s?.(w,d))),m(),w},{concurrency:this.config?.concurrency});return r?.({isLoading:!1,maxStep:this.maxStep,needToken:u,progress:100,step:this.maxStep}),{result:this.config.saveImmediately&&d?d:await this.translateMarkdownService.genMarkdownByString(N),tokenUsage:u+x(JSON.stringify(N))}}async translateMarkdownByMdast({md:e,...n}){const r=await this.translateMarkdownService.genTarget(e),{matter:o,mode:i,onChunkComplete:s,...a}=n,l=await this.translate({...a,entry:r,target:{}});if(!l?.result)return;const u=await this.translateMarkdownService.genMarkdownByMdast(l);if(u)return{result:u,tokenUsage:l.tokenUsage}}async translate({entry:e,target:n,to:r,onProgress:o,from:i,filename:s,onChunkComplete:a}){const l=await this.translateLocaleService.promptJson.formatMessages({from:i||this.config.entryLocale,json:JSON.stringify({}),to:r}),u=Xt(this.config,e,n,JSON.stringify(l));if(this.maxStep=u.length,u.length===0)return;const f=u.length*x(JSON.stringify(l))+x(JSON.stringify(u)),d=Array.from({length:this.maxStep},()=>0);let k=A.merge({},n);const m=c(()=>{const y=d.filter(T=>T===2).length,v=d.filter(T=>T===1).length;let w=0;if(y===this.maxStep)w=100;else if(v>0){const T=y/this.maxStep*100,q=(y+1)/this.maxStep*100;w=Math.floor(Math.max(T,q-1))}else w=Math.floor(y/this.maxStep*100);o?.({isLoading:y<this.maxStep,maxStep:this.maxStep,needToken:f,progress:w,step:y})},"updateProgress");o?.({isLoading:!0,maxStep:this.maxStep,needToken:f,progress:0,step:0});const N=await ae(u,async(y,v)=>{d[v]=1,m(),setTimeout(()=>{m()},800);const w=await this.translateLocaleService.runByJson({from:i||this.config.entryLocale,json:y,to:r});return d[v]=2,this.config.saveImmediately&&s&&(k=A.merge(k,w),B(s,k),a?.(w,k)),m(),w},{concurrency:this.config?.concurrency});return o?.({isLoading:!1,maxStep:this.maxStep,needToken:f,progress:100,step:this.maxStep}),{result:s?k:await A.merge(n,en(N)),tokenUsage:f+x(JSON.stringify(N))}}}const on=c(t=>{for(const e of t.outputLocales){const n=b.resolve(t.output,`${e}.json`);M.existsSync(n)||B(n,{})}},"checkLocales"),sn=c((t,e)=>{for(const n of t.outputLocales){const r=b.resolve(t.output,n);M.existsSync(r)||M.mkdirSync(r)}for(const n of t.outputLocales)for(const r of e){const o=b.resolve(t.output,n,r);try{const i=b.dirname(o);M.mkdirSync(i,{recursive:!0})}catch{}M.existsSync(o)||B(o,{})}},"checkLocaleFolders"),Fe=c(t=>{try{const e=b.resolve("./",t.entry);return M.existsSync(e)||h.alert.error(`Can't find ${g.bold.yellow(t.entry)} in dir`,!0),re(e)}catch{Ye.exit(1)}},"getEntryFile"),Oe=c(t=>{const e=t.entry.replaceAll("*","").replaceAll("*.json",""),n=de.globSync(b.join(e,"**/*.json").replaceAll("\\","/"),{nodir:!0}),r={};for(const o of n)r[b.relative(e,o)]=re(o);if(Object.keys(r).length===0){h.alert.error(`Can't find .json files in ${g.bold.yellow(e)}`,!0);return}return r},"getEntryFolderFiles");var an=Object.freeze({__proto__:null,getEntryFile:Fe,getEntryFolderFiles:Oe});const Re=c(t=>{const e=re(t);return e||(B(t,{}),{})},"getLocaleObj"),oe=c((t,e)=>{try{if(t===e)return!0;if(typeof t!=typeof e)return!1;if(typeof t=="object"&&typeof e=="object"){const n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(const o of n)if(!r.includes(o)||!oe(t[o],e[o]))return!1}return typeof t==typeof e}catch{return!1}},"isEqualJsonKeys");class cn{static{c(this,"TranslateLocale")}config;query=[];i18n;constructor(){this.config=C.getLocaleConfig(),this.i18n=new Pe({config:this.config,openAIApiKey:C.getOpenAIApiKey(),openAIProxyUrl:C.getOpenAIProxyUrl()})}async start(){p.consola.start("Lobe I18N is analyzing your project... \u{1F92F}\u{1F30F}\u{1F50D}"),!this.config.entry.includes(".json")||this.config.entry.includes("*")?this.genFolderQuery():this.genFlatQuery(),this.query.length>0?await this.runQuery():p.consola.success("No content requiring translation was found."),p.consola.success("All i18n tasks have been completed\uFF01")}async runQuery(){p.consola.info(`Current model setting: ${g.cyan(this.config.modelName)} (temperature: ${g.cyan(this.config.temperature)}) ${this.config.experimental?.jsonMode?g.red(" [JSON Mode]"):""}}`);let e=0;for(const n of this.query){const r={filename:n.filename,from:n.from||this.config.entryLocale,to:n.to},{rerender:o,clear:i}=h.render(S.jsx(U,{hide:!0,isLoading:!0,maxStep:1,progress:0,step:0,...r})),s=await this.i18n.translate({...n,filename:n.filename,onChunkComplete:c(()=>{},"onChunkComplete"),onProgress:c(l=>{l.maxStep>0?o(S.jsx(U,{...l,...r})):i()},"onProgress")});i();const a=b.relative(".",n.filename);s?.result&&Object.keys(s.result).length>0?(this.config.saveImmediately||B(n.filename,s.result),e+=s.tokenUsage,p.consola.success(g.yellow(a),g.gray(`[Token usage: ${s.tokenUsage}]`))):p.consola.warn("No translation result was found:",g.yellow(a))}e>0&&p.consola.info("Total token usage:",g.cyan(e))}genFolderQuery(){const e=this.config,n=Oe(e),r=Object.keys(n);p.consola.info(`Running in ${g.bold.cyan("\u{1F4C2} Folder Mode")} and has found ${g.bold.cyan(r.length)} files.`),sn(e,r);for(const o of e.outputLocales)for(const[i,s]of r.entries()){process.stdout.isTTY&&(process.stdout.clearLine(0),process.stdout.cursorTo(0)),process.stdout.write(`${g.cyan(o)}${g.gray(`[${i+1}/${r.length}] - `)}${g.yellow(s)}`);const a=b.resolve(e.output,o,s),l=n[s],u=ne(l,Re(a)).target;oe(l,u)||this.query.push({entry:l,filename:a,from:e.entryLocale,target:u,to:o})}process.stdout.isTTY&&(process.stdout.clearLine(0),process.stdout.cursorTo(0))}genFlatQuery(){const e=this.config,n=Fe(e);p.consola.start(`Running in ${g.bold.cyan("\u{1F4C4} Flat Mode")}, and translating ${g.bold.cyan(e.outputLocales.join("/"))} locales..`),on(e);for(const r of e.outputLocales){const o=b.resolve(e.output,r)+".json",i=n,s=ne(i,Re(o)).target;oe(i,s)||this.query.push({entry:i,filename:o,from:e.entryLocale,target:s,to:r})}}}const je=c((t,e)=>t.map(n=>n.includes("*")||n.includes(e)?n:b.join(n,`**/*${e}`).replaceAll("\\","/")),"matchInputPattern");class $e{static{c(this,"TranslateMarkdown")}config;markdownConfig;query=[];i18n;constructor(){this.markdownConfig=C.getMarkdownConfigFile();const e=C.getConfigFile();this.config={...e,entryLocale:e.entryLocale||this.markdownConfig.entryLocale,markdown:this.markdownConfig,outputLocales:e.outputLocales||this.markdownConfig.outputLocales},this.i18n=new Pe({config:this.config,openAIApiKey:C.getOpenAIApiKey(),openAIProxyUrl:C.getOpenAIProxyUrl()})}async start(){p.consola.start("Lobe I18N is analyzing your markdown... \u{1F92F}\u{1F30F}\u{1F50D}");const e=this.markdownConfig.entry;(!e||e.length===0)&&h.alert.error("No markdown entry was found.",!0);let n=de.globSync(je(e,".md"),{ignore:this.markdownConfig.exclude?je(this.markdownConfig.exclude||[],".md"):void 0,nodir:!0});this.markdownConfig.entryExtension&&(n=n.filter(r=>r.includes(this.markdownConfig.entryExtension||".md"))),(!n||n.length===0)&&h.alert.error("No markdown entry was found.",!0),this.genFilesQuery(n),this.query.length>0?await this.runQuery():p.consola.success("No content requiring translation was found."),p.consola.success("All i18n tasks have been completed\uFF01")}async runQuery(){p.consola.info(`Current model setting: ${g.cyan(this.config.modelName)} (temperature: ${g.cyan(this.config.temperature)}) ${this.config.experimental?.jsonMode?g.red(" [JSON Mode]"):""}}`);let e=0;for(const n of this.query){const r={filename:n.filename,from:n.from||this.markdownConfig.entryLocale||this.config.entryLocale,to:n.to},{rerender:o,clear:i}=h.render(S.jsx(U,{hide:!0,isLoading:!0,maxStep:1,progress:0,step:0,...r})),s=await this.i18n.translateMarkdown({...n,onProgress:c(l=>{l.maxStep>0?o(S.jsx(U,{...l,...r})):i()},"onProgress")});i();const a=b.relative(".",n.filename);if(s?.result&&Object.keys(s.result).length>0){let l=s.result;this.markdownConfig.includeMatter||(l=pe.stringify(s.result,n.matter)),this.config.saveImmediately||Ie(n.filename,l),e+=s.tokenUsage,p.consola.success(g.yellow(a),g.gray(`[Token usage: ${s.tokenUsage}]`))}else p.consola.warn("No translation result was found:",g.yellow(a))}e>0&&p.consola.info("Total token usage:",g.cyan(e))}genFilesQuery(e,n){const r=this.markdownConfig;n||p.consola.start(`Running in ${g.bold.cyan(`\u{1F4C4} ${e.length} Markdown`)}, and translating to ${g.bold.cyan(r?.outputLocales?.join("/"))} locales..`);for(const o of e)try{const i=Zt(o);for(const s of r.outputLocales||[]){const a=this.getTargetExtension(s,o,i),l=this.getTargetFilename(o,a);if(M.existsSync(l))continue;const u=this.getMode(o,i),{data:f,content:d}=pe(i);p.consola.info(`\u{1F4C4} To ${s}: ${g.yellow(l)}`),this.query.push({filename:l,from:r.entryLocale,matter:f,md:this.markdownConfig.includeMatter?i:d,mode:u,to:s})}}catch(i){p.consola.error(`Error processing file ${o}:`,i),h.alert.error(`${o} not found`,!0)}}getTargetExtension(e,n,r){return this.markdownConfig.outputExtensions?.(e,{fileContent:r,filePath:n,getDefaultExtension:H})||H(e)}getTargetFilename(e,n){if(this.markdownConfig.entryExtension)return b.resolve(".",e.replace(this.markdownConfig.entryExtension||".md",n));if(this.markdownConfig.entryLocale&&e.includes(`.${this.markdownConfig.entryLocale}.`))return[e.split(`.${this.markdownConfig.entryLocale}.`)[0],n].join("");{const r=e.split(".");return r.pop(),[r.join("."),n].join("")}}getMode(e,n){const r=this.markdownConfig.mode;return r?A.isString(r)?r:r({fileContent:n,filePath:e})||R.STRING:R.STRING}}const ln=Be({pkg:K,shouldNotifyInNpmScript:!0});ln.notify({isGlobal:!0});const E=new _.Command;E.name("lobe-i18n").description(K.description).version(K.version).addOption(new _.Option("-o, --option","Setup lobe-i18n preferences")).addOption(new _.Option("-c, --config <string>","Specify the configuration file")).addOption(new _.Option("-m, --with-md","Run i18n translation and markdown translation simultaneously")).addOption(new _.Option("--lint","Lint translation files for language correctness")).addOption(new _.Option("--quiet","Only show errors, suppress warnings")),E.command("locale",{isDefault:!0}).action(async()=>{const t=E.opts();t.option?h.render(S.jsx(Pt,{})):t.lint?(t.config&&j.loadCustomConfig(t.config),await new Me().start(t.quiet)):(t.config&&j.loadCustomConfig(t.config),await new cn().start(),t.withMd&&await new $e().start())}),E.command("md").action(async()=>{const t=E.opts();t.config&&j.loadCustomConfig(t.config),await new $e().start()}),E.command("lint").action(async()=>{const t=E.opts();t.config&&j.loadCustomConfig(t.config),await new Me().start(t.quiet)}),E.parse();