@lobehub/i18n-cli
Version:
Lobe i18n is a CLI tool that automate translate your i18n localization with AI
23 lines (19 loc) • 40.7 kB
JavaScript
var Xe=Object.defineProperty;var c=(n,e)=>Xe(n,"name",{value:e,configurable:!0});import{createRequire as Ye}from"node:module";const ce=Ye(import.meta.url);import{jsx as S,jsxs as K}from"react/jsx-runtime";import{alert as A,TextInput as le,ConfigPanel as Ze,useTheme as et,SplitView as tt,Spinner as nt,ProgressBar as ot,StatusMessage as rt,render as H}from"@lobehub/cli-ui";import{Command as st,Option as _}from"commander";import it from"update-notifier";import at from"conf";import{cosmiconfigSync as ct}from"cosmiconfig";import{memo as ue,useState as fe,useMemo as lt,useRef as pe,useEffect as ut}from"react";import p from"chalk";import ft from"dotenv";import{merge as E,sumBy as pt,isPlainObject as ge,cloneDeep as gt,unset as dt,set as mt,reduce as ht,isString as yt}from"lodash-es";import{consola as d}from"consola";import{resolve as M,dirname as kt,join as de,relative as V}from"node:path";import{eld as me}from"@yutengjing/eld";import{Text as P,Box as St}from"ink";import he from"p-map";import{encode as ye}from"gpt-tokenizer";import ke from"remark-frontmatter";import Se from"remark-gfm";import wt from"remark-parse";import bt from"remark-stringify";import{unified as we}from"unified";import{visit as be}from"unist-util-visit";import{diff as At}from"just-diff";import Mt from"json-stable-stringify";import{writeFileSync as Ae,readFileSync as Me,existsSync as F,mkdirSync as Te}from"node:fs";import Tt from"dirty-json";import vt from"openai";import{globSync as ve}from"glob";import*as Ct from"node:process";import Ce from"gray-matter";var Nt="@lobehub/i18n-cli",Lt="1.25.0",Et="Lobe i18n is a CLI tool that automate translate your i18n localization with AI",It=["ai","i18n","openai","gpt"],xt="https://github.comlobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n",_t={url:"https://github.com/lobehub/lobe-cli-toolbox/issues/new"},Pt={type:"git",url:"https://github.com/lobehub/lobe-cli-toolbox.git"},Ft="MIT",Rt="LobeHub <i@lobehub.com>",Ot=!1,$t="module",jt={"@":"./src"},Dt={require:{types:"./dist/index.d.cts",default:"./dist/index.cjs"},import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"}},Bt="./dist/index.cjs",Gt="./dist/index.mjs",Ut="./dist/index.d.cts",zt={"lobe-i18n":"dist/cli.js"},Jt=["dist"],Kt={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"},Ht={"@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"},Vt={"@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",qt={node:">=18"},Qt={access:"public",registry:"https://registry.npmjs.org/"},W={name:Nt,version:Lt,description:Et,keywords:It,homepage:xt,bugs:_t,repository:Pt,license:Ft,author:Rt,sideEffects:Ot,type:$t,imports:jt,exports:Dt,main:Bt,module:Gt,types:Ut,bin:zt,files:Jt,scripts:Kt,dependencies:Ht,devDependencies:Vt,packageManager:Wt,engines:qt,publishConfig:Qt},R=(n=>(n.MDAST="mdast",n.STRING="string",n))(R||{});const q=c(n=>`.${n}.md`,"getDefaultExtension"),Xt={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},Ne="o4-mini",Yt={concurrency:5,markdown:{entry:[],mode:R.STRING,outputExtensions:q},modelName:Ne,temperature:0},L=c((n,e)=>{n[e]||A.error(`Can't find ${p.bold.yellow("outputLocales")} in config`)},"checkOptionKeys"),Le={apiBaseUrl:{default:"",type:"string"},openaiToken:{default:"",type:"string"}},Q=new at({projectName:"lobe-i18n",schema:Le});class Zt{static{c(this,"ExplorerConfig")}explorer;customConfig;constructor(){this.explorer=ct("i18n")}loadCustomConfig(e){this.customConfig=e}getConfigFile(){return this.customConfig?this.explorer.load(this.customConfig)?.config:this.explorer.search()?.config}}const O=new Zt;ft.config();const X=c(n=>Q.get(n),"getConfig"),en=c(n=>Le[n].default,"getDefulatConfig"),tn=c((n,e)=>Q.set(n,e),"setConfig"),nn=c(()=>process.env.OPENAI_API_KEY||X("openaiToken"),"getOpenAIApiKey"),on=c(()=>process.env.OPENAI_PROXY_URL||X("apiBaseUrl"),"getOpenAIProxyUrl"),Y=c(()=>{const n=O.getConfigFile();return n?E(Yt,n):A.error(`Can't find ${p.bold.yellow("config")}`,!0)},"getConfigFile"),rn=c(()=>{const n=Y();return L(n,"entry"),L(n,"entryLocale"),L(n,"output"),L(n,"outputLocales"),n},"getLocaleConfig"),sn=c(()=>{const n=Y();if(!n.markdown)return A.error(`Can't find ${p.bold.yellow("config.markdown")}`,!0);const e=E(n?.markdown||{},{entryLocale:n?.markdown?.entryLocale||n.entryLocale,outputLocales:n?.markdown?.outputLocales||n.outputLocales});return L(e,"entry"),L(e,"entryLocale"),L(e,"outputLocales"),e},"getMarkdownConfigFile");var T={getConfig:X,getConfigFile:Y,getDefulatConfig:en,getLocaleConfig:rn,getMarkdownConfigFile:sn,getOpenAIApiKey:nn,getOpenAIProxyUrl:on,setConfig:tn};const an=c(()=>{const n=Q.store;return{get:T.getConfig,getDefault:T.getDefulatConfig,set:T.setConfig,store:n}},"useConfStore"),cn=ue(()=>{const[n,e]=fe(),{store:t,set:o,getDefault:r}=an(),i=c((a,l)=>{o(a,l),e("")},"setConfig"),s=lt(()=>[{children:S(le,{defaultValue:t.openaiToken,onSubmit:c(a=>i("openaiToken",a),"onSubmit"),placeholder:"Input OpenAI token..."}),defaultValue:r("openaiToken"),key:"openaiToken",label:"OpenAI token",showValue:!1,value:t.openaiToken},{children:S(le,{defaultValue:t.apiBaseUrl,onSubmit:c(a=>i("apiBaseUrl",a),"onSubmit"),placeholder:"Set openAI API proxy, default value: https://api.openai.com/v1/..."}),defaultValue:r("apiBaseUrl"),desc:"OpenAI API proxy, default value: https://api.openai.com/v1/",key:"apiBaseUrl",label:"OpenAI API proxy",showValue:!1,value:t.apiBaseUrl}],[t]);return S(Ze,{active:n,items:s,logo:"\u{1F92F}",setActive:e,title:"Lobe I18N Config"})}),ln={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"},Z=Object.fromEntries(Object.entries(ln).map(([n,e])=>[e,n]));Z.zh_TW="zh",Z.zh_CN="zh";const un={"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"},Ee=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"])},fn=["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"],I={ARABIC_SIMILAR:.9,ARRAY_TEXT:.65,LONG_TEXT:.7,SHORT_TEXT:.7,SIMILAR_LANGUAGES:.8};function x(n,e,t){try{const i=ce("node:fs").readFileSync(n,"utf8").split(`
`),s=new RegExp(`"${e.split(".").pop()}"\\s*:\\s*"${t.replaceAll(/[$()*+.?[\\\]^{|}]/g,"\\$&")}"`);for(const[a,l]of i.entries())if(s.test(l))return a+1;return}catch{return}}c(x,"findLineNumber");async function Ie(n,e,t){try{const r=ce("node:fs").readFileSync(n,"utf8"),i=JSON.parse(r),{extractMainLanguageFromLocale:s}=await Promise.resolve().then(function(){return hn}),a=s(e);return await t(i,"",a,n)}catch(o){return[{errorMessage:`Failed to process file: ${o instanceof Error?o.message:"Unknown error"}`,key:"file_error",severity:"error",type:"eld_error"}]}}c(Ie,"processLintFile");function pn(n){return n.replace(process.cwd()+"/","")}c(pn,"getRelativePath");function gn(n){return M(n)}c(gn,"getAbsolutePath");function dn(n,e){const t=n.severity==="error"?p.red("error"):p.yellow("warning"),o=n.severity==="error"?t+" ":t+" ",r=n.lineNumber?.toString().padStart(4," ")||"";let i="";switch(n.type){case"field_language_mismatch":{const a=`${p.green(n.expectedLanguage)} \u2192 ${p.red(n.detectedLanguage)}`,l=n.confidence?p.gray(`(confidence ${(n.confidence*100).toFixed(0)}%)`):"",f=`\x1B]8;;${n.lineNumber?`file://${e}:${n.lineNumber}`:`file://${e}`}\x07${n.fieldPath}\x1B]8;;\x07`;i=`${a} at ${p.cyan(f)}: ${p.white(`"${n.text}"`)} ${l}`.trim();break}case"empty_string":{const l=`\x1B]8;;${n.lineNumber?`file://${e}:${n.lineNumber}`:`file://${e}`}\x07${n.fieldPath}\x1B]8;;\x07`;i=`Empty string at ${p.cyan(l)}`;break}case"eld_error":{const l=`\x1B]8;;${n.lineNumber?`file://${e}:${n.lineNumber}`:`file://${e}`}\x07${n.fieldPath}\x1B]8;;\x07`;i=`Detection failed at ${p.cyan(l)}: ${p.red(n.errorMessage)}`;break}}const s=`${p.gray(`${r}:1`)} ${o} ${i}`;console.log(s)}c(dn,"displayIssue");function xe(n,e){if(n.length===0){d.success("\u2705 All translation files passed linting!");return}let t=0,o=0;for(const s of n)for(const a of s.issues)a.severity==="error"?t++:e||o++;if(e&&t===0){d.success("\u2705 No errors found in translation files!");return}const r=t+o,i=[];t>0&&i.push(p.red(`${t} error${t!==1?"s":""}`)),o>0&&i.push(p.yellow(`${o} warning${o!==1?"s":""}`)),console.log(`${p.bold("\u2716")} ${r} problem${r!==1?"s":""} (${i.join(", ")})`);for(const s of n){const a=pn(s.file),l=gn(s.file),u=e?s.issues.filter(f=>f.severity==="error"):s.issues;if(u.length!==0){console.log(`
${p.white.underline(a)}`);for(const f of u)dn(f,l)}}t>0&&d.error(`${p.bold.red("\u2716")} Found ${t} error${t!==1?"s":""}`),o>0&&d.warn(`${p.bold.yellow("\u26A0")} Found ${o} warning${o!==1?"s":""}`)}c(xe,"displayResults");let ee=null;async function _e(){return ee||(ee=(async()=>{console.log("\u{1F527} Initializing ELD language detector..."),await me.init("L"),console.log("\u2705 ELD language detector initialized")})()),ee}c(_e,"initializeELD");async function te(n){if(!n?.trim())return{confidence:0,detected:"",isReliable:!1,scores:{}};await _e();const e=me.detect(n),t=e.getScores(),o=Math.max(...Object.values(t));return{confidence:Math.min(o,1),detected:e.language,isReliable:e.isReliable(),scores:t}}c(te,"detectLanguage");function mn(n){return n.includes("_")?n.split("_")[0]||n:n.includes("-")&&n.split("-")[0]||n}c(mn,"extractMainLanguageFromLocale");var hn=Object.freeze({__proto__:null,detectLanguage:te,extractMainLanguageFromLocale:mn,initializeELD:_e});function Pe(n,e,t){if(Ee.has(n)&&Ee.has(e)&&t<I.ARABIC_SIMILAR)return!0;for(const o of Object.values($))if(o.has(n)&&o.has(e)&&t<I.SIMILAR_LANGUAGES)return!0;return!!(n==="tl"&&["es","pt"].includes(e)&&t<I.SIMILAR_LANGUAGES)}c(Pe,"isSimilarLanguage");function yn(n){return fn.some(e=>n.includes(e))}c(yn,"containsEnglishTerms");function kn(n,e,t,o,r){let i="warning";n>3&&e>I.LONG_TEXT&&(i="error"),n<=3&&e>I.SHORT_TEXT&&(i="error");const s=$.EAST_ASIAN.has(t),a=$.EAST_ASIAN.has(o);s!==a&&e>.5&&(i="error");const l=Object.values($).find(f=>f.has(o)),u=Object.values($).find(f=>f.has(t));return l&&u&&l!==u&&e>.6&&(i="error"),t==="en"&&o!=="en"&&yn(r)&&e>.5&&(i="error"),i}c(kn,"determineSeverity");function Fe(n,e,t,o,r,i){const s=kn(r.trim().length,o,e,t,r);return{confidence:o,detectedLanguage:e,expectedLanguage:t,fieldPath:n,key:"field_language_mismatch",lineNumber:i,severity:s,text:r,type:"field_language_mismatch"}}c(Fe,"createLanguageMismatchIssue");function Re(n,e){return{fieldPath:n,key:"empty_string",lineNumber:e,severity:"warning",type:"empty_string"}}c(Re,"createEmptyStringIssue");function Oe(n,e,t){return{errorMessage:e,fieldPath:n,key:"eld_error",lineNumber:t,severity:"warning",type:"eld_error"}}c(Oe,"createELDErrorIssue");async function ne(n,e="",t,o){const r=[];for(const[i,s]of Object.entries(n)){const a=e?`${e}.${i}`:i;if(typeof s=="string"){if(s.trim().length>0){if(s.trim()===""){const l=x(o,a,s);r.push(Re(a,l));continue}try{const l=await te(s),u=l.detected,f=l.confidence;if(u&&u!==t&&f>.5){if(Pe(t,u,f))continue;const g=x(o,a,s);r.push(Fe(a,u,t,f,s,g))}}catch(l){const u=x(o,a,s);r.push(Oe(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 g=x(o,f,u);r.push(Re(f,g));continue}try{const g=await te(u),y=g.detected,m=g.confidence;if(y&&y!==t&&m>I.ARRAY_TEXT){if(Pe(t,y,m))continue;const v=x(o,f,u);r.push(Fe(f,y,t,m,u,v))}}catch(g){const y=x(o,f,u);r.push(Oe(f,g instanceof Error?g.message:"Unknown error",y))}}}else if(typeof s=="object"&&s!==null){const l=await ne(s,a,t,o);r.push(...l)}}return r}c(ne,"checkFieldLanguages"),Object.entries(un).forEach(([n,e])=>{Z[n]=e});class $e{static{c(this,"Lint")}async start(e){try{console.log("\u{1F50D} Linting translation files...");const t=T.getLocaleConfig(),o=M(t.output);!t.entry.includes(".json")||t.entry.includes("*")?(console.log(`Running in ${p.bold.cyan("\u{1F4C2} Folder Mode")}`),await this.lintFolderMode(t,o,e)):(console.log(`Running in ${p.bold.cyan("\u{1F4C4} Flat Mode")}`),await this.lintFlatMode(t,o,e))}catch(t){d.error("Linting failed:",t),process.exit(1)}}async lintFolderMode(e,t,o){const{getEntryFolderFiles:r}=await Promise.resolve().then(function(){return Rn}),i=r(e);if(!i){d.error("No entry files found");return}const s=Object.keys(i);d.info(`Found ${p.bold.cyan(s.length)} files.`);const a=[];for(const l of[e.entryLocale,...e.outputLocales])for(const u of s){const f=M(t,l,u),g=await Ie(f,l,ne);g.length>0&&a.push({file:f,issues:g})}xe(a,o)}async lintFlatMode(e,t,o){const r=[];for(const i of[e.entryLocale,...e.outputLocales]){const s=M(t,i)+".json",a=await Ie(s,i,ne);a.length>0&&r.push({file:s,issues:a})}xe(r,o)}}const G=ue(({hide:n,filename:e,to:t,from:o,progress:r,maxStep:i,step:s,isLoading:a,needToken:l})=>{const u=et(),[f,g]=fe(0),y=pe(0),m=pe(null);return ut(()=>(y.current=r,m.current&&clearInterval(m.current),m.current=setInterval(()=>{g(v=>{const B=y.current,h=B-v;if(Math.abs(h)<1)return m.current&&(clearInterval(m.current),m.current=null),B;const w=Math.sign(h)*Math.max(.2,Math.min(1,Math.abs(h)*.05));return v+w})},300),()=>{m.current&&(clearInterval(m.current),m.current=null)}),[r]),n?null:K(tt,{flexDirection:"column",children:[S(P,{backgroundColor:u.colorBgLayout,color:u.colorText,children:` \u{1F4DD} ${e} `}),K(P,{color:u.colorTextDescription,children:["- from ",S(P,{bold:!0,color:u.colorInfo,children:o})," to ",S(P,{bold:!0,color:u.colorInfo,children:t}),S(P,{color:u.colorTextDescription,children:` [Tokens: ${l}]`})]}),a?K(St,{children:[S(nt,{label:` ${Math.round(f)}% [${s}/${i} chunks] `}),S(ot,{value:Math.round(f)})]}):S(rt,{variant:"success",children:"Success"})]})}),Sn=3,U=2,je=2,C=c(n=>ye(n).length,"calcToken"),j=c(n=>ye(String(n)).length,"calcEncodedKeyToken"),De=c(n=>j(n)+Sn,"calcPrimitiveValueToken"),Be=c((n,e=0)=>pt(Object.entries(n),([t,o])=>j(t)+U+(ge(o)?Be(o,e+1):De(o)))+je+e,"calcJsonToken"),wn=new Set([`
`,`\r
`,"[!NOTE]","[!IMPORTANT]","[!WARNING]","[!CAUTION]","\\[!NOTE]","\\[!IMPORTANT]","\\[!WARNING]","\\[!CAUTION]","\\[!NOTE]\\","\\[!IMPORTANT]\\","\\[!WARNING]\\","\\[!CAUTION]\\"]),bn=c(n=>wn.has(n)?!0:/^[\s\p{P}\p{S}\u{1F300}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}]*$/u.test(n.replaceAll(" ","")),"checkMdString"),Ge=c(async n=>we().use(wt).use(Se).use(ke).parse(n.trim()),"convertMarkdownToMdast"),An=c((n,e)=>{const t={};let o=0;return be(n,e||"text",r=>{t[o]=r.value,o++}),t},"convertMdastToMdastObj"),Mn=c(n=>{const e={};for(const[t,o]of Object.entries(n))bn(o)||(e[Number(t)]=o);return e},"pickMdastObj"),Tn=c(({mdast:n,entry:e,target:t},o)=>{const r={...e,...t};let i=0;return be(n,o||"text",s=>{s.value=r[i],i++}),n},"mergeMdastObj"),oe=c(async n=>we().use(bt,{bullet:"-",emphasis:"*",fences:!0,rule:"-",strong:"*",tightDefinitions:!0}).use(ke).use(Se).stringify(n).toString(),"convertMdastToMarkdown"),re=c((n,e)=>{const t=At(e,n),o=t.filter(a=>a.op==="add"),r=t.filter(a=>a.op==="remove"),i=gt(e),s={};for(const a of r)dt(i,a.path);for(const a of o)mt(s,a.path,a.value);return{add:o,entry:s,remove:r,target:i}},"diff"),vn=c((n,e)=>ht(Object.entries(n),(t,[o,r])=>{let[i,s]=t.pop()||[{},je];const a=ge(r)?Be(r,1):De(r);return s+j(o)+U+a<=e?(i[o]=r,s+=j(o)+U+a,t.push([i,s])):t.push([i,s],[{[o]:r},j(o)+U+a]),t},[]).map(([t])=>t),"splitJSONtoSmallChunks"),Ue=c((n,e)=>{let t=(Xt[n.modelName||Ne]-C(e))/3;return n.splitToken&&n.splitToken<t&&(t=n.splitToken),t=Math.floor(t),t},"getSplitToken"),Cn=c((n,e,t,o)=>{const r=re(e,t).entry,i=Ue(n,o);return vn(r,i)},"splitJsonToChunks");class ae{static{c(this,"RecursiveCharacterTextSplitter")}chunkSize;chunkOverlap;lengthFunction;separators;constructor(e){this.chunkSize=e.chunkSize,this.chunkOverlap=e.chunkOverlap,this.lengthFunction=e.lengthFunction||(t=>t.length),this.separators=[`
`,`
`," ",""]}static fromLanguage(e,t){const o=new ae(t);return e==="markdown"&&(o.separators=[`
## `,`
### `,`
#### `,`
##### `,`
###### `,`
`,`
`," ",""]),o}async splitText(e){return this.splitTextRecursively(e,this.separators)}splitTextRecursively(e,t){const o=[];let r=t.at(-1)||"",i=[];for(let u=0;u<t.length;u++){const f=t[u];if(f){if(f===""){r=f;break}if(e.includes(f)){r=f,i=t.slice(u+1);break}}}const s=this.splitTextWithSeparator(e,r);let a=[];const l=r===""?"":r;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);o.push(...f),a=[]}if(i.length===0)o.push(u);else{const f=this.splitTextRecursively(u,i);o.push(...f)}}if(a.length>0){const u=this.mergeSplits(a,l);o.push(...u)}return o}splitTextWithSeparator(e,t){let o;return t?o=e.split(t):o=e.split(""),o.filter(r=>r!=="")}mergeSplits(e,t){const o=[],r=[];let i=0;for(const a of e){const l=this.lengthFunction(a);if(i+l+(r.length>0?this.lengthFunction(t):0)>this.chunkSize&&(i>this.chunkSize&&console.warn(`Created a chunk of size ${i}, which is longer than the specified ${this.chunkSize}`),r.length>0)){const u=this.joinDocs(r,t);for(u!==null&&o.push(u);i>this.chunkOverlap||i+l+(r.length>0?this.lengthFunction(t):0)>this.chunkSize&&i>0;){const f=r[0];if(f)i-=this.lengthFunction(f)+(r.length>1?this.lengthFunction(t):0),r.shift();else break}}r.push(a),i+=l+(r.length>1?this.lengthFunction(t):0)}const s=this.joinDocs(r,t);return s!==null&&o.push(s),o}joinDocs(e,t){const o=e.join(t).trim();return o===""?null:o}}let Nn=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 Ge(e),this.entry=An(this.mdast,this.check),Mn(this.entry)}async genMarkdownByMdast(e){if(!e)return;const t=Tn({entry:this.entry,mdast:this.mdast,target:e},this.check);return oe(t)}async clearMarkdownString(e){const t=[],o=await Ge(e);return o.children=o.children.map(r=>r.type==="definition"?(t.push(r),!1):r).filter(Boolean),{content:await oe(o),definition:await oe({children:t,type:"root"})}}async genSplitMarkdown(e,t){this.definition="";const{content:o,definition:r}=await this.clearMarkdownString(e);return this.definition=r,await ae.fromLanguage("markdown",{chunkOverlap:0,chunkSize:Ue(this.config,t),lengthFunction:c(s=>C(s),"lengthFunction")}).splitText(o)}async genMarkdownByString(e){return[...e,this.definition].join(`
`)}};const se=c(n=>{const e=Me(n,"utf8");return JSON.parse(e)},"readJSON"),D=c((n,e)=>{const t=Mt(e,{space:" "});Ae(n,t+`\r
`,"utf8")},"writeJSON"),Ln=c(n=>Me(n,"utf8"),"readMarkdown"),ze=c((n,e)=>{Ae(n,e,"utf8")},"writeMarkdown"),En=c(n=>{let e={};for(const t of n)e=E(e,t);return e},"mergeJsonFromChunks");class z{static{c(this,"ChatPromptTemplate")}messages;constructor(e){this.messages=e}static fromMessages(e){const t=e.map(([o,r])=>({content:r,role:o}));return new z(t)}async formatMessages(e){return this.messages.map(t=>({content:this.formatString(t.content,e),role:t.role}))}formatString(e,t){let o=e;for(const[r,i]of Object.entries(t))if(i!==void 0){const s=new RegExp(`\\{${r}\\}`,"g");o=o.replace(s,i)}return o}}const Je="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.",In=c((n=Je)=>z.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. ---${n}---`,"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"),xn=c((n=Je)=>z.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. ---${n}---`,"Make sure the output remains a valid markdown file."].filter(Boolean).join(`
`)],["user","{text}"]]),"promptStringTranslate");let _n=class{static{c(this,"TranslateLocale")}client;config;isJsonMode;promptJson;promptString;constructor(e,t,o){this.config=e,this.client=new vt({apiKey:t,baseURL:o,maxRetries:4}),this.promptJson=In(e.reference),this.promptString=xn(e.reference),this.isJsonMode=!!this.config?.experimental?.jsonMode}async runByString({from:e,to:t,text:o}){try{const r=await this.promptString.formatMessages({from:e||this.config.entryLocale,text:o,to:t}),s=(await this.client.chat.completions.create({messages:r,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(r){this.handleError(r)}}async runByJson({from:e,to:t,json:o}){try{const r=await this.promptJson.formatMessages({from:e||this.config.entryLocale,json:JSON.stringify(o),to:t}),s=(await this.client.chat.completions.create({messages:r,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{A.warn("parse fail, try to use dirty json");try{return Tt.parse(s)}catch{A.error("i18n dirty json fail"),A.error(s,!0)}}}catch(r){this.handleError(r)}}handleError(e){A.error(`Translate failed, ${e||"please check your network or try again..."}`,!0)}};class Ke{static{c(this,"I18n")}config;maxStep=1;translateLocaleService;translateMarkdownService;constructor({openAIApiKey:e,openAIProxyUrl:t,config:o}){this.config=o,this.translateLocaleService=new _n(o,e,t),this.translateMarkdownService=new Nn(o)}async translateMarkdown(e){return e.mode===R.STRING?this.translateMarkdownByString(e):this.translateMarkdownByMdast(e)}async translateMarkdownByString({md:e,to:t,onProgress:o,from:r,filename:i,onChunkComplete:s}){const a=await this.translateLocaleService.promptString.formatMessages({from:r||this.config.entryLocale,text:"",to:t}),l=await this.translateMarkdownService.genSplitMarkdown(e,JSON.stringify(a));if(this.maxStep=l.length,l.length===0)return;const u=l.length*C(JSON.stringify(a))+C(JSON.stringify(l)),f=Array.from({length:this.maxStep},()=>0);let g="";const y=Array.from({length:this.maxStep},()=>""),m=c(()=>{const h=f.filter(b=>b===2).length,w=f.filter(b=>b===1).length;let k=0;if(h===this.maxStep)k=100;else if(w>0){const b=h/this.maxStep*100,J=(h+1)/this.maxStep*100;k=Math.floor(Math.max(b,J-1))}else k=Math.floor(h/this.maxStep*100);o?.({isLoading:h<this.maxStep,maxStep:this.maxStep,needToken:u,progress:k,step:h})},"updateProgress");o?.({isLoading:!0,maxStep:this.maxStep,needToken:u,progress:0,step:0});const v=await he(l,async(h,w)=>{f[w]=1,m(),setTimeout(()=>{m()},800);const k=await this.translateLocaleService.runByString({from:r||this.config.entryLocale,text:h,to:t});return f[w]=2,this.config.saveImmediately&&i&&(y[w]=k,(w===0||f.slice(0,w).every(b=>b===2))&&(g=await this.translateMarkdownService.genMarkdownByString(y.filter(Boolean)),ze(i,g),s?.(k,g))),m(),k},{concurrency:this.config?.concurrency});return o?.({isLoading:!1,maxStep:this.maxStep,needToken:u,progress:100,step:this.maxStep}),{result:this.config.saveImmediately&&g?g:await this.translateMarkdownService.genMarkdownByString(v),tokenUsage:u+C(JSON.stringify(v))}}async translateMarkdownByMdast({md:e,...t}){const o=await this.translateMarkdownService.genTarget(e),{matter:r,mode:i,onChunkComplete:s,...a}=t,l=await this.translate({...a,entry:o,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:t,to:o,onProgress:r,from:i,filename:s,onChunkComplete:a}){const l=await this.translateLocaleService.promptJson.formatMessages({from:i||this.config.entryLocale,json:JSON.stringify({}),to:o}),u=Cn(this.config,e,t,JSON.stringify(l));if(this.maxStep=u.length,u.length===0)return;const f=u.length*C(JSON.stringify(l))+C(JSON.stringify(u)),g=Array.from({length:this.maxStep},()=>0);let y=E({},t);const m=c(()=>{const h=g.filter(b=>b===2).length,w=g.filter(b=>b===1).length;let k=0;if(h===this.maxStep)k=100;else if(w>0){const b=h/this.maxStep*100,J=(h+1)/this.maxStep*100;k=Math.floor(Math.max(b,J-1))}else k=Math.floor(h/this.maxStep*100);r?.({isLoading:h<this.maxStep,maxStep:this.maxStep,needToken:f,progress:k,step:h})},"updateProgress");r?.({isLoading:!0,maxStep:this.maxStep,needToken:f,progress:0,step:0});const v=await he(u,async(h,w)=>{g[w]=1,m(),setTimeout(()=>{m()},800);const k=await this.translateLocaleService.runByJson({from:i||this.config.entryLocale,json:h,to:o});return g[w]=2,this.config.saveImmediately&&s&&(y=E(y,k),D(s,y),a?.(k,y)),m(),k},{concurrency:this.config?.concurrency});return r?.({isLoading:!1,maxStep:this.maxStep,needToken:f,progress:100,step:this.maxStep}),{result:s?y:await E(t,En(v)),tokenUsage:f+C(JSON.stringify(v))}}}const Pn=c(n=>{for(const e of n.outputLocales){const t=M(n.output,`${e}.json`);F(t)||D(t,{})}},"checkLocales"),Fn=c((n,e)=>{for(const t of n.outputLocales){const o=M(n.output,t);F(o)||Te(o)}for(const t of n.outputLocales)for(const o of e){const r=M(n.output,t,o);try{const i=kt(r);Te(i,{recursive:!0})}catch{}F(r)||D(r,{})}},"checkLocaleFolders"),He=c(n=>{try{const e=M("./",n.entry);return F(e)||A.error(`Can't find ${p.bold.yellow(n.entry)} in dir`,!0),se(e)}catch{Ct.exit(1)}},"getEntryFile"),Ve=c(n=>{const e=n.entry.replaceAll("*","").replaceAll("*.json",""),t=ve(de(e,"**/*.json").replaceAll("\\","/"),{nodir:!0}),o={};for(const r of t)o[V(e,r)]=se(r);if(Object.keys(o).length===0){A.error(`Can't find .json files in ${p.bold.yellow(e)}`,!0);return}return o},"getEntryFolderFiles");var Rn=Object.freeze({__proto__:null,getEntryFile:He,getEntryFolderFiles:Ve});const We=c(n=>{const e=se(n);return e||(D(n,{}),{})},"getLocaleObj"),ie=c((n,e)=>{try{if(n===e)return!0;if(typeof n!=typeof e)return!1;if(typeof n=="object"&&typeof e=="object"){const t=Object.keys(n),o=Object.keys(e);if(t.length!==o.length)return!1;for(const r of t)if(!o.includes(r)||!ie(n[r],e[r]))return!1}return typeof n==typeof e}catch{return!1}},"isEqualJsonKeys");class On{static{c(this,"TranslateLocale")}config;query=[];i18n;constructor(){this.config=T.getLocaleConfig(),this.i18n=new Ke({config:this.config,openAIApiKey:T.getOpenAIApiKey(),openAIProxyUrl:T.getOpenAIProxyUrl()})}async start(){d.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():d.success("No content requiring translation was found."),d.success("All i18n tasks have been completed\uFF01")}async runQuery(){d.info(`Current model setting: ${p.cyan(this.config.modelName)} (temperature: ${p.cyan(this.config.temperature)}) ${this.config.experimental?.jsonMode?p.red(" [JSON Mode]"):""}}`);let e=0;for(const t of this.query){const o={filename:t.filename,from:t.from||this.config.entryLocale,to:t.to},{rerender:r,clear:i}=H(S(G,{hide:!0,isLoading:!0,maxStep:1,progress:0,step:0,...o})),s=await this.i18n.translate({...t,filename:t.filename,onChunkComplete:c(()=>{},"onChunkComplete"),onProgress:c(l=>{l.maxStep>0?r(S(G,{...l,...o})):i()},"onProgress")});i();const a=V(".",t.filename);s?.result&&Object.keys(s.result).length>0?(this.config.saveImmediately||D(t.filename,s.result),e+=s.tokenUsage,d.success(p.yellow(a),p.gray(`[Token usage: ${s.tokenUsage}]`))):d.warn("No translation result was found:",p.yellow(a))}e>0&&d.info("Total token usage:",p.cyan(e))}genFolderQuery(){const e=this.config,t=Ve(e),o=Object.keys(t);d.info(`Running in ${p.bold.cyan("\u{1F4C2} Folder Mode")} and has found ${p.bold.cyan(o.length)} files.`),Fn(e,o);for(const r of e.outputLocales)for(const[i,s]of o.entries()){process.stdout.isTTY&&(process.stdout.clearLine(0),process.stdout.cursorTo(0)),process.stdout.write(`${p.cyan(r)}${p.gray(`[${i+1}/${o.length}] - `)}${p.yellow(s)}`);const a=M(e.output,r,s),l=t[s],u=re(l,We(a)).target;ie(l,u)||this.query.push({entry:l,filename:a,from:e.entryLocale,target:u,to:r})}process.stdout.isTTY&&(process.stdout.clearLine(0),process.stdout.cursorTo(0))}genFlatQuery(){const e=this.config,t=He(e);d.start(`Running in ${p.bold.cyan("\u{1F4C4} Flat Mode")}, and translating ${p.bold.cyan(e.outputLocales.join("/"))} locales..`),Pn(e);for(const o of e.outputLocales){const r=M(e.output,o)+".json",i=t,s=re(i,We(r)).target;ie(i,s)||this.query.push({entry:i,filename:r,from:e.entryLocale,target:s,to:o})}}}const qe=c((n,e)=>n.map(t=>t.includes("*")||t.includes(e)?t:de(t,`**/*${e}`).replaceAll("\\","/")),"matchInputPattern");class Qe{static{c(this,"TranslateMarkdown")}config;markdownConfig;query=[];i18n;constructor(){this.markdownConfig=T.getMarkdownConfigFile();const e=T.getConfigFile();this.config={...e,entryLocale:e.entryLocale||this.markdownConfig.entryLocale,markdown:this.markdownConfig,outputLocales:e.outputLocales||this.markdownConfig.outputLocales},this.i18n=new Ke({config:this.config,openAIApiKey:T.getOpenAIApiKey(),openAIProxyUrl:T.getOpenAIProxyUrl()})}async start(){d.start("Lobe I18N is analyzing your markdown... \u{1F92F}\u{1F30F}\u{1F50D}");const e=this.markdownConfig.entry;(!e||e.length===0)&&A.error("No markdown entry was found.",!0);let t=ve(qe(e,".md"),{ignore:this.markdownConfig.exclude?qe(this.markdownConfig.exclude||[],".md"):void 0,nodir:!0});this.markdownConfig.entryExtension&&(t=t.filter(o=>o.includes(this.markdownConfig.entryExtension||".md"))),(!t||t.length===0)&&A.error("No markdown entry was found.",!0),this.genFilesQuery(t),this.query.length>0?await this.runQuery():d.success("No content requiring translation was found."),d.success("All i18n tasks have been completed\uFF01")}async runQuery(){d.info(`Current model setting: ${p.cyan(this.config.modelName)} (temperature: ${p.cyan(this.config.temperature)}) ${this.config.experimental?.jsonMode?p.red(" [JSON Mode]"):""}}`);let e=0;for(const t of this.query){const o={filename:t.filename,from:t.from||this.markdownConfig.entryLocale||this.config.entryLocale,to:t.to},{rerender:r,clear:i}=H(S(G,{hide:!0,isLoading:!0,maxStep:1,progress:0,step:0,...o})),s=await this.i18n.translateMarkdown({...t,onProgress:c(l=>{l.maxStep>0?r(S(G,{...l,...o})):i()},"onProgress")});i();const a=V(".",t.filename);if(s?.result&&Object.keys(s.result).length>0){let l=s.result;this.markdownConfig.includeMatter||(l=Ce.stringify(s.result,t.matter)),this.config.saveImmediately||ze(t.filename,l),e+=s.tokenUsage,d.success(p.yellow(a),p.gray(`[Token usage: ${s.tokenUsage}]`))}else d.warn("No translation result was found:",p.yellow(a))}e>0&&d.info("Total token usage:",p.cyan(e))}genFilesQuery(e,t){const o=this.markdownConfig;t||d.start(`Running in ${p.bold.cyan(`\u{1F4C4} ${e.length} Markdown`)}, and translating to ${p.bold.cyan(o?.outputLocales?.join("/"))} locales..`);for(const r of e)try{const i=Ln(r);for(const s of o.outputLocales||[]){const a=this.getTargetExtension(s,r,i),l=this.getTargetFilename(r,a);if(F(l))continue;const u=this.getMode(r,i),{data:f,content:g}=Ce(i);d.info(`\u{1F4C4} To ${s}: ${p.yellow(l)}`),this.query.push({filename:l,from:o.entryLocale,matter:f,md:this.markdownConfig.includeMatter?i:g,mode:u,to:s})}}catch(i){d.error(`Error processing file ${r}:`,i),A.error(`${r} not found`,!0)}}getTargetExtension(e,t,o){return this.markdownConfig.outputExtensions?.(e,{fileContent:o,filePath:t,getDefaultExtension:q})||q(e)}getTargetFilename(e,t){if(this.markdownConfig.entryExtension)return M(".",e.replace(this.markdownConfig.entryExtension||".md",t));if(this.markdownConfig.entryLocale&&e.includes(`.${this.markdownConfig.entryLocale}.`))return[e.split(`.${this.markdownConfig.entryLocale}.`)[0],t].join("");{const o=e.split(".");return o.pop(),[o.join("."),t].join("")}}getMode(e,t){const o=this.markdownConfig.mode;return o?yt(o)?o:o({fileContent:t,filePath:e})||R.STRING:R.STRING}}const $n=it({pkg:W,shouldNotifyInNpmScript:!0});$n.notify({isGlobal:!0});const N=new st;N.name("lobe-i18n").description(W.description).version(W.version).addOption(new _("-o, --option","Setup lobe-i18n preferences")).addOption(new _("-c, --config <string>","Specify the configuration file")).addOption(new _("-m, --with-md","Run i18n translation and markdown translation simultaneously")).addOption(new _("--lint","Lint translation files for language correctness")).addOption(new _("--quiet","Only show errors, suppress warnings")),N.command("locale",{isDefault:!0}).action(async()=>{const n=N.opts();n.option?H(S(cn,{})):n.lint?(n.config&&O.loadCustomConfig(n.config),await new $e().start(n.quiet)):(n.config&&O.loadCustomConfig(n.config),await new On().start(),n.withMd&&await new Qe().start())}),N.command("md").action(async()=>{const n=N.opts();n.config&&O.loadCustomConfig(n.config),await new Qe().start()}),N.command("lint").action(async()=>{const n=N.opts();n.config&&O.loadCustomConfig(n.config),await new $e().start(n.quiet)}),N.parse();