@llmnative/react 1.19.1 → 1.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.css +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/llms-full.txt +1140 -0
- package/llms.txt +82 -0
- package/package.json +6 -2
- package/scripts/cli/setup-project.js +60 -36
- package/templates/_shared/layouts/Default.tsx +23 -0
- package/templates/_shared/sections/Footer.tsx +9 -0
- package/templates/_shared/sections/Header.tsx +24 -0
- package/templates/_shared/sections/PageHeader.tsx +10 -0
- package/templates/_shared/sections/Sidebar.tsx +22 -0
- package/templates/admin/conf/menu.ts +14 -0
- package/templates/admin/data/mockData.ts +21 -0
- package/templates/admin/pages/home/HomePage.tsx +32 -0
- package/templates/admin/pages/roles/RolesPage.tsx +25 -0
- package/templates/admin/pages/settings/SettingsPage.tsx +24 -0
- package/templates/admin/pages/users/UsersPage.tsx +54 -0
- package/templates/blank/conf/menu.ts +8 -0
- package/templates/blank/data/mockData.ts +6 -0
- package/templates/blank/pages/home/HomePage.tsx +25 -0
- package/templates/crm/conf/menu.ts +14 -0
- package/templates/crm/data/mockData.ts +24 -0
- package/templates/crm/pages/companies/CompaniesPage.tsx +42 -0
- package/templates/crm/pages/contacts/ContactsPage.tsx +48 -0
- package/templates/crm/pages/deals/DealsPage.tsx +61 -0
- package/templates/crm/pages/home/HomePage.tsx +35 -0
- package/templates/inventory/conf/menu.ts +12 -0
- package/templates/inventory/data/mockData.ts +16 -0
- package/templates/inventory/pages/categories/CategoriesPage.tsx +23 -0
- package/templates/inventory/pages/home/HomePage.tsx +35 -0
- package/templates/inventory/pages/products/ProductsPage.tsx +56 -0
- package/templates/project/conf/menu.ts +14 -0
- package/templates/project/data/mockData.ts +21 -0
- package/templates/project/pages/home/HomePage.tsx +33 -0
- package/templates/project/pages/projects/ProjectsPage.tsx +50 -0
- package/templates/project/pages/tasks/TasksPage.tsx +67 -0
- package/templates/project/pages/team/TeamPage.tsx +25 -0
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
16
16
|
`):void 0};let i=n.join(`
|
|
17
17
|
`);return i?{type:`text`,text:i}:null}var om={id:`anthropic`,label:`Anthropic`,description:`Claude models via the Anthropic API.`,configKey:`anthropicApiKey`,defaultModel:`claude-sonnet-4-0`,fallbackModels:[`claude-sonnet-4-0`,`claude-opus-4-1`,`claude-3-7-sonnet-latest`],dashboardUrl:`https://console.anthropic.com/settings/keys`,credentialsHint:`Anthropic Console → Settings → API Keys → Create Key.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},discoverModels:async e=>{let t=await xe(tm,{headers:{"x-api-key":e,"anthropic-version":`2023-06-01`}},zs);return Array.isArray(t?.data)?t.data.map(e=>e.id).filter(Boolean):[]},complete:async(t,n)=>{let r=n.attachments??[],i=r.length>0?[...r.map(e=>e.mimeType.startsWith(`image/`)?{type:`image`,source:{type:`base64`,media_type:e.mimeType,data:e.base64}}:hc.isTextAttachment(e.mimeType)?{type:`text`,text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{type:`document`,source:{type:`base64`,media_type:e.mimeType,data:e.base64}}),{type:`text`,text:n.prompt}]:n.prompt;return am(await xe(nm,{method:`POST`,headers:{"x-api-key":t,"anthropic-version":`2023-06-01`,...n.logId?{[e.t]:n.logId}:{}},body:{model:n.model,max_tokens:4096,...n.role?{system:Ds.parseRole(n.role,n)}:{},messages:[...(n.history??[]).map(im),...n.prompt?[{role:`user`,content:i}]:[]],...n.tools?.length?{tools:n.tools.map(rm)}:{},...typeof n.temperature==`number`?{temperature:n.temperature}:{}},signal:n.signal},zs))}},sm=e=>typeof e.id==`string`?e.id:void 0,cm=e=>e.replace(/\/+$/,``);function lm(e){return{type:`function`,function:{name:e.name,description:e.description,parameters:e.inputSchema}}}function um(e){if(typeof e!=`string`)return{};try{return JSON.parse(e)}catch{return{}}}function dm(e){return e.role===`user`?[{role:`user`,content:e.content}]:e.role===`assistant`?[{role:`assistant`,content:e.content??null,...e.toolCalls?.length?{tool_calls:e.toolCalls.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.input)}}))}:{}}]:e.results.map(e=>({role:`tool`,tool_call_id:e.toolCallId,content:typeof e.output==`string`?e.output:JSON.stringify(e.output)}))}function fm(e){let t=e?.choices?.[0]?.message;if(!t)return null;let n=Array.isArray(t.tool_calls)?t.tool_calls:[];if(n.length>0){let e=typeof t.content==`string`?t.content:void 0;return{type:`tool_calls`,toolCalls:n.map(e=>{let t=e.function??{};return{id:String(e.id),name:String(t.name??``),input:um(t.arguments)}}),text:e||void 0}}let r=ic(t.content);return r?{type:`text`,text:r}:null}var pm=({id:t,label:n,description:r,configKey:i,requiredConfigKeys:a,defaultModel:o,fallbackModels:s,baseUrl:c,modelsUrl:l,chatCompletionsUrl:u,dashboardUrl:d,credentialsHint:f,validateApiKey:p,mapModelEntry:m=sm})=>{let h=cm(c),g=l||`${h}/models`,_=u||`${h}/chat/completions`;return{id:t,label:n,description:r,configKey:i,requiredConfigKeys:a,defaultModel:o,fallbackModels:s,dashboardUrl:d,credentialsHint:f,credentialFields:t===`openai-compatible`?[{key:`apiKey`,label:`API Key`,type:`password`},{key:`baseUrl`,label:`Base URL`,type:`text`,placeholder:`https://api.example.com/v1`}]:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},validateApiKey:p??(async e=>{try{let t=await xe(g,{headers:{Authorization:`Bearer ${e}`}},zs);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o proxy non attivo)`}:typeof t?.message==`string`&&!Array.isArray(t?.data)?{valid:!1,error:t.message}:{valid:!0}}catch(e){return{valid:!1,error:nc(e)}}}),discoverModels:async e=>{let t=await xe(g,{headers:{Authorization:`Bearer ${e}`}},zs);return Array.isArray(t?.data)?t.data.map(e=>m(e??{})).filter(e=>!!e):[]},complete:async(t,r)=>{let i=r.attachments??[],a=i.length>0?i.map(e=>e.mimeType.startsWith(`image/`)?{type:`image_url`,image_url:{url:`data:${e.mimeType};base64,${e.base64}`}}:hc.isTextAttachment(e.mimeType)?{type:`text`,text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{type:`text`,text:`[File attached: ${e.name} (${e.mimeType})]`}).concat({type:`text`,text:r.prompt}):r.prompt,o=await xe(_,{method:`POST`,headers:{Authorization:`Bearer ${t}`,...r.logId?{[e.t]:r.logId}:{}},body:{model:r.model,messages:[...r.role?[{role:`system`,content:Ds.parseRole(r.role,r)}]:[],...(r.history??[]).flatMap(dm),...r.prompt?[{role:`user`,content:a}]:[]],...r.tools?.length?{tools:r.tools.map(lm)}:{},...typeof r.temperature==`number`?{temperature:r.temperature}:{}},signal:r.signal},zs);if(!o)throw rc(n);return fm(o)}}},mm=`https://api.cloudflare.com/client/v4`,hm=100,gm=5,_m=/-guard-/,vm=`Cloudflare Workers AI`,ym=`Open-weight models (Llama, GPT-OSS, Qwen, Gemma, GLM…) with a free daily allowance.`,bm=`https://dash.cloudflare.com/?to=/:account/ai/workers-ai`,xm=`Cloudflare dashboard → AI → Workers AI → REST API: create a Workers AI API token and copy the Account ID.`,Sm=[{key:`apiKey`,label:`API Token`,type:`password`},{key:`accountId`,label:`Account ID`,type:`text`,placeholder:`32-character account id`}],Cm=(e,t)=>(e.properties??[]).some(e=>e.property_id===t&&String(e.value)===`true`),wm=e=>{let t=(e.properties??[]).find(e=>e.property_id===`price`)?.value;if(!Array.isArray(t))return;let n=e=>{let n=t.find(t=>typeof t?.unit==`string`&&t.unit.toLowerCase().includes(e));return n&&(n.currency===void 0||n.currency===`USD`)?Number(n.price):NaN},r=n(`input`),i=n(`output`);if(Number.isFinite(r)&&Number.isFinite(i))return{input:r,output:i,currency:`USD`,source:`provider`}},Tm=e=>e?.map(e=>e.role===`assistant`&&!e.content?{...e,content:``}:e),Em=({accountId:e,defaultModel:t=`@cf/meta/llama-3.3-70b-instruct-fp8-fast`,includePaidModels:n=!1})=>{let r=`${mm}/accounts/${encodeURIComponent(e.trim())}`,i=`${r}/ai/models/search`,a=(e,t,n)=>{let r=new URLSearchParams({task:`Text Generation`,hide_experimental:`true`,page:String(t),per_page:String(n)});return xe(`${i}?${r}`,{headers:{Authorization:`Bearer ${e}`}},zs)},o=pm({id:`cloudflare`,label:vm,description:ym,configKey:`cloudflare`,requiredConfigKeys:[`ai.cloudflare.apiToken`,`ai.cloudflare.accountId`],defaultModel:t,fallbackModels:[t,`@cf/openai/gpt-oss-120b`,`@cf/qwen/qwen3-30b-a3b-fp8`,`@cf/meta/llama-4-scout-17b-16e-instruct`].filter((e,t,n)=>n.indexOf(e)===t),baseUrl:`${r}/ai/v1`,dashboardUrl:bm,credentialsHint:xm,validateApiKey:async e=>{try{let t=await a(e,1,1);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o proxy non attivo)`}:t.success?{valid:!0}:{valid:!1,error:nc(t)}}catch(e){return{valid:!1,error:nc(e)}}}});return{...o,credentialFields:Sm,discoverModels:async e=>{let t=[];for(let r=1;r<=gm;r++){let i=await a(e,r,hm),o=Array.isArray(i?.result)?i.result:[];if(o.filter(e=>!_m.test(e.name??``)).filter(e=>n||!Cm(e,`require_workers_paid`)).forEach(e=>{e.name&&t.push({model:e.name,pricing:wm(e)})}),o.length<hm)break}return t},complete:(e,t)=>o.complete(e,{...t,history:Tm(t.history)})}},Dm={id:`cloudflare`,label:vm,description:ym,credentialFields:Sm,credentialsUrl:bm,credentialsHint:xm},Om=pm({id:`deepseek`,label:`DeepSeek`,description:`Cost-efficient reasoning and chat models.`,configKey:`deepSeekApiKey`,defaultModel:`deepseek-chat`,fallbackModels:[`deepseek-chat`,`deepseek-reasoner`],baseUrl:`https://api.deepseek.com`,dashboardUrl:`https://platform.deepseek.com/api_keys`,credentialsHint:`DeepSeek platform → API Keys → Create new API key.`}),km=`https://generativelanguage.googleapis.com/v1beta/models`,Am=`https://generativelanguage.googleapis.com/v1beta/models`;function jm(e){return[{function_declarations:e.map(e=>({name:e.name,description:e.description,parameters:e.inputSchema}))}]}function Mm(e){if(e.role===`user`)return{role:`user`,parts:[{text:e.content}]};if(e.role===`assistant`){let t=[];e.content&&t.push({text:e.content});for(let n of e.toolCalls??[])t.push({functionCall:{name:n.name,args:n.input}});return{role:`model`,parts:t}}return{role:`function`,parts:e.results.map(e=>({functionResponse:{name:e.name,response:{result:e.output}}}))}}function Nm(e){let t=e?.candidates?.[0]?.content?.parts;if(!Array.isArray(t))return null;let n=t.filter(e=>typeof e?.text==`string`).map(e=>e.text),r=t.filter(e=>e?.functionCall);if(r.length>0)return{type:`tool_calls`,toolCalls:r.map(e=>({id:`${e.functionCall.name}-${crypto.randomUUID()}`,name:e.functionCall.name,input:e.functionCall.args??{}})),text:n.length?n.join(`
|
|
18
18
|
`).trim():void 0};let i=n.join(`
|
|
19
|
-
`).trim();return i?{type:`text`,text:i}:null}var Pm={id:`gemini`,label:`Gemini`,description:`Google's multimodal Gemini model family.`,configKey:`geminiApiKey`,defaultModel:`gemini-2.5-pro`,fallbackModels:[`gemini-2.5-pro`,`gemini-2.5-flash`,`gemini-2.5-flash-lite`],dashboardUrl:`https://aistudio.google.com/app/apikey`,credentialsHint:`Google AI Studio → Get API key → Create API key.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},discoverModels:async e=>{let t=await xe(`${km}?key=${e}`,null,zs);return Array.isArray(t?.models)?t.models.map(e=>e.name?.replace(/^models\//,``)).filter(Boolean):[]},validateApiKey:async e=>{try{let t=await xe(`${km}?key=${e}`,null,zs);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o rete)`}:t?.error?{valid:!1,error:typeof t.error==`object`&&`message`in t.error?String(t.error.message):String(t.error)}:{valid:!0}}catch(e){let t=e;return{valid:!1,error:t?.error&&typeof t.error==`object`?String(t.error.message??e):String(e)}}},complete:async(t,n)=>{let r=[...(n.attachments??[]).map(e=>hc.isTextAttachment(e.mimeType)?{text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{inline_data:{mime_type:e.mimeType,data:e.base64}}),{text:n.prompt}];return Nm(await xe(`${Am}/${n.model}:generateContent?key=${t}`,{method:`POST`,headers:n.logId?{[e.t]:n.logId}:void 0,body:{contents:[...(n.history??[]).map(Mm),...n.prompt?[{role:`user`,parts:r}]:[]],...n.role?{systemInstruction:{parts:[{text:Ds.parseRole(n.role,n)}]}}:{},...n.tools?.length?{tools:jm(n.tools)}:{},generationConfig:typeof n.temperature==`number`?{temperature:n.temperature}:void 0},signal:n.signal},zs))}},Fm=pm({id:`mistral`,label:`Mistral`,description:`European-hosted open and commercial language models.`,configKey:`mistralApiKey`,defaultModel:`mistral-medium-3`,fallbackModels:[`mistral-medium-3`,`mistral-small-3.1`,`ministral-8b-latest`],baseUrl:`https://api.mistral.ai/v1`,dashboardUrl:`https://console.mistral.ai/api-keys`,credentialsHint:`Mistral Console → API Keys → Create new key.`}),Im=/whisper|orpheus|tts|guard/i,Lm=pm({id:`groq`,label:`Groq`,description:`Very fast inference on open-weight models, with a free tier.`,configKey:`groqApiKey`,defaultModel:`openai/gpt-oss-120b`,fallbackModels:[`openai/gpt-oss-120b`,`openai/gpt-oss-20b`],baseUrl:`https://api.groq.com/openai/v1`,dashboardUrl:`https://console.groq.com/keys`,credentialsHint:`Groq Console → API Keys → Create API Key.`,mapModelEntry:e=>typeof e.id==`string`&&e.active!==!1&&!Im.test(e.id)?e.id:void 0}),Rm=pm({id:`openai`,label:`OpenAI`,description:`GPT models via the OpenAI API.`,configKey:`openaiApiKey`,defaultModel:`gpt-5.2`,fallbackModels:[`gpt-5.2`,`gpt-5`,`gpt-5-mini`,`gpt-5-nano`,`gpt-4.1`,`gpt-4.1-mini`,`gpt-4.1-nano`],baseUrl:`https://api.openai.com/v1`,dashboardUrl:`https://platform.openai.com/api-keys`,credentialsHint:`OpenAI dashboard → API keys → Create new secret key.`}),zm=`https://opencode.ai/zen/v1/models`,Bm=`https://opencode.ai/zen/v1/chat/completions`,Vm=`deepseek-v4.1-flash`,Hm=[Vm,`deepseek-v4-pro`,`glm-5.3`,`glm-5.3-flash`,`grok-build-0.1`,`kimi-k3`,`minimax-m3`,`qwen3.8-flash`],Um=/-free$/,Wm=new Set([`big-pickle`]),Gm=e=>Um.test(e)||Wm.has(e),Km={id:`opencode`,label:`OpenCode`,description:`OpenCode Zen — a curated set of coding-focused models.`,configKey:`openCodeApiKey`,defaultModel:Vm,fallbackModels:Hm,dashboardUrl:`https://opencode.ai`,credentialsHint:`OpenCode Zen dashboard → API Keys → Create Key.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},discoverModels:async e=>{let t=await xe(zm,{headers:{Authorization:`Bearer ${e}`}},zs);return(Array.isArray(t?.data)?t.data:Array.isArray(t?.models)?t.models:Array.isArray(t)?t:[]).map(e=>e.id).filter(e=>typeof e==`string`&&e.length>0).filter(e=>!Gm(e))},complete:async(t,n)=>{let r=n.attachments??[],i=r.length>0?r.map(e=>e.mimeType.startsWith(`image/`)?{type:`image_url`,image_url:{url:`data:${e.mimeType};base64,${e.base64}`}}:hc.isTextAttachment(e.mimeType)?{type:`text`,text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{type:`text`,text:`[File attached: ${e.name} (${e.mimeType})]`}).concat({type:`text`,text:n.prompt}):n.prompt,a=await xe(Bm,{method:`POST`,headers:{Authorization:`Bearer ${t}`,...n.logId?{[e.t]:n.logId}:{}},body:{model:n.model,messages:[...n.role?[{role:`system`,content:Ds.parseRole(n.role,n)}]:[],...(n.history??[]).flatMap(dm),...n.prompt?[{role:`user`,content:i}]:[]],...n.tools?.length?{tools:n.tools.map(lm)}:{},...typeof n.temperature==`number`?{temperature:n.temperature}:{}},signal:n.signal},zs);if(!a)throw rc(`OpenCode`);return fm(a)}},qm=e=>{if(!e||typeof e!=`object`)return;let{prompt:t,completion:n}=e,r=Number(t),i=Number(n);if(t===void 0||n===void 0||!Number.isFinite(r)||!Number.isFinite(i)||r<0||i<0)return;let a=e=>Math.round(e*0xe8d4a51000)/1e6;return{input:a(r),output:a(i),currency:`USD`,source:`provider`}},Jm=pm({id:`openrouter`,label:`OpenRouter`,description:`Unified access to many model providers through one API.`,configKey:`openRouterApiKey`,defaultModel:`openai/gpt-4`,fallbackModels:[`openai/gpt-4`,`openai/gpt-5-nano`,`anthropic/claude-3.7-sonnet`],baseUrl:`https://openrouter.ai/api/v1`,dashboardUrl:`https://openrouter.ai/settings/keys`,credentialsHint:`OpenRouter → Settings → API Keys → Create Key.`,mapModelEntry:e=>typeof e.id==`string`?{model:e.id,pricing:qm(e.pricing)}:void 0,validateApiKey:async e=>{try{let t=await xe(`https://openrouter.ai/api/v1/auth/key`,{headers:{Authorization:`Bearer ${e}`}},zs);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o proxy non attivo)`}:t?.data?.label!==void 0||t?.data?.usage!==void 0?{valid:!0}:t?.error?{valid:!1,error:nc(t)}:{valid:!1,error:`Chiave non riconosciuta da OpenRouter`}}catch(e){return{valid:!1,error:nc(e)}}}}),Ym={dbRealtime:{service:`data`,create:()=>new Rp},firestoreDb:{service:`data`,create:()=>new Ti},firestorage:{service:`storage`,create:()=>new Zi},firebaseAuth:{service:`auth`,create:()=>new Hp}},Xm={googleAuth:{service:`auth`,create:()=>new yp},gmail:{service:`email`,create:()=>new Qp},googleServiceAccount:{service:`credentials`,create:e=>new qp(e.serviceAccount),when:e=>!!e.serviceAccount}},Zm={dropboxAuth:{service:`auth`,create:e=>new Yp(e)}},Qm={supabaseDb:{service:`data`,create:e=>new Ri(e)},supabaseStorage:{service:`storage`,create:e=>new Qi(e)},supabaseAuth:{service:`auth`,create:e=>new em(e)}},$m={mock:{service:`data`,create:e=>new Gi(e?.data)}},eh=(e,t)=>({service:`ai`,create:n=>new lc(e,n?.[t]||``),when:e=>!!e?.[t]}),th={firebase:Ym,google:Xm,dropbox:Zm,supabase:Qm,mock:$m,ai:{openai:eh(Rm,`openaiApiKey`),openrouter:eh(Jm,`openRouterApiKey`),opencode:eh(Km,`openCodeApiKey`),deepseek:eh(Om,`deepSeekApiKey`),gemini:eh(Pm,`geminiApiKey`),anthropic:eh(om,`anthropicApiKey`),mistral:eh(Fm,`mistralApiKey`),groq:eh(Lm,`groqApiKey`),cloudflare:{service:`ai`,create:e=>new lc(Em({accountId:e?.cloudflare?.accountId?.trim()||``,defaultModel:e?.cloudflare?.defaultModel?.trim()||void 0,includePaidModels:e?.cloudflare?.includePaidModels}),e?.cloudflare?.apiToken?.trim()||``),when:e=>!!e?.cloudflare?.apiToken?.trim()&&!!e?.cloudflare?.accountId?.trim()}}},nh=()=>t.default.createElement(`div`,{className:`flex min-h-[calc(100vh-4rem)] items-center justify-center`},t.default.createElement(`div`,{className:`h-8 w-8 animate-spin rounded-full border-2 border-muted border-t-primary`}));function rh(e,t){if(!t)return;let n=t,r=typeof t==`object`&&!Array.isArray(t)?Object.entries(n):[];if(r.length>0&&r.every(([,e])=>typeof e==`object`&&!!e)){Object.assign(e,n);return}e.custom=t}function ih(e,t,n=`default`){return t&&e[t]?t:Object.keys(e)[0]??n}function ah(e={}){let t={data:{},storage:{},auth:{},email:{},ai:{},credentials:{}},n=e=>t[e]??={};for(let[t,r]of Object.entries(th)){let i=e[t];if(i!==void 0)for(let[e,t]of Object.entries(r))(!t.when||t.when(i))&&(n(t.service)[e]=t.create(i))}for(let[t,r]of Object.entries(e.custom??{}))rh(n(t),r);Object.keys(t.data).length===0&&(t.data.mock=new Gi),Object.keys(t.auth).length===0&&(t.auth.googleAuth=new yp);let r=e.services??{},i={};for(let[e,n]of Object.entries(t))i[e]={registry:n,defaultKey:ih(n,r[e])};return i}var oh={},sh=e=>{oh=e},ch=e=>oh[e]||[];function lh({contextProviders:e,providers:r={},appName:i=`LLM Native`,scrapeConfig:a,iconProvider:o,googleMaps:s,themeProvider:c,i18n:l,children:u,errorReportUrl:d,debug:f,basename:p}){let[m,h]=(0,t.useState)(()=>ah(r)),g=(0,t.useRef)(m);g.current=m;let _=(0,t.useRef)(void 0);_.current||=(async(e,t,n)=>{let r=g.current[e]?.registry?.[t];r!==n&&(await r?.dispose?.(),h(r=>({...r,[e]:{defaultKey:r[e]?.defaultKey??t,registry:{...r[e]?.registry,[t]:n}}})))});let v=_.current,y=e??t.default.Fragment;return t.default.createElement(_p,{fullPage:!0,reportUrl:d,debug:f},t.default.createElement(n.BrowserRouter,{basename:p},t.default.createElement(ti,{defaultConfig:{title:i,firebase:r.firebase,google:r.google?{oAuth2:{clientId:r.google.clientId,scope:r.google.scope},serviceAccount:r.google.serviceAccount,developerToken:r.google.developerToken}:void 0,dropbox:r.dropbox,ai:r.ai,scrape:a,proxy:r.proxy}},t.default.createElement(Kr,{registries:m,setProvider:v},t.default.createElement(jn,m.auth,t.default.createElement(wp,m.credentials,t.default.createElement(er,m.data,t.default.createElement(Vo,m.storage,t.default.createElement(xp,m.email,t.default.createElement(Ms,m.ai,t.default.createElement(Zt,{config:o},t.default.createElement(fd,{config:s},t.default.createElement(Cf,{appName:i},t.default.createElement(lt,{config:l},t.default.createElement(Xe,{config:c},t.default.createElement(y,null,u))))))))))))))))}function uh({importPage:e,LayoutDefault:r=void 0,menuConfig:i={},children:a,...o}){sh(i);let s=({children:e})=>t.default.createElement(t.default.Fragment,null,e),c=({pageSource:e,message:n})=>t.default.createElement(da,{variant:`warning`},`Missing Page: `,e,n&&t.default.createElement(`code`,{className:`ml-2`},n));function l(i,a,l){let u=`./pages${a.component?`/`+a.component:a.path===`/`?`/Home`:T.toCamel(a.path.split(`*`)[0])}.js`,d=a.page||t.default.lazy(()=>e(u).then(e=>typeof e.default==`function`?{default:e.default}:(console.warn(`⚠️ Invalid default export in ${u}`),{default:()=>t.default.createElement(c,{pageSource:u})})).catch(e=>(console.error(`❌ Failed to load ${u}:`,e),{default:()=>t.default.createElement(c,{pageSource:u,message:e.message})}))),f=a.layout||r||s;return t.default.createElement(n.Route,{key:`${i}-${l}`,path:a.path,element:t.default.createElement(f,null,t.default.createElement(_p,{key:a.path,reportUrl:o.errorReportUrl,debug:o.debug},t.default.createElement(t.Suspense,{fallback:t.default.createElement(nh,null)},t.default.createElement(d,null))))})}let u=e=>Object.keys(e).flatMap(t=>e[t].flatMap((e,n)=>[e.path&&l(t,e,n),e.children&&u({children:e.children})].filter(Boolean)));return t.default.createElement(lh,o,a,t.default.createElement(n.Routes,null,t.default.createElement(n.Route,{path:Rn,element:t.default.createElement(Gn,null)}),t.default.createElement(t.default.Fragment,null,u({default:[{path:`/`}],...oh,_auth:[{path:`/users`,page:cp,layout:r}]})),t.default.createElement(n.Route,{path:`*`,element:t.default.createElement(lp,null)})))}var dh=e=>{let r=ch(e),i=(0,n.useLocation)(),a=e=>e.map(e=>{let t=i.pathname===e.path,n=e.children?a(e.children):[],r=t||n.some(e=>e.active);return{...e,active:r,children:n}});return(0,t.useMemo)(()=>a(r),[i.pathname])},fh={common:{save:`Salva`,cancel:`Annulla`,delete:`Elimina`,close:`Chiudi`,back:`Indietro`,search:`Cerca`,loading:`Caricamento...`,noDataFound:`Nessun dato trovato`,pageNavigation:`Navigazione pagine`,previous:`Precedente`,next:`Successivo`,notFoundMessage:`Ops! Pagina non trovata.`,goHome:`Vai alla Home`},auth:{signIn:`Accedi`,signOut:`Esci`,connect:`Connetti`,connected:`Connesso`,authenticated:`Autenticato`,notConfigured:`Il provider auth "{provider}" non è configurato. Controlla le chiavi API.`,notImplemented:`Il provider non implementa signIn().`},form:{headerAdd:`Aggiungi`,headerEdit:`Modifica`,buttonSave:`Salva`,buttonDelete:`Elimina`,buttonBack:`Indietro`,requiredField:`Il campo "{field}" è obbligatorio`,requiredFieldGeneric:`I campi obbligatori non sono compilati`,saveSuccess:`Salvato con successo`,deleteSuccess:`Eliminato con successo`,noticeRequiredFields:`Completa i campi obbligatori prima di salvare.`},grid:{buttonAdd:`Aggiungi`,deleteConfirm:`Sei sicuro di voler eliminare questo elemento?`,emptyState:`Nessun elemento da mostrare`,filtersButton:`Filtri`,filtersPanelTitle:`Filtri`,filtersClearAll:`Cancella tutti`,filtersSelectPlaceholder:`Tutti`,filtersRangeFrom:`Da`,filtersRangeTo:`A`,filtersRangeMin:`Min`,filtersRangeMax:`Max`,filtersSelectedCountTemplate:`{count} selezionati`},select:{placeholder:`Seleziona...`,loading:`Caricamento...`},modal:{save:`Salva`,delete:`Elimina`,cancel:`Annulla`,close:`Chiudi`,ok:`Ok`,yes:`Sì`,no:`No`},upload:{clickOrDrag:`Clicca o trascina per caricare...`,dropToUpload:`Rilascia per caricare`,uploadMore:`Aggiungi altri file`,editFileName:`Modifica nome file`,editorImage:`Editor immagine`,loaded:`Caricato`,removeFile:`Rimuovi`,uploadAnother:`Carica un altro file`,dropToParse:`Rilascia per analizzare`,insertFromUrl:`Inserisci da URL`,urlPlaceholder:`https://…/immagine.png`,invalidUrl:`Inserisci un URL valido`},notifications:{title:`Notifiche`,seeAll:`Vedi tutte`},code:{copyCode:`Copia codice`,copy:`Copia`,copied:`Copiato!`,codeLanguageDefault:`Testo`},table:{noDataFound:`Nessun dato trovato`,selectAllRows:`Seleziona tutte le righe`,sortBy:`Ordina per {label}`,sortByCurrent:`Ordina per {label} ({direction})`,selectRow:`Seleziona riga {key}`,reorderRow:`Riordina riga {key}`},gallery:{selectItem:`Seleziona elemento {key}`},crop:{enableCrop:`Abilita ritaglio a scala {scale}`,variants:`Varianti`,outputFile:`File di output`,active:`Attivo`,removeVariant:`Rimuovi variante {scale}`,fileName:`Nome file`,altText:`Testo alternativo`,altTextPlaceholder:`Descrivi questa immagine…`},imageEditor:{title:`Editor immagine`,save:`Salva`,undo:`Annulla`,redo:`Ripristina`,zoomOut:`Riduci zoom`,zoomIn:`Aumenta zoom`,crop:`Ritaglia`,flipHorizontal:`Capovolgi orizzontalmente`,flipVertical:`Capovolgi verticalmente`,rotate:`Ruota 90°`,freeDrawing:`Disegno libero`,arrow:`Freccia`,text:`Testo`,rectangle:`Rettangolo`,circle:`Cerchio`,triangle:`Triangolo`},prompt:{noProviders:`Nessun provider AI registrato.`,aiNotConfiguredEdit:`L'AI non è configurata. Puoi comunque modificare e salvare questo prompt.`,aiNotConfiguredRun:`L'AI non è configurata. Impossibile eseguire questo prompt.`,aiNotConfiguredShort:`AI non configurata`,toggleOnTitle:`Prompt ATTIVO. Il testo viene usato come template e può essere eseguito.`,toggleOffTitle:`Prompt DISATTIVO. Il testo viene usato direttamente senza elaborazione AI.`,closeEditor:`Chiudi editor`,editSettings:`Modifica impostazioni`,attachFiles:`Allega file`,dropFilesHere:`Rilascia i file per allegarli`,modelPricing:`Input / output, USD per 1M token`,modelPriceNotFound:`Prezzo non trovato`,attachmentsNotSupported:`Il provider AI selezionato non supporta allegati immagini o documenti.`,run:`Esegui`,runFailed:`Esecuzione del prompt fallita.`,noMatchingCommands:`Nessun comando corrispondente`,tokenUsage:`Utilizzo token`,tokenInput:`In: {count} tok`,tokenOutput:`Out: {count} tok`,tokenContext:`Contesto: {percent}%`,tokenCost:"Costo: ~${amount}",tokenTime:`Tempo: {seconds}s`,tokenUsageEmpty:`Esegui il prompt per vedere l'utilizzo token.`,hidePreview:`Nascondi anteprima`,showPreview:`Mostra anteprima risolta`,noProvider:`Nessun provider AI disponibile per questo prompt.`,noResponse:`Il provider AI non ha restituito alcuna risposta.`,promptLabel:`Prompt: `,defaultOption:`Predefinito`},layout:{maxElements:`Hai già 12 elementi nella riga: rimuovine uno prima.`,noSpace:`Nessuno spazio: impossibile ridurre gli elementi per inserire questo campo.`,dragToMove:`Trascina per spostare`,remove:`Rimuovi`,dragToResize:`Trascina per ridimensionare`,dragHere:`Trascina un elemento qui dentro`},addressAutocomplete:{placeholder:`Cerca un indirizzo...`,noResults:`Nessun indirizzo corrispondente`,searching:`Ricerca in corso...`,notConfigured:`La ricerca indirizzi non è configurata (manca la API key Google Maps).`,loadError:`Impossibile caricare la ricerca indirizzi.`}},ph={common:{save:`Speichern`,cancel:`Abbrechen`,delete:`Löschen`,close:`Schließen`,back:`Zurück`,search:`Suchen`,loading:`Laden...`,noDataFound:`Keine Daten gefunden`,pageNavigation:`Seitennavigation`,previous:`Zurück`,next:`Weiter`,notFoundMessage:`Ups! Seite nicht gefunden.`,goHome:`Zur Startseite`},auth:{signIn:`Anmelden`,signOut:`Abmelden`,connect:`Verbinden`,connected:`Verbunden`,authenticated:`Authentifiziert`,notConfigured:`Auth-Provider "{provider}" ist nicht konfiguriert. API-Schlüssel prüfen.`,notImplemented:`Der Provider implementiert signIn() nicht.`},form:{headerAdd:`Hinzufügen`,headerEdit:`Bearbeiten`,buttonSave:`Speichern`,buttonDelete:`Löschen`,buttonBack:`Zurück`,requiredField:`Das Feld "{field}" ist erforderlich`,requiredFieldGeneric:`Pflichtfelder sind nicht ausgefüllt`,saveSuccess:`Erfolgreich gespeichert`,deleteSuccess:`Erfolgreich gelöscht`,noticeRequiredFields:`Pflichtfelder vor dem Speichern ausfüllen.`},grid:{buttonAdd:`Hinzufügen`,deleteConfirm:`Dieses Element wirklich löschen?`,emptyState:`Keine Elemente vorhanden`,filtersButton:`Filter`,filtersPanelTitle:`Filter`,filtersClearAll:`Alle zurücksetzen`,filtersSelectPlaceholder:`Alle`,filtersRangeFrom:`Von`,filtersRangeTo:`Bis`,filtersRangeMin:`Min`,filtersRangeMax:`Max`,filtersSelectedCountTemplate:`{count} ausgewählt`},select:{placeholder:`Auswählen...`,loading:`Lädt...`},modal:{save:`Speichern`,delete:`Löschen`,cancel:`Abbrechen`,close:`Schließen`,ok:`Ok`,yes:`Ja`,no:`Nein`},upload:{clickOrDrag:`Klicken oder ziehen zum Hochladen...`,dropToUpload:`Loslassen zum Hochladen`,uploadMore:`Weitere Dateien hinzufügen`,editFileName:`Dateiname bearbeiten`,editorImage:`Bildeditor`,loaded:`Geladen`,removeFile:`Entfernen`,uploadAnother:`Eine weitere Datei hochladen`,dropToParse:`Loslassen zum Analysieren`,insertFromUrl:`Von URL einfügen`,urlPlaceholder:`https://…/bild.png`,invalidUrl:`Gültige URL eingeben`},notifications:{title:`Benachrichtigungen`,seeAll:`Alle anzeigen`},code:{copyCode:`Code kopieren`,copy:`Kopieren`,copied:`Kopiert!`,codeLanguageDefault:`Text`},table:{noDataFound:`Keine Daten gefunden`,selectAllRows:`Alle Zeilen auswählen`,sortBy:`Nach {label} sortieren`,sortByCurrent:`Nach {label} sortieren ({direction})`,selectRow:`Zeile {key} auswählen`,reorderRow:`Zeile {key} neu anordnen`},gallery:{selectItem:`Element {key} auswählen`},crop:{enableCrop:`Zuschnitt mit Skalierung {scale} aktivieren`,variants:`Varianten`,outputFile:`Ausgabedatei`,active:`Aktiv`,removeVariant:`Variante {scale} entfernen`,fileName:`Dateiname`,altText:`Alt-Text`,altTextPlaceholder:`Beschreiben Sie dieses Bild…`},imageEditor:{title:`Bildeditor`,save:`Speichern`,undo:`Rückgängig`,redo:`Wiederherstellen`,zoomOut:`Herauszoomen`,zoomIn:`Hineinzoomen`,crop:`Zuschneiden`,flipHorizontal:`Horizontal spiegeln`,flipVertical:`Vertikal spiegeln`,rotate:`90° drehen`,freeDrawing:`Freihandzeichnen`,arrow:`Pfeil`,text:`Text`,rectangle:`Rechteck`,circle:`Kreis`,triangle:`Dreieck`},prompt:{noProviders:`Keine AI-Provider registriert.`,aiNotConfiguredEdit:`AI ist nicht konfiguriert. Sie können diesen Prompt trotzdem bearbeiten.`,aiNotConfiguredRun:`AI ist nicht konfiguriert. Dieser Prompt kann nicht ausgeführt werden.`,aiNotConfiguredShort:`AI nicht konfiguriert`,toggleOnTitle:`Prompt AKTIV. Der Text wird als Vorlage verwendet und kann ausgeführt werden.`,toggleOffTitle:`Prompt INAKTIV. Der Text wird direkt ohne AI-Verarbeitung verwendet.`,closeEditor:`Editor schließen`,editSettings:`Einstellungen bearbeiten`,attachFiles:`Dateien anhängen`,dropFilesHere:`Dateien zum Anhängen hier ablegen`,modelPricing:`Input / Output, USD pro 1 Mio. Token`,modelPriceNotFound:`Preis nicht gefunden`,attachmentsNotSupported:`Der ausgewählte AI-Provider unterstützt keine Bild- oder Dokumentanlagen.`,run:`Ausführen`,runFailed:`Prompt-Ausführung fehlgeschlagen.`,noMatchingCommands:`Keine passenden Befehle`,tokenUsage:`Token-Nutzung`,tokenInput:`Eingabe: {count} tok`,tokenOutput:`Ausgabe: {count} tok`,tokenContext:`Kontext: {percent}%`,tokenCost:"Kosten: ~${amount}",tokenTime:`Zeit: {seconds}s`,tokenUsageEmpty:`Prompt ausführen, um Token-Nutzung zu sehen.`,hidePreview:`Vorschau ausblenden`,showPreview:`Aufgelöste Vorschau anzeigen`,noProvider:`Kein AI-Provider für diesen Prompt verfügbar.`,noResponse:`Der AI-Provider hat keine Antwort zurückgegeben.`,promptLabel:`Prompt: `,defaultOption:`Standard`},layout:{maxElements:`Bereits 12 Elemente in der Zeile: Eines entfernen.`,noSpace:`Kein Platz: Elemente können nicht genug verkleinert werden.`,dragToMove:`Zum Verschieben ziehen`,remove:`Entfernen`,dragToResize:`Zum Verkleinern ziehen`,dragHere:`Element hierher ziehen`},addressAutocomplete:{placeholder:`Adresse suchen...`,noResults:`Keine passende Adresse`,searching:`Suche läuft...`,notConfigured:`Adresssuche ist nicht konfiguriert (Google Maps API-Schlüssel fehlt).`,loadError:`Adresssuche konnte nicht geladen werden.`}},mh={common:{save:`Сохранить`,cancel:`Отменить`,delete:`Удалить`,close:`Закрыть`,back:`Назад`,search:`Поиск`,loading:`Загрузка...`,noDataFound:`Данные не найдены`,pageNavigation:`Навигация по страницам`,previous:`Назад`,next:`Вперёд`,notFoundMessage:`Упс! Страница не найдена.`,goHome:`На главную`},auth:{signIn:`Войти`,signOut:`Выйти`,connect:`Подключить`,connected:`Подключено`,authenticated:`Авторизован`,notConfigured:`Провайдер "{provider}" не настроен. Проверьте API-ключи.`,notImplemented:`Провайдер не реализует signIn().`},form:{headerAdd:`Добавить`,headerEdit:`Редактировать`,buttonSave:`Сохранить`,buttonDelete:`Удалить`,buttonBack:`Назад`,requiredField:`Поле "{field}" обязательно для заполнения`,requiredFieldGeneric:`Обязательные поля не заполнены`,saveSuccess:`Успешно сохранено`,deleteSuccess:`Успешно удалено`,noticeRequiredFields:`Заполните обязательные поля перед сохранением.`},grid:{buttonAdd:`Добавить`,deleteConfirm:`Вы уверены, что хотите удалить этот элемент?`,emptyState:`Нет элементов для отображения`,filtersButton:`Фильтры`,filtersPanelTitle:`Фильтры`,filtersClearAll:`Сбросить все`,filtersSelectPlaceholder:`Все`,filtersRangeFrom:`От`,filtersRangeTo:`До`,filtersRangeMin:`Мин`,filtersRangeMax:`Макс`,filtersSelectedCountTemplate:`Выбрано: {count}`},select:{placeholder:`Выбрать...`,loading:`Загрузка...`},modal:{save:`Сохранить`,delete:`Удалить`,cancel:`Отменить`,close:`Закрыть`,ok:`Ок`,yes:`Да`,no:`Нет`},upload:{clickOrDrag:`Нажмите или перетащите для загрузки...`,dropToUpload:`Отпустите для загрузки`,uploadMore:`Добавить ещё файлы`,editFileName:`Изменить имя файла`,editorImage:`Редактор изображений`,loaded:`Загружено`,removeFile:`Удалить`,uploadAnother:`Загрузить ещё один файл`,dropToParse:`Отпустите для анализа`,insertFromUrl:`Вставить по URL`,urlPlaceholder:`https://…/image.png`,invalidUrl:`Введите корректный URL`},notifications:{title:`Уведомления`,seeAll:`Смотреть все`},code:{copyCode:`Копировать код`,copy:`Копировать`,copied:`Скопировано!`,codeLanguageDefault:`Текст`},table:{noDataFound:`Данные не найдены`,selectAllRows:`Выбрать все строки`,sortBy:`Сортировать по {label}`,sortByCurrent:`Сортировать по {label} ({direction})`,selectRow:`Выбрать строку {key}`,reorderRow:`Переместить строку {key}`},gallery:{selectItem:`Выбрать элемент {key}`},crop:{enableCrop:`Включить обрезку в масштабе {scale}`,variants:`Варианты`,outputFile:`Выходной файл`,active:`Активно`,removeVariant:`Удалить вариант {scale}`,fileName:`Имя файла`,altText:`Альтернативный текст`,altTextPlaceholder:`Опишите это изображение…`},imageEditor:{title:`Редактор изображений`,save:`Сохранить`,undo:`Отменить`,redo:`Повторить`,zoomOut:`Уменьшить`,zoomIn:`Увеличить`,crop:`Обрезать`,flipHorizontal:`Отразить горизонтально`,flipVertical:`Отразить вертикально`,rotate:`Повернуть на 90°`,freeDrawing:`Свободное рисование`,arrow:`Стрелка`,text:`Текст`,rectangle:`Прямоугольник`,circle:`Круг`,triangle:`Треугольник`},prompt:{noProviders:`Нет зарегистрированных AI-провайдеров.`,aiNotConfiguredEdit:`AI не настроен. Вы можете редактировать и сохранять этот промпт.`,aiNotConfiguredRun:`AI не настроен. Запуск этого промпта невозможен.`,aiNotConfiguredShort:`AI не настроен`,toggleOnTitle:`Промпт ВКЛЮЧЁН. Текст используется как шаблон и может быть выполнен.`,toggleOffTitle:`Промпт ВЫКЛЮЧЕН. Текст используется напрямую без AI.`,closeEditor:`Закрыть редактор`,editSettings:`Изменить настройки`,attachFiles:`Прикрепить файлы`,dropFilesHere:`Перетащите файлы сюда, чтобы прикрепить`,modelPricing:`Ввод / вывод, USD за 1 млн токенов`,modelPriceNotFound:`Цена не найдена`,attachmentsNotSupported:`Выбранный AI-провайдер не поддерживает изображения или документы.`,run:`Запустить`,runFailed:`Ошибка выполнения промпта.`,noMatchingCommands:`Нет подходящих команд`,tokenUsage:`Использование токенов`,tokenInput:`Вход: {count} tok`,tokenOutput:`Выход: {count} tok`,tokenContext:`Контекст: {percent}%`,tokenCost:"Стоимость: ~${amount}",tokenTime:`Время: {seconds}с`,tokenUsageEmpty:`Запустите промпт для просмотра статистики.`,hidePreview:`Скрыть предпросмотр`,showPreview:`Показать предпросмотр`,noProvider:`AI-провайдер недоступен для этого промпта.`,noResponse:`AI-провайдер не вернул ответа.`,promptLabel:`Промпт: `,defaultOption:`По умолчанию`},layout:{maxElements:`В строке уже 12 элементов: сначала удалите один.`,noSpace:`Нет места: невозможно сжать элементы для добавления.`,dragToMove:`Перетащить для перемещения`,remove:`Удалить`,dragToResize:`Перетащить для изменения размера`,dragHere:`Перетащите элемент сюда`},addressAutocomplete:{placeholder:`Поиск адреса...`,noResults:`Нет подходящего адреса`,searching:`Поиск...`,notConfigured:`Поиск адресов не настроен (отсутствует ключ Google Maps API).`,loadError:`Не удалось загрузить поиск адресов.`}},hh={common:{save:`保存`,cancel:`取消`,delete:`删除`,close:`关闭`,back:`返回`,search:`搜索`,loading:`加载中...`,noDataFound:`未找到数据`,pageNavigation:`页面导航`,previous:`上一页`,next:`下一页`,notFoundMessage:`哎呀!页面未找到。`,goHome:`返回首页`},auth:{signIn:`登录`,signOut:`退出`,connect:`连接`,connected:`已连接`,authenticated:`已认证`,notConfigured:`授权提供商"{provider}"未配置。请检查API密钥。`,notImplemented:`提供商未实现signIn()。`},form:{headerAdd:`添加`,headerEdit:`编辑`,buttonSave:`保存`,buttonDelete:`删除`,buttonBack:`返回`,requiredField:`字段"{field}"为必填项`,requiredFieldGeneric:`必填字段未填写`,saveSuccess:`保存成功`,deleteSuccess:`删除成功`,noticeRequiredFields:`请在保存前填写必填字段。`},grid:{buttonAdd:`添加`,deleteConfirm:`确定要删除此项目吗?`,emptyState:`暂无数据`,filtersButton:`筛选`,filtersPanelTitle:`筛选`,filtersClearAll:`清除全部`,filtersSelectPlaceholder:`全部`,filtersRangeFrom:`从`,filtersRangeTo:`到`,filtersRangeMin:`最小`,filtersRangeMax:`最大`,filtersSelectedCountTemplate:`已选 {count} 项`},select:{placeholder:`请选择...`,loading:`加载中...`},modal:{save:`保存`,delete:`删除`,cancel:`取消`,close:`关闭`,ok:`确定`,yes:`是`,no:`否`},upload:{clickOrDrag:`点击或拖拽上传...`,dropToUpload:`松开上传`,uploadMore:`添加更多文件`,editFileName:`编辑文件名`,editorImage:`图片编辑器`,loaded:`已加载`,removeFile:`删除`,uploadAnother:`上传另一个文件`,dropToParse:`松开解析`,insertFromUrl:`通过URL插入`,urlPlaceholder:`https://…/image.png`,invalidUrl:`请输入有效的URL`},notifications:{title:`通知`,seeAll:`查看全部`},code:{copyCode:`复制代码`,copy:`复制`,copied:`已复制!`,codeLanguageDefault:`文本`},table:{noDataFound:`未找到数据`,selectAllRows:`选择所有行`,sortBy:`按{label}排序`,sortByCurrent:`按{label}排序({direction})`,selectRow:`选择行{key}`,reorderRow:`重排行{key}`},gallery:{selectItem:`选择项目{key}`},crop:{enableCrop:`启用{scale}比例裁剪`,variants:`变体`,outputFile:`输出文件`,active:`活跃`,removeVariant:`删除变体{scale}`,fileName:`文件名`,altText:`替代文本`,altTextPlaceholder:`描述此图片…`},imageEditor:{title:`图片编辑器`,save:`保存`,undo:`撤销`,redo:`重做`,zoomOut:`缩小`,zoomIn:`放大`,crop:`裁剪`,flipHorizontal:`水平翻转`,flipVertical:`垂直翻转`,rotate:`旋转90°`,freeDrawing:`自由绘制`,arrow:`箭头`,text:`文本`,rectangle:`矩形`,circle:`圆形`,triangle:`三角形`},prompt:{noProviders:`没有已注册的AI提供商。`,aiNotConfiguredEdit:`AI未配置。您仍然可以编辑并保存此提示词。`,aiNotConfiguredRun:`AI未配置。无法运行此提示词。`,aiNotConfiguredShort:`AI未配置`,toggleOnTitle:`提示词已启用。文本用作模板并可执行。`,toggleOffTitle:`提示词已禁用。文本直接使用,不经AI处理。`,closeEditor:`关闭编辑器`,editSettings:`编辑设置`,attachFiles:`附加文件`,dropFilesHere:`拖放文件以附加`,modelPricing:`输入 / 输出,每百万 token 美元价格`,modelPriceNotFound:`未找到价格`,attachmentsNotSupported:`所选AI提供商不支持图像或文档附件。`,run:`运行`,runFailed:`提示词执行失败。`,noMatchingCommands:`没有匹配的命令`,tokenUsage:`Token用量`,tokenInput:`输入:{count} tok`,tokenOutput:`输出:{count} tok`,tokenContext:`上下文:{percent}%`,tokenCost:"费用:~${amount}",tokenTime:`时间:{seconds}秒`,tokenUsageEmpty:`运行提示词以查看Token用量。`,hidePreview:`隐藏预览`,showPreview:`显示解析预览`,noProvider:`此提示词没有可用的AI提供商。`,noResponse:`AI提供商未返回任何响应。`,promptLabel:`Prompt: `,defaultOption:`默认`},layout:{maxElements:`行中已有12个元素:请先删除一个。`,noSpace:`空间不足:无法缩小元素以插入此字段。`,dragToMove:`拖拽移动`,remove:`删除`,dragToResize:`拖拽调整大小`,dragHere:`拖拽元素到此处`},addressAutocomplete:{placeholder:`搜索地址...`,noResults:`未找到匹配地址`,searching:`搜索中...`,notConfigured:`地址搜索未配置(缺少 Google Maps API 密钥)。`,loadError:`无法加载地址搜索。`}},gh={common:{save:`حفظ`,cancel:`إلغاء`,delete:`حذف`,close:`إغلاق`,back:`رجوع`,search:`بحث`,loading:`جاري التحميل...`,noDataFound:`لم يتم العثور على بيانات`,pageNavigation:`تنقل الصفحات`,previous:`السابق`,next:`التالي`,notFoundMessage:`عفوًا! الصفحة غير موجودة.`,goHome:`الذهاب إلى الرئيسية`},auth:{signIn:`تسجيل الدخول`,signOut:`تسجيل الخروج`,connect:`ربط`,connected:`مرتبط`,authenticated:`موثق`,notConfigured:`مزود المصادقة "{provider}" غير مكوّن. يرجى التحقق من مفاتيح API.`,notImplemented:`المزود لا ينفّذ signIn().`},form:{headerAdd:`إضافة`,headerEdit:`تعديل`,buttonSave:`حفظ`,buttonDelete:`حذف`,buttonBack:`رجوع`,requiredField:`الحقل "{field}" إلزامي`,requiredFieldGeneric:`الحقول الإلزامية غير مكتملة`,saveSuccess:`تم الحفظ بنجاح`,deleteSuccess:`تم الحذف بنجاح`,noticeRequiredFields:`يرجى ملء الحقول الإلزامية قبل الحفظ.`},grid:{buttonAdd:`إضافة`,deleteConfirm:`هل أنت متأكد من حذف هذا العنصر؟`,emptyState:`لا توجد عناصر للعرض`,filtersButton:`الفلاتر`,filtersPanelTitle:`الفلاتر`,filtersClearAll:`مسح الكل`,filtersSelectPlaceholder:`الكل`,filtersRangeFrom:`من`,filtersRangeTo:`إلى`,filtersRangeMin:`أدنى`,filtersRangeMax:`أقصى`,filtersSelectedCountTemplate:`تم اختيار {count}`},select:{placeholder:`اختر...`,loading:`جارٍ التحميل...`},modal:{save:`حفظ`,delete:`حذف`,cancel:`إلغاء`,close:`إغلاق`,ok:`موافق`,yes:`نعم`,no:`لا`},upload:{clickOrDrag:`انقر أو اسحب للتحميل...`,dropToUpload:`أفلت للتحميل`,uploadMore:`إضافة المزيد من الملفات`,editFileName:`تعديل اسم الملف`,editorImage:`محرر الصور`,loaded:`محمّل`,removeFile:`إزالة`,uploadAnother:`تحميل ملف آخر`,dropToParse:`أفلت للتحليل`,insertFromUrl:`إدراج من رابط`,urlPlaceholder:`https://…/image.png`,invalidUrl:`أدخل رابطًا صالحًا`},notifications:{title:`الإشعارات`,seeAll:`عرض الكل`},code:{copyCode:`نسخ الكود`,copy:`نسخ`,copied:`تم النسخ!`,codeLanguageDefault:`نص`},table:{noDataFound:`لم يتم العثور على بيانات`,selectAllRows:`تحديد جميع الصفوف`,sortBy:`ترتيب حسب {label}`,sortByCurrent:`ترتيب حسب {label} ({direction})`,selectRow:`تحديد الصف {key}`,reorderRow:`إعادة ترتيب الصف {key}`},gallery:{selectItem:`تحديد العنصر {key}`},crop:{enableCrop:`تفعيل الاقتصاص بمقياس {scale}`,variants:`المتغيرات`,outputFile:`ملف الإخراج`,active:`نشط`,removeVariant:`إزالة المتغير {scale}`,fileName:`اسم الملف`,altText:`النص البديل`,altTextPlaceholder:`صف هذه الصورة…`},imageEditor:{title:`محرر الصور`,save:`حفظ`,undo:`تراجع`,redo:`إعادة`,zoomOut:`تصغير`,zoomIn:`تكبير`,crop:`اقتصاص`,flipHorizontal:`قلب أفقي`,flipVertical:`قلب رأسي`,rotate:`تدوير 90°`,freeDrawing:`رسم حر`,arrow:`سهم`,text:`نص`,rectangle:`مستطيل`,circle:`دائرة`,triangle:`مثلث`},prompt:{noProviders:`لا توجد مزودات AI مسجّلة.`,aiNotConfiguredEdit:`AI غير مكوّن. يمكنك تعديل وحفظ هذا الأمر.`,aiNotConfiguredRun:`AI غير مكوّن. لا يمكن تشغيل هذا الأمر.`,aiNotConfiguredShort:`AI غير مكوّن`,toggleOnTitle:`الأمر مفعّل. النص يُستخدم كقالب ويمكن تشغيله.`,toggleOffTitle:`الأمر معطّل. النص يُستخدم مباشرةً دون معالجة AI.`,closeEditor:`إغلاق المحرر`,editSettings:`تعديل الإعدادات`,attachFiles:`إرفاق الملفات`,dropFilesHere:`أفلت الملفات هنا لإرفاقها`,modelPricing:`الإدخال / الإخراج، دولار أمريكي لكل مليون رمز`,modelPriceNotFound:`السعر غير متوفر`,attachmentsNotSupported:`مزوّد AI المحدد لا يدعم مرفقات الصور أو المستندات.`,run:`تشغيل`,runFailed:`فشل تنفيذ الأمر.`,noMatchingCommands:`لا توجد أوامر مطابقة`,tokenUsage:`استخدام الرموز`,tokenInput:`دخل: {count} tok`,tokenOutput:`خرج: {count} tok`,tokenContext:`السياق: {percent}%`,tokenCost:"التكلفة: ~${amount}",tokenTime:`الوقت: {seconds}ث`,tokenUsageEmpty:`شغّل الأمر لعرض إحصائيات الرموز.`,hidePreview:`إخفاء المعاينة`,showPreview:`عرض المعاينة المحلولة`,noProvider:`لا يوجد مزود AI متاح لهذا الأمر.`,noResponse:`لم يُرجع مزود AI أي استجابة.`,promptLabel:`أمر: `,defaultOption:`افتراضي`},layout:{maxElements:`الصف يحتوي بالفعل على 12 عنصرًا: احذف عنصرًا أولاً.`,noSpace:`لا مساحة: لا يمكن تصغير العناصر لإضافة هذا الحقل.`,dragToMove:`اسحب للتحريك`,remove:`إزالة`,dragToResize:`اسحب لتغيير الحجم`,dragHere:`اسحب عنصرًا إلى هنا`},addressAutocomplete:{placeholder:`ابحث عن عنوان...`,noResults:`لا يوجد عنوان مطابق`,searching:`جارٍ البحث...`,notConfigured:`البحث عن العناوين غير مُعد (مفتاح Google Maps API مفقود).`,loadError:`تعذر تحميل البحث عن العناوين.`}},_h=e.n({ar:()=>gh,de:()=>ph,en:()=>$e,it:()=>fh,ru:()=>mh,zh:()=>hh}),vh=e=>Yr(`api`,e);async function yh(e){if(!e.ok)throw Error(`ApiProvider request failed: ${e.status} ${e.statusText}`);let t=await e.text();return t?JSON.parse(t):void 0}var bh=class{config;constructor(e){this.config=e}async fetch(e){let t=(e.method??`POST`).toUpperCase(),n=new URL(this.config.baseUrl.replace(/\/+$/,``)+`/`+e.path.replace(/^\/+/,``));Object.entries({...e.query,...this.config.query}).forEach(([e,t])=>n.searchParams.set(e,t));let r={...e.body,...this.config.body};return yh(await zs(n.toString(),{method:t,headers:{"Content-Type":`application/json`,...this.config.header},body:t===`GET`||t===`HEAD`?void 0:JSON.stringify(r)}))}},xh=class{resolver;constructor(e){this.resolver=e}async fetch(e){return this.resolver(e)}},Sh=class{config;constructor(e){this.config=e}async fetch(e){return mi(this.config.functionName,{provider:this.config.providerName,request:e},void 0,this.config.region)}},Ch=class{config;constructor(e){this.config=e}async fetch(e){let{data:t,error:n}=await Di(this.config.url,this.config.anonKey).functions.invoke(this.config.functionName,{body:{provider:this.config.providerName,request:e}});if(n)throw n;return t}},wh=[{id:`resend`,label:`Resend`,description:`Developer-first transactional email API.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`,placeholder:`re_...`}],credentialsUrl:`https://resend.com/api-keys`,credentialsHint:`Resend dashboard → API Keys → Create API Key.`},{id:`sendgrid`,label:`SendGrid`,description:`Scalable email delivery by Twilio.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`,placeholder:`SG...`}],credentialsUrl:`https://app.sendgrid.com/settings/api_keys`,credentialsHint:`SendGrid dashboard → Settings → API Keys → Create API Key.`},{id:`mailgun`,label:`Mailgun`,description:`Email API with analytics and webhooks.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`},{key:`domain`,label:`Mailgun domain`,type:`text`,placeholder:`mg.yourdomain.com`}],credentialsUrl:`https://app.mailgun.com/settings/api_security/api_keys`,credentialsHint:`Mailgun dashboard → Security → API Keys. The domain is the sending domain you verified under Sending → Domains.`},{id:`postmark`,label:`Postmark`,description:`High-deliverability transactional email.`,credentialFields:[{key:`serverToken`,label:`Server API Token`,type:`password`}],credentialsUrl:`https://account.postmarkapp.com/servers`,credentialsHint:`Postmark → your Server → API Tokens tab (each server has its own token).`},{id:`ses`,label:`AWS SES`,description:`Amazon Simple Email Service.`,credentialFields:[{key:`accessKeyId`,label:`Access Key ID`,type:`text`},{key:`secretAccessKey`,label:`Secret Access Key`,type:`password`},{key:`region`,label:`Region`,type:`text`,placeholder:`us-east-1`}],credentialsUrl:`https://console.aws.amazon.com/iam/home#/security_credentials`,credentialsHint:`AWS IAM → Security credentials → Access keys, for a user with SES send permissions.`},{id:`smtp`,label:`SMTP`,description:`Any SMTP-compatible mail server.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`smtp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`587`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password`,type:`password`}],credentialsHint:`Ask your mail host or hosting provider for the SMTP host, port, and credentials.`}],Th=[{id:`cloudflare_pages`,label:`Cloudflare Pages`,description:`Static hosting on Cloudflare's edge network, with native rollback.`,credentialFields:[{key:`apiToken`,label:`API Token`,type:`password`},{key:`accountId`,label:`Account ID`,type:`text`},{key:`projectName`,label:`Project name`,type:`text`,placeholder:`my-site`}],credentialsUrl:`https://dash.cloudflare.com/profile/api-tokens`,credentialsHint:`Cloudflare dashboard → My Profile → API Tokens → Create Token (Pages edit permission).`},{id:`firebase_hosting`,label:`Firebase Hosting`,description:`Google's static hosting, same project family as Firestore/Auth.`,credentialFields:[{key:`projectId`,label:`Firebase project ID`,type:`text`},{key:`siteId`,label:`Hosting site ID`,type:`text`},{key:`serviceAccountJson`,label:`Service account JSON`,type:`password`}],credentialsUrl:`https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk`,credentialsHint:`Firebase Console → Project settings → Service accounts → Generate new private key.`},{id:`supabase_storage`,label:`Supabase (Storage + custom domain)`,description:`Not a hosting product — serves the static build from a public Storage bucket behind your own domain. DIY, not officially supported by Supabase.`,credentialFields:[{key:`projectUrl`,label:`Project URL`,type:`text`,placeholder:`https://xyzcompany.supabase.co`},{key:`serviceKey`,label:`Service role key`,type:`password`},{key:`bucketName`,label:`Bucket name`,type:`text`}],credentialsUrl:`https://supabase.com/dashboard/project/_/settings/api`,credentialsHint:`Supabase dashboard → Project Settings → API → service_role key (never the anon key).`},{id:`ftp`,label:`FTP`,description:`Direct upload to any server over plain FTP — legacy, usually unencrypted; prefer SFTP when the server supports it.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`ftp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`21`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password`,type:`password`},{key:`remotePath`,label:`Remote path`,type:`text`,placeholder:`/var/www/html`}],credentialsHint:`Ask your hosting provider or server admin for FTP host, port, and credentials.`},{id:`sftp`,label:`SFTP`,description:`Direct upload to any server over SFTP (SSH) — no vendor lock-in.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`sftp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`22`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password / key`,type:`password`},{key:`remotePath`,label:`Remote path`,type:`text`,placeholder:`/var/www/html`}],credentialsHint:`Ask your hosting provider or server admin for SFTP host, port, and credentials.`},{id:`netlify`,label:`Netlify`,description:`Popular JAMstack hosting with a simple deploy API.`,credentialFields:[{key:`accessToken`,label:`Personal access token`,type:`password`},{key:`siteId`,label:`Site ID`,type:`text`}],credentialsUrl:`https://app.netlify.com/user/applications#personal-access-tokens`,credentialsHint:`Netlify → User settings → Applications → New access token.`},{id:`github_pages`,label:`GitHub Pages`,description:`Publishes by pushing the build to a branch of a GitHub repository.`,credentialFields:[{key:`repo`,label:`Repository`,type:`text`,placeholder:`owner/repo`},{key:`branch`,label:`Branch`,type:`text`,placeholder:`gh-pages`},{key:`token`,label:`Access token`,type:`password`}],credentialsUrl:`https://github.com/settings/tokens`,credentialsHint:`GitHub → Settings → Developer settings → Personal access tokens (repo scope).`},{id:`s3_cloudfront`,label:`AWS S3 + CloudFront`,description:`Classic static hosting on S3, served and cached through a CloudFront distribution.`,credentialFields:[{key:`accessKeyId`,label:`Access Key ID`,type:`text`},{key:`secretAccessKey`,label:`Secret Access Key`,type:`password`},{key:`bucketName`,label:`Bucket name`,type:`text`},{key:`distributionId`,label:`CloudFront distribution ID`,type:`text`},{key:`region`,label:`Region`,type:`text`,placeholder:`us-east-1`}],credentialsUrl:`https://console.aws.amazon.com/iam/home#/security_credentials`,credentialsHint:`AWS IAM → Security credentials → Access keys, for a user with S3 + CloudFront invalidation permissions.`},{id:`static_export`,label:`Static export (download)`,description:`No vendor — packages the build as a downloadable archive for self-hosting anywhere else.`,credentialFields:[]}],Eh=[Rm,Jm,Km,Om,Pm,om,Fm,pm({id:`glm`,label:`ZhipuAI (GLM)`,description:`Zhipu AI's GLM model family.`,configKey:`glmApiKey`,defaultModel:`glm-4-flash`,fallbackModels:[`glm-4-flash`,`glm-4`,`glm-z1-preview`,`glm-z1-plus`,`glm-4-long`],baseUrl:`https://open.bigmodel.cn/api/paas/v4`,dashboardUrl:`https://bigmodel.cn/usercenter/apikeys`,credentialsHint:`Zhipu BigModel → User Center → API Keys → Create Key.`}),Lm],Dh=e=>({id:e.id,label:e.label,description:e.description??``,credentialFields:e.credentialFields??[{key:`apiKey`,label:`API Key`,type:`password`}],credentialsUrl:e.dashboardUrl,credentialsHint:e.credentialsHint}),Oh=[...Eh.map(Dh),Dm],kh={id:`openai-compatible`,label:`OpenAI-compatible`,description:`Any OpenAI-compatible endpoint (self-hosted or third-party).`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`},{key:`baseUrl`,label:`Base URL`,type:`text`,placeholder:`https://api.example.com/v1`}]},Ah=e=>{let t=[],n=e?.cloudflare?.accountId?.trim();n&&t.push(Em({accountId:n,defaultModel:e?.cloudflare?.defaultModel?.trim()||void 0,includePaidModels:e?.cloudflare?.includePaidModels}));let r=e?.openAICompatible?.baseUrl?.trim();return r?[...t,pm({id:`openai-compatible`,label:e?.openAICompatible?.label?.trim()||`OpenAI-compatible`,description:`Any OpenAI-compatible endpoint (self-hosted or third-party).`,configKey:`openAICompatible`,requiredConfigKeys:[`ai.openAICompatible.apiKey`,`ai.openAICompatible.baseUrl`],defaultModel:e?.openAICompatible?.defaultModel?.trim()||`default`,fallbackModels:e?.openAICompatible?.fallbackModels?.filter(Boolean)||[`default`],baseUrl:r,modelsUrl:e?.openAICompatible?.modelsUrl?.trim()||void 0,chatCompletionsUrl:e?.openAICompatible?.chatCompletionsUrl?.trim()||void 0})]:t},jh=e=>e?[...Eh,...Ah(e)].reduce((t,n)=>{let r=n.id===`openai-compatible`?e.openAICompatible?.apiKey?.trim()||``:n.id===`cloudflare`?e.cloudflare?.apiToken?.trim()||``:typeof n.configKey==`string`&&typeof e[n.configKey]==`string`?String(e[n.configKey]||``).trim():``;return r&&(t[n.id]=new lc(n,r)),t},{}):{},Mh=void 0;typeof ei==`function`&&ei(e=>{Mh=e.google});var Nh={ita:`geoTargetConstants/2380`,rome:`geoTargetConstants/1033236`,mil:`geoTargetConstants/1033239`,nap:`geoTargetConstants/1033245`,tor:`geoTargetConstants/1033247`},Ph={it:`languageConstants/1000`,en:`languageConstants/1001`,fr:`languageConstants/1002`,es:`languageConstants/1003`,de:`languageConstants/1005`};function Fh(e){return Nh[e.toLowerCase()]||`geoTargetConstants/2380`}function Ih(e){return Ph[e.toLowerCase()]||`languageConstants/1000`}async function Lh({keyword:e,googleAdsAccountId:t,geoCode:n=`ita`,languageCode:r=`it`}){if(!Mh?.developerToken)return console.error(`
|
|
19
|
+
`).trim();return i?{type:`text`,text:i}:null}var Pm={id:`gemini`,label:`Gemini`,description:`Google's multimodal Gemini model family.`,configKey:`geminiApiKey`,defaultModel:`gemini-2.5-pro`,fallbackModels:[`gemini-2.5-pro`,`gemini-2.5-flash`,`gemini-2.5-flash-lite`],dashboardUrl:`https://aistudio.google.com/app/apikey`,credentialsHint:`Google AI Studio → Get API key → Create API key.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},discoverModels:async e=>{let t=await xe(`${km}?key=${e}`,null,zs);return Array.isArray(t?.models)?t.models.map(e=>e.name?.replace(/^models\//,``)).filter(Boolean):[]},validateApiKey:async e=>{try{let t=await xe(`${km}?key=${e}`,null,zs);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o rete)`}:t?.error?{valid:!1,error:typeof t.error==`object`&&`message`in t.error?String(t.error.message):String(t.error)}:{valid:!0}}catch(e){let t=e;return{valid:!1,error:t?.error&&typeof t.error==`object`?String(t.error.message??e):String(e)}}},complete:async(t,n)=>{let r=[...(n.attachments??[]).map(e=>hc.isTextAttachment(e.mimeType)?{text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{inline_data:{mime_type:e.mimeType,data:e.base64}}),{text:n.prompt}];return Nm(await xe(`${Am}/${n.model}:generateContent?key=${t}`,{method:`POST`,headers:n.logId?{[e.t]:n.logId}:void 0,body:{contents:[...(n.history??[]).map(Mm),...n.prompt?[{role:`user`,parts:r}]:[]],...n.role?{systemInstruction:{parts:[{text:Ds.parseRole(n.role,n)}]}}:{},...n.tools?.length?{tools:jm(n.tools)}:{},generationConfig:typeof n.temperature==`number`?{temperature:n.temperature}:void 0},signal:n.signal},zs))}},Fm=pm({id:`mistral`,label:`Mistral`,description:`European-hosted open and commercial language models.`,configKey:`mistralApiKey`,defaultModel:`mistral-medium-3`,fallbackModels:[`mistral-medium-3`,`mistral-small-3.1`,`ministral-8b-latest`],baseUrl:`https://api.mistral.ai/v1`,dashboardUrl:`https://console.mistral.ai/api-keys`,credentialsHint:`Mistral Console → API Keys → Create new key.`}),Im=/whisper|orpheus|tts|guard/i,Lm=pm({id:`groq`,label:`Groq`,description:`Very fast inference on open-weight models, with a free tier.`,configKey:`groqApiKey`,defaultModel:`openai/gpt-oss-120b`,fallbackModels:[`openai/gpt-oss-120b`,`openai/gpt-oss-20b`],baseUrl:`https://api.groq.com/openai/v1`,dashboardUrl:`https://console.groq.com/keys`,credentialsHint:`Groq Console → API Keys → Create API Key.`,mapModelEntry:e=>typeof e.id==`string`&&e.active!==!1&&!Im.test(e.id)?e.id:void 0}),Rm=pm({id:`openai`,label:`OpenAI`,description:`GPT models via the OpenAI API.`,configKey:`openaiApiKey`,defaultModel:`gpt-5.2`,fallbackModels:[`gpt-5.2`,`gpt-5`,`gpt-5-mini`,`gpt-5-nano`,`gpt-4.1`,`gpt-4.1-mini`,`gpt-4.1-nano`],baseUrl:`https://api.openai.com/v1`,dashboardUrl:`https://platform.openai.com/api-keys`,credentialsHint:`OpenAI dashboard → API keys → Create new secret key.`}),zm=`https://opencode.ai/zen/v1/models`,Bm=`https://opencode.ai/zen/v1/chat/completions`,Vm=`deepseek-v4.1-flash`,Hm=[Vm,`deepseek-v4-pro`,`glm-5.3`,`glm-5.3-flash`,`grok-build-0.1`,`kimi-k3`,`minimax-m3`,`qwen3.8-flash`],Um=/-free$/,Wm=new Set([`big-pickle`]),Gm=e=>Um.test(e)||Wm.has(e),Km={id:`opencode`,label:`OpenCode`,description:`OpenCode Zen — a curated set of coding-focused models.`,configKey:`openCodeApiKey`,defaultModel:Vm,fallbackModels:Hm,dashboardUrl:`https://opencode.ai`,credentialsHint:`OpenCode Zen dashboard → API Keys → Create Key.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`}],capabilities:{supportsTemperature:!0,supportsVision:!0,supportsDocuments:!0},discoverModels:async e=>{let t=await xe(zm,{headers:{Authorization:`Bearer ${e}`}},zs);return(Array.isArray(t?.data)?t.data:Array.isArray(t?.models)?t.models:Array.isArray(t)?t:[]).map(e=>e.id).filter(e=>typeof e==`string`&&e.length>0).filter(e=>!Gm(e))},complete:async(t,n)=>{let r=n.attachments??[],i=r.length>0?r.map(e=>e.mimeType.startsWith(`image/`)?{type:`image_url`,image_url:{url:`data:${e.mimeType};base64,${e.base64}`}}:hc.isTextAttachment(e.mimeType)?{type:`text`,text:`[File: ${e.name}]\n${hc.decodeBase64Text(e.base64)}`}:{type:`text`,text:`[File attached: ${e.name} (${e.mimeType})]`}).concat({type:`text`,text:n.prompt}):n.prompt,a=await xe(Bm,{method:`POST`,headers:{Authorization:`Bearer ${t}`,...n.logId?{[e.t]:n.logId}:{}},body:{model:n.model,messages:[...n.role?[{role:`system`,content:Ds.parseRole(n.role,n)}]:[],...(n.history??[]).flatMap(dm),...n.prompt?[{role:`user`,content:i}]:[]],...n.tools?.length?{tools:n.tools.map(lm)}:{},...typeof n.temperature==`number`?{temperature:n.temperature}:{}},signal:n.signal},zs);if(!a)throw rc(`OpenCode`);return fm(a)}},qm=e=>{if(!e||typeof e!=`object`)return;let{prompt:t,completion:n}=e,r=Number(t),i=Number(n);if(t===void 0||n===void 0||!Number.isFinite(r)||!Number.isFinite(i)||r<0||i<0)return;let a=e=>Math.round(e*0xe8d4a51000)/1e6;return{input:a(r),output:a(i),currency:`USD`,source:`provider`}},Jm=pm({id:`openrouter`,label:`OpenRouter`,description:`Unified access to many model providers through one API.`,configKey:`openRouterApiKey`,defaultModel:`openai/gpt-4`,fallbackModels:[`openai/gpt-4`,`openai/gpt-5-nano`,`anthropic/claude-3.7-sonnet`],baseUrl:`https://openrouter.ai/api/v1`,dashboardUrl:`https://openrouter.ai/settings/keys`,credentialsHint:`OpenRouter → Settings → API Keys → Create Key.`,mapModelEntry:e=>typeof e.id==`string`?{model:e.id,pricing:qm(e.pricing)}:void 0,validateApiKey:async e=>{try{let t=await xe(`https://openrouter.ai/api/v1/auth/key`,{headers:{Authorization:`Bearer ${e}`}},zs);return t===null?{valid:!1,error:`Nessuna risposta dal server (CORS o proxy non attivo)`}:t?.data?.label!==void 0||t?.data?.usage!==void 0?{valid:!0}:t?.error?{valid:!1,error:nc(t)}:{valid:!1,error:`Chiave non riconosciuta da OpenRouter`}}catch(e){return{valid:!1,error:nc(e)}}}}),Ym={dbRealtime:{service:`data`,create:()=>new Rp},firestoreDb:{service:`data`,create:()=>new Ti},firestorage:{service:`storage`,create:()=>new Zi},firebaseAuth:{service:`auth`,create:()=>new Hp}},Xm={googleAuth:{service:`auth`,create:()=>new yp},gmail:{service:`email`,create:()=>new Qp},googleServiceAccount:{service:`credentials`,create:e=>new qp(e.serviceAccount),when:e=>!!e.serviceAccount}},Zm={dropboxAuth:{service:`auth`,create:e=>new Yp(e)}},Qm={supabaseDb:{service:`data`,create:e=>new Ri(e)},supabaseStorage:{service:`storage`,create:e=>new Qi(e)},supabaseAuth:{service:`auth`,create:e=>new em(e)}},$m={mock:{service:`data`,create:e=>new Gi(e?.data)}},eh=(e,t)=>({service:`ai`,create:n=>new lc(e,n?.[t]||``),when:e=>!!e?.[t]}),th={firebase:Ym,google:Xm,dropbox:Zm,supabase:Qm,mock:$m,ai:{openai:eh(Rm,`openaiApiKey`),openrouter:eh(Jm,`openRouterApiKey`),opencode:eh(Km,`openCodeApiKey`),deepseek:eh(Om,`deepSeekApiKey`),gemini:eh(Pm,`geminiApiKey`),anthropic:eh(om,`anthropicApiKey`),mistral:eh(Fm,`mistralApiKey`),groq:eh(Lm,`groqApiKey`),cloudflare:{service:`ai`,create:e=>new lc(Em({accountId:e?.cloudflare?.accountId?.trim()||``,defaultModel:e?.cloudflare?.defaultModel?.trim()||void 0,includePaidModels:e?.cloudflare?.includePaidModels}),e?.cloudflare?.apiToken?.trim()||``),when:e=>!!e?.cloudflare?.apiToken?.trim()&&!!e?.cloudflare?.accountId?.trim()}}},nh=()=>t.default.createElement(`div`,{className:`flex min-h-[calc(100vh-4rem)] items-center justify-center`},t.default.createElement(`div`,{className:`h-8 w-8 animate-spin rounded-full border-2 border-muted border-t-primary`}));function rh(e,t){if(!t)return;let n=t,r=typeof t==`object`&&!Array.isArray(t)?Object.entries(n):[];if(r.length>0&&r.every(([,e])=>typeof e==`object`&&!!e)){Object.assign(e,n);return}e.custom=t}function ih(e,t,n=`default`){return t&&e[t]?t:Object.keys(e)[0]??n}function ah(e={}){let t={data:{},storage:{},auth:{},email:{},ai:{},credentials:{}},n=e=>t[e]??={};for(let[t,r]of Object.entries(th)){let i=e[t];if(i!==void 0)for(let[e,t]of Object.entries(r))(!t.when||t.when(i))&&(n(t.service)[e]=t.create(i))}for(let[t,r]of Object.entries(e.custom??{}))rh(n(t),r);Object.keys(t.data).length===0&&(t.data.mock=new Gi),Object.keys(t.auth).length===0&&(t.auth.googleAuth=new yp);let r=e.services??{},i={};for(let[e,n]of Object.entries(t))i[e]={registry:n,defaultKey:ih(n,r[e])};return i}var oh={},sh=e=>{oh=e},ch=e=>oh[e]||[];function lh({contextProviders:e,providers:r={},appName:i=`LLM Native`,scrapeConfig:a,iconProvider:o,googleMaps:s,themeProvider:c,i18n:l,children:u,errorReportUrl:d,debug:f,basename:p}){let[m,h]=(0,t.useState)(()=>ah(r)),g=(0,t.useRef)(m);g.current=m;let _=(0,t.useRef)(void 0);_.current||=(async(e,t,n)=>{let r=g.current[e]?.registry?.[t];r!==n&&(await r?.dispose?.(),h(r=>({...r,[e]:{defaultKey:r[e]?.defaultKey??t,registry:{...r[e]?.registry,[t]:n}}})))});let v=_.current,y=e??t.default.Fragment;return t.default.createElement(_p,{fullPage:!0,reportUrl:d,debug:f},t.default.createElement(n.BrowserRouter,{basename:p},t.default.createElement(ti,{defaultConfig:{title:i,firebase:r.firebase,google:r.google?{oAuth2:{clientId:r.google.clientId,scope:r.google.scope},serviceAccount:r.google.serviceAccount,developerToken:r.google.developerToken}:void 0,dropbox:r.dropbox,ai:r.ai,scrape:a,proxy:r.proxy}},t.default.createElement(Kr,{registries:m,setProvider:v},t.default.createElement(jn,m.auth,t.default.createElement(wp,m.credentials,t.default.createElement(er,m.data,t.default.createElement(Vo,m.storage,t.default.createElement(xp,m.email,t.default.createElement(Ms,m.ai,t.default.createElement(Zt,{config:o},t.default.createElement(fd,{config:s},t.default.createElement(Cf,{appName:i},t.default.createElement(lt,{config:l},t.default.createElement(Xe,{config:c},t.default.createElement(y,null,u))))))))))))))))}function uh({importPage:e,LayoutDefault:r=void 0,menuConfig:i={},children:a,...o}){sh(i);let s=({children:e})=>t.default.createElement(t.default.Fragment,null,e),c=({pageSource:e,message:n})=>t.default.createElement(da,{variant:`warning`},`Missing Page: `,e,n&&t.default.createElement(`code`,{className:`ml-2`},n));function l(i,a,l){let u=`./pages${a.component?`/`+a.component:a.path===`/`?`/Home`:T.toCamel(a.path.split(`*`)[0])}.js`,d=a.page||t.default.lazy(()=>e(u).then(e=>typeof e.default==`function`?{default:e.default}:(console.warn(`⚠️ Invalid default export in ${u}`),{default:()=>t.default.createElement(c,{pageSource:u})})).catch(e=>(console.error(`❌ Failed to load ${u}:`,e),{default:()=>t.default.createElement(c,{pageSource:u,message:e.message})}))),f=a.layout||r||s;return t.default.createElement(n.Route,{key:`${i}-${l}`,path:a.path,element:t.default.createElement(f,null,t.default.createElement(_p,{key:a.path,reportUrl:o.errorReportUrl,debug:o.debug},t.default.createElement(t.Suspense,{fallback:t.default.createElement(nh,null)},t.default.createElement(d,null))))})}let u=e=>Object.keys(e).flatMap(t=>e[t].flatMap((e,n)=>[e.path&&l(t,e,n),e.children&&u({children:e.children})].filter(Boolean))),d=(e,t)=>e.some(e=>e.path===t||!!e.children&&d(e.children,t)),f=Object.values(oh).some(e=>d(e,`/`))?{}:{default:[{path:`/`}]};return t.default.createElement(lh,o,a,t.default.createElement(n.Routes,null,t.default.createElement(n.Route,{path:Rn,element:t.default.createElement(Gn,null)}),t.default.createElement(t.default.Fragment,null,u({...f,...oh,_auth:[{path:`/users`,page:cp,layout:r}]})),t.default.createElement(n.Route,{path:`*`,element:t.default.createElement(lp,null)})))}var dh=e=>{let r=ch(e),i=(0,n.useLocation)(),a=e=>e.map(e=>{let t=i.pathname===e.path,n=e.children?a(e.children):[],r=t||n.some(e=>e.active);return{...e,active:r,children:n}});return(0,t.useMemo)(()=>a(r),[i.pathname])},fh={common:{save:`Salva`,cancel:`Annulla`,delete:`Elimina`,close:`Chiudi`,back:`Indietro`,search:`Cerca`,loading:`Caricamento...`,noDataFound:`Nessun dato trovato`,pageNavigation:`Navigazione pagine`,previous:`Precedente`,next:`Successivo`,notFoundMessage:`Ops! Pagina non trovata.`,goHome:`Vai alla Home`},auth:{signIn:`Accedi`,signOut:`Esci`,connect:`Connetti`,connected:`Connesso`,authenticated:`Autenticato`,notConfigured:`Il provider auth "{provider}" non è configurato. Controlla le chiavi API.`,notImplemented:`Il provider non implementa signIn().`},form:{headerAdd:`Aggiungi`,headerEdit:`Modifica`,buttonSave:`Salva`,buttonDelete:`Elimina`,buttonBack:`Indietro`,requiredField:`Il campo "{field}" è obbligatorio`,requiredFieldGeneric:`I campi obbligatori non sono compilati`,saveSuccess:`Salvato con successo`,deleteSuccess:`Eliminato con successo`,noticeRequiredFields:`Completa i campi obbligatori prima di salvare.`},grid:{buttonAdd:`Aggiungi`,deleteConfirm:`Sei sicuro di voler eliminare questo elemento?`,emptyState:`Nessun elemento da mostrare`,filtersButton:`Filtri`,filtersPanelTitle:`Filtri`,filtersClearAll:`Cancella tutti`,filtersSelectPlaceholder:`Tutti`,filtersRangeFrom:`Da`,filtersRangeTo:`A`,filtersRangeMin:`Min`,filtersRangeMax:`Max`,filtersSelectedCountTemplate:`{count} selezionati`},select:{placeholder:`Seleziona...`,loading:`Caricamento...`},modal:{save:`Salva`,delete:`Elimina`,cancel:`Annulla`,close:`Chiudi`,ok:`Ok`,yes:`Sì`,no:`No`},upload:{clickOrDrag:`Clicca o trascina per caricare...`,dropToUpload:`Rilascia per caricare`,uploadMore:`Aggiungi altri file`,editFileName:`Modifica nome file`,editorImage:`Editor immagine`,loaded:`Caricato`,removeFile:`Rimuovi`,uploadAnother:`Carica un altro file`,dropToParse:`Rilascia per analizzare`,insertFromUrl:`Inserisci da URL`,urlPlaceholder:`https://…/immagine.png`,invalidUrl:`Inserisci un URL valido`},notifications:{title:`Notifiche`,seeAll:`Vedi tutte`},code:{copyCode:`Copia codice`,copy:`Copia`,copied:`Copiato!`,codeLanguageDefault:`Testo`},table:{noDataFound:`Nessun dato trovato`,selectAllRows:`Seleziona tutte le righe`,sortBy:`Ordina per {label}`,sortByCurrent:`Ordina per {label} ({direction})`,selectRow:`Seleziona riga {key}`,reorderRow:`Riordina riga {key}`},gallery:{selectItem:`Seleziona elemento {key}`},crop:{enableCrop:`Abilita ritaglio a scala {scale}`,variants:`Varianti`,outputFile:`File di output`,active:`Attivo`,removeVariant:`Rimuovi variante {scale}`,fileName:`Nome file`,altText:`Testo alternativo`,altTextPlaceholder:`Descrivi questa immagine…`},imageEditor:{title:`Editor immagine`,save:`Salva`,undo:`Annulla`,redo:`Ripristina`,zoomOut:`Riduci zoom`,zoomIn:`Aumenta zoom`,crop:`Ritaglia`,flipHorizontal:`Capovolgi orizzontalmente`,flipVertical:`Capovolgi verticalmente`,rotate:`Ruota 90°`,freeDrawing:`Disegno libero`,arrow:`Freccia`,text:`Testo`,rectangle:`Rettangolo`,circle:`Cerchio`,triangle:`Triangolo`},prompt:{noProviders:`Nessun provider AI registrato.`,aiNotConfiguredEdit:`L'AI non è configurata. Puoi comunque modificare e salvare questo prompt.`,aiNotConfiguredRun:`L'AI non è configurata. Impossibile eseguire questo prompt.`,aiNotConfiguredShort:`AI non configurata`,toggleOnTitle:`Prompt ATTIVO. Il testo viene usato come template e può essere eseguito.`,toggleOffTitle:`Prompt DISATTIVO. Il testo viene usato direttamente senza elaborazione AI.`,closeEditor:`Chiudi editor`,editSettings:`Modifica impostazioni`,attachFiles:`Allega file`,dropFilesHere:`Rilascia i file per allegarli`,modelPricing:`Input / output, USD per 1M token`,modelPriceNotFound:`Prezzo non trovato`,attachmentsNotSupported:`Il provider AI selezionato non supporta allegati immagini o documenti.`,run:`Esegui`,runFailed:`Esecuzione del prompt fallita.`,noMatchingCommands:`Nessun comando corrispondente`,tokenUsage:`Utilizzo token`,tokenInput:`In: {count} tok`,tokenOutput:`Out: {count} tok`,tokenContext:`Contesto: {percent}%`,tokenCost:"Costo: ~${amount}",tokenTime:`Tempo: {seconds}s`,tokenUsageEmpty:`Esegui il prompt per vedere l'utilizzo token.`,hidePreview:`Nascondi anteprima`,showPreview:`Mostra anteprima risolta`,noProvider:`Nessun provider AI disponibile per questo prompt.`,noResponse:`Il provider AI non ha restituito alcuna risposta.`,promptLabel:`Prompt: `,defaultOption:`Predefinito`},layout:{maxElements:`Hai già 12 elementi nella riga: rimuovine uno prima.`,noSpace:`Nessuno spazio: impossibile ridurre gli elementi per inserire questo campo.`,dragToMove:`Trascina per spostare`,remove:`Rimuovi`,dragToResize:`Trascina per ridimensionare`,dragHere:`Trascina un elemento qui dentro`},addressAutocomplete:{placeholder:`Cerca un indirizzo...`,noResults:`Nessun indirizzo corrispondente`,searching:`Ricerca in corso...`,notConfigured:`La ricerca indirizzi non è configurata (manca la API key Google Maps).`,loadError:`Impossibile caricare la ricerca indirizzi.`}},ph={common:{save:`Speichern`,cancel:`Abbrechen`,delete:`Löschen`,close:`Schließen`,back:`Zurück`,search:`Suchen`,loading:`Laden...`,noDataFound:`Keine Daten gefunden`,pageNavigation:`Seitennavigation`,previous:`Zurück`,next:`Weiter`,notFoundMessage:`Ups! Seite nicht gefunden.`,goHome:`Zur Startseite`},auth:{signIn:`Anmelden`,signOut:`Abmelden`,connect:`Verbinden`,connected:`Verbunden`,authenticated:`Authentifiziert`,notConfigured:`Auth-Provider "{provider}" ist nicht konfiguriert. API-Schlüssel prüfen.`,notImplemented:`Der Provider implementiert signIn() nicht.`},form:{headerAdd:`Hinzufügen`,headerEdit:`Bearbeiten`,buttonSave:`Speichern`,buttonDelete:`Löschen`,buttonBack:`Zurück`,requiredField:`Das Feld "{field}" ist erforderlich`,requiredFieldGeneric:`Pflichtfelder sind nicht ausgefüllt`,saveSuccess:`Erfolgreich gespeichert`,deleteSuccess:`Erfolgreich gelöscht`,noticeRequiredFields:`Pflichtfelder vor dem Speichern ausfüllen.`},grid:{buttonAdd:`Hinzufügen`,deleteConfirm:`Dieses Element wirklich löschen?`,emptyState:`Keine Elemente vorhanden`,filtersButton:`Filter`,filtersPanelTitle:`Filter`,filtersClearAll:`Alle zurücksetzen`,filtersSelectPlaceholder:`Alle`,filtersRangeFrom:`Von`,filtersRangeTo:`Bis`,filtersRangeMin:`Min`,filtersRangeMax:`Max`,filtersSelectedCountTemplate:`{count} ausgewählt`},select:{placeholder:`Auswählen...`,loading:`Lädt...`},modal:{save:`Speichern`,delete:`Löschen`,cancel:`Abbrechen`,close:`Schließen`,ok:`Ok`,yes:`Ja`,no:`Nein`},upload:{clickOrDrag:`Klicken oder ziehen zum Hochladen...`,dropToUpload:`Loslassen zum Hochladen`,uploadMore:`Weitere Dateien hinzufügen`,editFileName:`Dateiname bearbeiten`,editorImage:`Bildeditor`,loaded:`Geladen`,removeFile:`Entfernen`,uploadAnother:`Eine weitere Datei hochladen`,dropToParse:`Loslassen zum Analysieren`,insertFromUrl:`Von URL einfügen`,urlPlaceholder:`https://…/bild.png`,invalidUrl:`Gültige URL eingeben`},notifications:{title:`Benachrichtigungen`,seeAll:`Alle anzeigen`},code:{copyCode:`Code kopieren`,copy:`Kopieren`,copied:`Kopiert!`,codeLanguageDefault:`Text`},table:{noDataFound:`Keine Daten gefunden`,selectAllRows:`Alle Zeilen auswählen`,sortBy:`Nach {label} sortieren`,sortByCurrent:`Nach {label} sortieren ({direction})`,selectRow:`Zeile {key} auswählen`,reorderRow:`Zeile {key} neu anordnen`},gallery:{selectItem:`Element {key} auswählen`},crop:{enableCrop:`Zuschnitt mit Skalierung {scale} aktivieren`,variants:`Varianten`,outputFile:`Ausgabedatei`,active:`Aktiv`,removeVariant:`Variante {scale} entfernen`,fileName:`Dateiname`,altText:`Alt-Text`,altTextPlaceholder:`Beschreiben Sie dieses Bild…`},imageEditor:{title:`Bildeditor`,save:`Speichern`,undo:`Rückgängig`,redo:`Wiederherstellen`,zoomOut:`Herauszoomen`,zoomIn:`Hineinzoomen`,crop:`Zuschneiden`,flipHorizontal:`Horizontal spiegeln`,flipVertical:`Vertikal spiegeln`,rotate:`90° drehen`,freeDrawing:`Freihandzeichnen`,arrow:`Pfeil`,text:`Text`,rectangle:`Rechteck`,circle:`Kreis`,triangle:`Dreieck`},prompt:{noProviders:`Keine AI-Provider registriert.`,aiNotConfiguredEdit:`AI ist nicht konfiguriert. Sie können diesen Prompt trotzdem bearbeiten.`,aiNotConfiguredRun:`AI ist nicht konfiguriert. Dieser Prompt kann nicht ausgeführt werden.`,aiNotConfiguredShort:`AI nicht konfiguriert`,toggleOnTitle:`Prompt AKTIV. Der Text wird als Vorlage verwendet und kann ausgeführt werden.`,toggleOffTitle:`Prompt INAKTIV. Der Text wird direkt ohne AI-Verarbeitung verwendet.`,closeEditor:`Editor schließen`,editSettings:`Einstellungen bearbeiten`,attachFiles:`Dateien anhängen`,dropFilesHere:`Dateien zum Anhängen hier ablegen`,modelPricing:`Input / Output, USD pro 1 Mio. Token`,modelPriceNotFound:`Preis nicht gefunden`,attachmentsNotSupported:`Der ausgewählte AI-Provider unterstützt keine Bild- oder Dokumentanlagen.`,run:`Ausführen`,runFailed:`Prompt-Ausführung fehlgeschlagen.`,noMatchingCommands:`Keine passenden Befehle`,tokenUsage:`Token-Nutzung`,tokenInput:`Eingabe: {count} tok`,tokenOutput:`Ausgabe: {count} tok`,tokenContext:`Kontext: {percent}%`,tokenCost:"Kosten: ~${amount}",tokenTime:`Zeit: {seconds}s`,tokenUsageEmpty:`Prompt ausführen, um Token-Nutzung zu sehen.`,hidePreview:`Vorschau ausblenden`,showPreview:`Aufgelöste Vorschau anzeigen`,noProvider:`Kein AI-Provider für diesen Prompt verfügbar.`,noResponse:`Der AI-Provider hat keine Antwort zurückgegeben.`,promptLabel:`Prompt: `,defaultOption:`Standard`},layout:{maxElements:`Bereits 12 Elemente in der Zeile: Eines entfernen.`,noSpace:`Kein Platz: Elemente können nicht genug verkleinert werden.`,dragToMove:`Zum Verschieben ziehen`,remove:`Entfernen`,dragToResize:`Zum Verkleinern ziehen`,dragHere:`Element hierher ziehen`},addressAutocomplete:{placeholder:`Adresse suchen...`,noResults:`Keine passende Adresse`,searching:`Suche läuft...`,notConfigured:`Adresssuche ist nicht konfiguriert (Google Maps API-Schlüssel fehlt).`,loadError:`Adresssuche konnte nicht geladen werden.`}},mh={common:{save:`Сохранить`,cancel:`Отменить`,delete:`Удалить`,close:`Закрыть`,back:`Назад`,search:`Поиск`,loading:`Загрузка...`,noDataFound:`Данные не найдены`,pageNavigation:`Навигация по страницам`,previous:`Назад`,next:`Вперёд`,notFoundMessage:`Упс! Страница не найдена.`,goHome:`На главную`},auth:{signIn:`Войти`,signOut:`Выйти`,connect:`Подключить`,connected:`Подключено`,authenticated:`Авторизован`,notConfigured:`Провайдер "{provider}" не настроен. Проверьте API-ключи.`,notImplemented:`Провайдер не реализует signIn().`},form:{headerAdd:`Добавить`,headerEdit:`Редактировать`,buttonSave:`Сохранить`,buttonDelete:`Удалить`,buttonBack:`Назад`,requiredField:`Поле "{field}" обязательно для заполнения`,requiredFieldGeneric:`Обязательные поля не заполнены`,saveSuccess:`Успешно сохранено`,deleteSuccess:`Успешно удалено`,noticeRequiredFields:`Заполните обязательные поля перед сохранением.`},grid:{buttonAdd:`Добавить`,deleteConfirm:`Вы уверены, что хотите удалить этот элемент?`,emptyState:`Нет элементов для отображения`,filtersButton:`Фильтры`,filtersPanelTitle:`Фильтры`,filtersClearAll:`Сбросить все`,filtersSelectPlaceholder:`Все`,filtersRangeFrom:`От`,filtersRangeTo:`До`,filtersRangeMin:`Мин`,filtersRangeMax:`Макс`,filtersSelectedCountTemplate:`Выбрано: {count}`},select:{placeholder:`Выбрать...`,loading:`Загрузка...`},modal:{save:`Сохранить`,delete:`Удалить`,cancel:`Отменить`,close:`Закрыть`,ok:`Ок`,yes:`Да`,no:`Нет`},upload:{clickOrDrag:`Нажмите или перетащите для загрузки...`,dropToUpload:`Отпустите для загрузки`,uploadMore:`Добавить ещё файлы`,editFileName:`Изменить имя файла`,editorImage:`Редактор изображений`,loaded:`Загружено`,removeFile:`Удалить`,uploadAnother:`Загрузить ещё один файл`,dropToParse:`Отпустите для анализа`,insertFromUrl:`Вставить по URL`,urlPlaceholder:`https://…/image.png`,invalidUrl:`Введите корректный URL`},notifications:{title:`Уведомления`,seeAll:`Смотреть все`},code:{copyCode:`Копировать код`,copy:`Копировать`,copied:`Скопировано!`,codeLanguageDefault:`Текст`},table:{noDataFound:`Данные не найдены`,selectAllRows:`Выбрать все строки`,sortBy:`Сортировать по {label}`,sortByCurrent:`Сортировать по {label} ({direction})`,selectRow:`Выбрать строку {key}`,reorderRow:`Переместить строку {key}`},gallery:{selectItem:`Выбрать элемент {key}`},crop:{enableCrop:`Включить обрезку в масштабе {scale}`,variants:`Варианты`,outputFile:`Выходной файл`,active:`Активно`,removeVariant:`Удалить вариант {scale}`,fileName:`Имя файла`,altText:`Альтернативный текст`,altTextPlaceholder:`Опишите это изображение…`},imageEditor:{title:`Редактор изображений`,save:`Сохранить`,undo:`Отменить`,redo:`Повторить`,zoomOut:`Уменьшить`,zoomIn:`Увеличить`,crop:`Обрезать`,flipHorizontal:`Отразить горизонтально`,flipVertical:`Отразить вертикально`,rotate:`Повернуть на 90°`,freeDrawing:`Свободное рисование`,arrow:`Стрелка`,text:`Текст`,rectangle:`Прямоугольник`,circle:`Круг`,triangle:`Треугольник`},prompt:{noProviders:`Нет зарегистрированных AI-провайдеров.`,aiNotConfiguredEdit:`AI не настроен. Вы можете редактировать и сохранять этот промпт.`,aiNotConfiguredRun:`AI не настроен. Запуск этого промпта невозможен.`,aiNotConfiguredShort:`AI не настроен`,toggleOnTitle:`Промпт ВКЛЮЧЁН. Текст используется как шаблон и может быть выполнен.`,toggleOffTitle:`Промпт ВЫКЛЮЧЕН. Текст используется напрямую без AI.`,closeEditor:`Закрыть редактор`,editSettings:`Изменить настройки`,attachFiles:`Прикрепить файлы`,dropFilesHere:`Перетащите файлы сюда, чтобы прикрепить`,modelPricing:`Ввод / вывод, USD за 1 млн токенов`,modelPriceNotFound:`Цена не найдена`,attachmentsNotSupported:`Выбранный AI-провайдер не поддерживает изображения или документы.`,run:`Запустить`,runFailed:`Ошибка выполнения промпта.`,noMatchingCommands:`Нет подходящих команд`,tokenUsage:`Использование токенов`,tokenInput:`Вход: {count} tok`,tokenOutput:`Выход: {count} tok`,tokenContext:`Контекст: {percent}%`,tokenCost:"Стоимость: ~${amount}",tokenTime:`Время: {seconds}с`,tokenUsageEmpty:`Запустите промпт для просмотра статистики.`,hidePreview:`Скрыть предпросмотр`,showPreview:`Показать предпросмотр`,noProvider:`AI-провайдер недоступен для этого промпта.`,noResponse:`AI-провайдер не вернул ответа.`,promptLabel:`Промпт: `,defaultOption:`По умолчанию`},layout:{maxElements:`В строке уже 12 элементов: сначала удалите один.`,noSpace:`Нет места: невозможно сжать элементы для добавления.`,dragToMove:`Перетащить для перемещения`,remove:`Удалить`,dragToResize:`Перетащить для изменения размера`,dragHere:`Перетащите элемент сюда`},addressAutocomplete:{placeholder:`Поиск адреса...`,noResults:`Нет подходящего адреса`,searching:`Поиск...`,notConfigured:`Поиск адресов не настроен (отсутствует ключ Google Maps API).`,loadError:`Не удалось загрузить поиск адресов.`}},hh={common:{save:`保存`,cancel:`取消`,delete:`删除`,close:`关闭`,back:`返回`,search:`搜索`,loading:`加载中...`,noDataFound:`未找到数据`,pageNavigation:`页面导航`,previous:`上一页`,next:`下一页`,notFoundMessage:`哎呀!页面未找到。`,goHome:`返回首页`},auth:{signIn:`登录`,signOut:`退出`,connect:`连接`,connected:`已连接`,authenticated:`已认证`,notConfigured:`授权提供商"{provider}"未配置。请检查API密钥。`,notImplemented:`提供商未实现signIn()。`},form:{headerAdd:`添加`,headerEdit:`编辑`,buttonSave:`保存`,buttonDelete:`删除`,buttonBack:`返回`,requiredField:`字段"{field}"为必填项`,requiredFieldGeneric:`必填字段未填写`,saveSuccess:`保存成功`,deleteSuccess:`删除成功`,noticeRequiredFields:`请在保存前填写必填字段。`},grid:{buttonAdd:`添加`,deleteConfirm:`确定要删除此项目吗?`,emptyState:`暂无数据`,filtersButton:`筛选`,filtersPanelTitle:`筛选`,filtersClearAll:`清除全部`,filtersSelectPlaceholder:`全部`,filtersRangeFrom:`从`,filtersRangeTo:`到`,filtersRangeMin:`最小`,filtersRangeMax:`最大`,filtersSelectedCountTemplate:`已选 {count} 项`},select:{placeholder:`请选择...`,loading:`加载中...`},modal:{save:`保存`,delete:`删除`,cancel:`取消`,close:`关闭`,ok:`确定`,yes:`是`,no:`否`},upload:{clickOrDrag:`点击或拖拽上传...`,dropToUpload:`松开上传`,uploadMore:`添加更多文件`,editFileName:`编辑文件名`,editorImage:`图片编辑器`,loaded:`已加载`,removeFile:`删除`,uploadAnother:`上传另一个文件`,dropToParse:`松开解析`,insertFromUrl:`通过URL插入`,urlPlaceholder:`https://…/image.png`,invalidUrl:`请输入有效的URL`},notifications:{title:`通知`,seeAll:`查看全部`},code:{copyCode:`复制代码`,copy:`复制`,copied:`已复制!`,codeLanguageDefault:`文本`},table:{noDataFound:`未找到数据`,selectAllRows:`选择所有行`,sortBy:`按{label}排序`,sortByCurrent:`按{label}排序({direction})`,selectRow:`选择行{key}`,reorderRow:`重排行{key}`},gallery:{selectItem:`选择项目{key}`},crop:{enableCrop:`启用{scale}比例裁剪`,variants:`变体`,outputFile:`输出文件`,active:`活跃`,removeVariant:`删除变体{scale}`,fileName:`文件名`,altText:`替代文本`,altTextPlaceholder:`描述此图片…`},imageEditor:{title:`图片编辑器`,save:`保存`,undo:`撤销`,redo:`重做`,zoomOut:`缩小`,zoomIn:`放大`,crop:`裁剪`,flipHorizontal:`水平翻转`,flipVertical:`垂直翻转`,rotate:`旋转90°`,freeDrawing:`自由绘制`,arrow:`箭头`,text:`文本`,rectangle:`矩形`,circle:`圆形`,triangle:`三角形`},prompt:{noProviders:`没有已注册的AI提供商。`,aiNotConfiguredEdit:`AI未配置。您仍然可以编辑并保存此提示词。`,aiNotConfiguredRun:`AI未配置。无法运行此提示词。`,aiNotConfiguredShort:`AI未配置`,toggleOnTitle:`提示词已启用。文本用作模板并可执行。`,toggleOffTitle:`提示词已禁用。文本直接使用,不经AI处理。`,closeEditor:`关闭编辑器`,editSettings:`编辑设置`,attachFiles:`附加文件`,dropFilesHere:`拖放文件以附加`,modelPricing:`输入 / 输出,每百万 token 美元价格`,modelPriceNotFound:`未找到价格`,attachmentsNotSupported:`所选AI提供商不支持图像或文档附件。`,run:`运行`,runFailed:`提示词执行失败。`,noMatchingCommands:`没有匹配的命令`,tokenUsage:`Token用量`,tokenInput:`输入:{count} tok`,tokenOutput:`输出:{count} tok`,tokenContext:`上下文:{percent}%`,tokenCost:"费用:~${amount}",tokenTime:`时间:{seconds}秒`,tokenUsageEmpty:`运行提示词以查看Token用量。`,hidePreview:`隐藏预览`,showPreview:`显示解析预览`,noProvider:`此提示词没有可用的AI提供商。`,noResponse:`AI提供商未返回任何响应。`,promptLabel:`Prompt: `,defaultOption:`默认`},layout:{maxElements:`行中已有12个元素:请先删除一个。`,noSpace:`空间不足:无法缩小元素以插入此字段。`,dragToMove:`拖拽移动`,remove:`删除`,dragToResize:`拖拽调整大小`,dragHere:`拖拽元素到此处`},addressAutocomplete:{placeholder:`搜索地址...`,noResults:`未找到匹配地址`,searching:`搜索中...`,notConfigured:`地址搜索未配置(缺少 Google Maps API 密钥)。`,loadError:`无法加载地址搜索。`}},gh={common:{save:`حفظ`,cancel:`إلغاء`,delete:`حذف`,close:`إغلاق`,back:`رجوع`,search:`بحث`,loading:`جاري التحميل...`,noDataFound:`لم يتم العثور على بيانات`,pageNavigation:`تنقل الصفحات`,previous:`السابق`,next:`التالي`,notFoundMessage:`عفوًا! الصفحة غير موجودة.`,goHome:`الذهاب إلى الرئيسية`},auth:{signIn:`تسجيل الدخول`,signOut:`تسجيل الخروج`,connect:`ربط`,connected:`مرتبط`,authenticated:`موثق`,notConfigured:`مزود المصادقة "{provider}" غير مكوّن. يرجى التحقق من مفاتيح API.`,notImplemented:`المزود لا ينفّذ signIn().`},form:{headerAdd:`إضافة`,headerEdit:`تعديل`,buttonSave:`حفظ`,buttonDelete:`حذف`,buttonBack:`رجوع`,requiredField:`الحقل "{field}" إلزامي`,requiredFieldGeneric:`الحقول الإلزامية غير مكتملة`,saveSuccess:`تم الحفظ بنجاح`,deleteSuccess:`تم الحذف بنجاح`,noticeRequiredFields:`يرجى ملء الحقول الإلزامية قبل الحفظ.`},grid:{buttonAdd:`إضافة`,deleteConfirm:`هل أنت متأكد من حذف هذا العنصر؟`,emptyState:`لا توجد عناصر للعرض`,filtersButton:`الفلاتر`,filtersPanelTitle:`الفلاتر`,filtersClearAll:`مسح الكل`,filtersSelectPlaceholder:`الكل`,filtersRangeFrom:`من`,filtersRangeTo:`إلى`,filtersRangeMin:`أدنى`,filtersRangeMax:`أقصى`,filtersSelectedCountTemplate:`تم اختيار {count}`},select:{placeholder:`اختر...`,loading:`جارٍ التحميل...`},modal:{save:`حفظ`,delete:`حذف`,cancel:`إلغاء`,close:`إغلاق`,ok:`موافق`,yes:`نعم`,no:`لا`},upload:{clickOrDrag:`انقر أو اسحب للتحميل...`,dropToUpload:`أفلت للتحميل`,uploadMore:`إضافة المزيد من الملفات`,editFileName:`تعديل اسم الملف`,editorImage:`محرر الصور`,loaded:`محمّل`,removeFile:`إزالة`,uploadAnother:`تحميل ملف آخر`,dropToParse:`أفلت للتحليل`,insertFromUrl:`إدراج من رابط`,urlPlaceholder:`https://…/image.png`,invalidUrl:`أدخل رابطًا صالحًا`},notifications:{title:`الإشعارات`,seeAll:`عرض الكل`},code:{copyCode:`نسخ الكود`,copy:`نسخ`,copied:`تم النسخ!`,codeLanguageDefault:`نص`},table:{noDataFound:`لم يتم العثور على بيانات`,selectAllRows:`تحديد جميع الصفوف`,sortBy:`ترتيب حسب {label}`,sortByCurrent:`ترتيب حسب {label} ({direction})`,selectRow:`تحديد الصف {key}`,reorderRow:`إعادة ترتيب الصف {key}`},gallery:{selectItem:`تحديد العنصر {key}`},crop:{enableCrop:`تفعيل الاقتصاص بمقياس {scale}`,variants:`المتغيرات`,outputFile:`ملف الإخراج`,active:`نشط`,removeVariant:`إزالة المتغير {scale}`,fileName:`اسم الملف`,altText:`النص البديل`,altTextPlaceholder:`صف هذه الصورة…`},imageEditor:{title:`محرر الصور`,save:`حفظ`,undo:`تراجع`,redo:`إعادة`,zoomOut:`تصغير`,zoomIn:`تكبير`,crop:`اقتصاص`,flipHorizontal:`قلب أفقي`,flipVertical:`قلب رأسي`,rotate:`تدوير 90°`,freeDrawing:`رسم حر`,arrow:`سهم`,text:`نص`,rectangle:`مستطيل`,circle:`دائرة`,triangle:`مثلث`},prompt:{noProviders:`لا توجد مزودات AI مسجّلة.`,aiNotConfiguredEdit:`AI غير مكوّن. يمكنك تعديل وحفظ هذا الأمر.`,aiNotConfiguredRun:`AI غير مكوّن. لا يمكن تشغيل هذا الأمر.`,aiNotConfiguredShort:`AI غير مكوّن`,toggleOnTitle:`الأمر مفعّل. النص يُستخدم كقالب ويمكن تشغيله.`,toggleOffTitle:`الأمر معطّل. النص يُستخدم مباشرةً دون معالجة AI.`,closeEditor:`إغلاق المحرر`,editSettings:`تعديل الإعدادات`,attachFiles:`إرفاق الملفات`,dropFilesHere:`أفلت الملفات هنا لإرفاقها`,modelPricing:`الإدخال / الإخراج، دولار أمريكي لكل مليون رمز`,modelPriceNotFound:`السعر غير متوفر`,attachmentsNotSupported:`مزوّد AI المحدد لا يدعم مرفقات الصور أو المستندات.`,run:`تشغيل`,runFailed:`فشل تنفيذ الأمر.`,noMatchingCommands:`لا توجد أوامر مطابقة`,tokenUsage:`استخدام الرموز`,tokenInput:`دخل: {count} tok`,tokenOutput:`خرج: {count} tok`,tokenContext:`السياق: {percent}%`,tokenCost:"التكلفة: ~${amount}",tokenTime:`الوقت: {seconds}ث`,tokenUsageEmpty:`شغّل الأمر لعرض إحصائيات الرموز.`,hidePreview:`إخفاء المعاينة`,showPreview:`عرض المعاينة المحلولة`,noProvider:`لا يوجد مزود AI متاح لهذا الأمر.`,noResponse:`لم يُرجع مزود AI أي استجابة.`,promptLabel:`أمر: `,defaultOption:`افتراضي`},layout:{maxElements:`الصف يحتوي بالفعل على 12 عنصرًا: احذف عنصرًا أولاً.`,noSpace:`لا مساحة: لا يمكن تصغير العناصر لإضافة هذا الحقل.`,dragToMove:`اسحب للتحريك`,remove:`إزالة`,dragToResize:`اسحب لتغيير الحجم`,dragHere:`اسحب عنصرًا إلى هنا`},addressAutocomplete:{placeholder:`ابحث عن عنوان...`,noResults:`لا يوجد عنوان مطابق`,searching:`جارٍ البحث...`,notConfigured:`البحث عن العناوين غير مُعد (مفتاح Google Maps API مفقود).`,loadError:`تعذر تحميل البحث عن العناوين.`}},_h=e.n({ar:()=>gh,de:()=>ph,en:()=>$e,it:()=>fh,ru:()=>mh,zh:()=>hh}),vh=e=>Yr(`api`,e);async function yh(e){if(!e.ok)throw Error(`ApiProvider request failed: ${e.status} ${e.statusText}`);let t=await e.text();return t?JSON.parse(t):void 0}var bh=class{config;constructor(e){this.config=e}async fetch(e){let t=(e.method??`POST`).toUpperCase(),n=new URL(this.config.baseUrl.replace(/\/+$/,``)+`/`+e.path.replace(/^\/+/,``));Object.entries({...e.query,...this.config.query}).forEach(([e,t])=>n.searchParams.set(e,t));let r={...e.body,...this.config.body};return yh(await zs(n.toString(),{method:t,headers:{"Content-Type":`application/json`,...this.config.header},body:t===`GET`||t===`HEAD`?void 0:JSON.stringify(r)}))}},xh=class{resolver;constructor(e){this.resolver=e}async fetch(e){return this.resolver(e)}},Sh=class{config;constructor(e){this.config=e}async fetch(e){return mi(this.config.functionName,{provider:this.config.providerName,request:e},void 0,this.config.region)}},Ch=class{config;constructor(e){this.config=e}async fetch(e){let{data:t,error:n}=await Di(this.config.url,this.config.anonKey).functions.invoke(this.config.functionName,{body:{provider:this.config.providerName,request:e}});if(n)throw n;return t}},wh=[{id:`resend`,label:`Resend`,description:`Developer-first transactional email API.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`,placeholder:`re_...`}],credentialsUrl:`https://resend.com/api-keys`,credentialsHint:`Resend dashboard → API Keys → Create API Key.`},{id:`sendgrid`,label:`SendGrid`,description:`Scalable email delivery by Twilio.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`,placeholder:`SG...`}],credentialsUrl:`https://app.sendgrid.com/settings/api_keys`,credentialsHint:`SendGrid dashboard → Settings → API Keys → Create API Key.`},{id:`mailgun`,label:`Mailgun`,description:`Email API with analytics and webhooks.`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`},{key:`domain`,label:`Mailgun domain`,type:`text`,placeholder:`mg.yourdomain.com`}],credentialsUrl:`https://app.mailgun.com/settings/api_security/api_keys`,credentialsHint:`Mailgun dashboard → Security → API Keys. The domain is the sending domain you verified under Sending → Domains.`},{id:`postmark`,label:`Postmark`,description:`High-deliverability transactional email.`,credentialFields:[{key:`serverToken`,label:`Server API Token`,type:`password`}],credentialsUrl:`https://account.postmarkapp.com/servers`,credentialsHint:`Postmark → your Server → API Tokens tab (each server has its own token).`},{id:`ses`,label:`AWS SES`,description:`Amazon Simple Email Service.`,credentialFields:[{key:`accessKeyId`,label:`Access Key ID`,type:`text`},{key:`secretAccessKey`,label:`Secret Access Key`,type:`password`},{key:`region`,label:`Region`,type:`text`,placeholder:`us-east-1`}],credentialsUrl:`https://console.aws.amazon.com/iam/home#/security_credentials`,credentialsHint:`AWS IAM → Security credentials → Access keys, for a user with SES send permissions.`},{id:`smtp`,label:`SMTP`,description:`Any SMTP-compatible mail server.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`smtp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`587`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password`,type:`password`}],credentialsHint:`Ask your mail host or hosting provider for the SMTP host, port, and credentials.`}],Th=[{id:`cloudflare_pages`,label:`Cloudflare Pages`,description:`Static hosting on Cloudflare's edge network, with native rollback.`,credentialFields:[{key:`apiToken`,label:`API Token`,type:`password`},{key:`accountId`,label:`Account ID`,type:`text`},{key:`projectName`,label:`Project name`,type:`text`,placeholder:`my-site`}],credentialsUrl:`https://dash.cloudflare.com/profile/api-tokens`,credentialsHint:`Cloudflare dashboard → My Profile → API Tokens → Create Token (Pages edit permission).`},{id:`firebase_hosting`,label:`Firebase Hosting`,description:`Google's static hosting, same project family as Firestore/Auth.`,credentialFields:[{key:`projectId`,label:`Firebase project ID`,type:`text`},{key:`siteId`,label:`Hosting site ID`,type:`text`},{key:`serviceAccountJson`,label:`Service account JSON`,type:`password`}],credentialsUrl:`https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk`,credentialsHint:`Firebase Console → Project settings → Service accounts → Generate new private key.`},{id:`supabase_storage`,label:`Supabase (Storage + custom domain)`,description:`Not a hosting product — serves the static build from a public Storage bucket behind your own domain. DIY, not officially supported by Supabase.`,credentialFields:[{key:`projectUrl`,label:`Project URL`,type:`text`,placeholder:`https://xyzcompany.supabase.co`},{key:`serviceKey`,label:`Service role key`,type:`password`},{key:`bucketName`,label:`Bucket name`,type:`text`}],credentialsUrl:`https://supabase.com/dashboard/project/_/settings/api`,credentialsHint:`Supabase dashboard → Project Settings → API → service_role key (never the anon key).`},{id:`ftp`,label:`FTP`,description:`Direct upload to any server over plain FTP — legacy, usually unencrypted; prefer SFTP when the server supports it.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`ftp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`21`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password`,type:`password`},{key:`remotePath`,label:`Remote path`,type:`text`,placeholder:`/var/www/html`}],credentialsHint:`Ask your hosting provider or server admin for FTP host, port, and credentials.`},{id:`sftp`,label:`SFTP`,description:`Direct upload to any server over SFTP (SSH) — no vendor lock-in.`,credentialFields:[{key:`host`,label:`Host`,type:`text`,placeholder:`sftp.example.com`},{key:`port`,label:`Port`,type:`text`,placeholder:`22`},{key:`username`,label:`Username`,type:`text`},{key:`password`,label:`Password / key`,type:`password`},{key:`remotePath`,label:`Remote path`,type:`text`,placeholder:`/var/www/html`}],credentialsHint:`Ask your hosting provider or server admin for SFTP host, port, and credentials.`},{id:`netlify`,label:`Netlify`,description:`Popular JAMstack hosting with a simple deploy API.`,credentialFields:[{key:`accessToken`,label:`Personal access token`,type:`password`},{key:`siteId`,label:`Site ID`,type:`text`}],credentialsUrl:`https://app.netlify.com/user/applications#personal-access-tokens`,credentialsHint:`Netlify → User settings → Applications → New access token.`},{id:`github_pages`,label:`GitHub Pages`,description:`Publishes by pushing the build to a branch of a GitHub repository.`,credentialFields:[{key:`repo`,label:`Repository`,type:`text`,placeholder:`owner/repo`},{key:`branch`,label:`Branch`,type:`text`,placeholder:`gh-pages`},{key:`token`,label:`Access token`,type:`password`}],credentialsUrl:`https://github.com/settings/tokens`,credentialsHint:`GitHub → Settings → Developer settings → Personal access tokens (repo scope).`},{id:`s3_cloudfront`,label:`AWS S3 + CloudFront`,description:`Classic static hosting on S3, served and cached through a CloudFront distribution.`,credentialFields:[{key:`accessKeyId`,label:`Access Key ID`,type:`text`},{key:`secretAccessKey`,label:`Secret Access Key`,type:`password`},{key:`bucketName`,label:`Bucket name`,type:`text`},{key:`distributionId`,label:`CloudFront distribution ID`,type:`text`},{key:`region`,label:`Region`,type:`text`,placeholder:`us-east-1`}],credentialsUrl:`https://console.aws.amazon.com/iam/home#/security_credentials`,credentialsHint:`AWS IAM → Security credentials → Access keys, for a user with S3 + CloudFront invalidation permissions.`},{id:`static_export`,label:`Static export (download)`,description:`No vendor — packages the build as a downloadable archive for self-hosting anywhere else.`,credentialFields:[]}],Eh=[Rm,Jm,Km,Om,Pm,om,Fm,pm({id:`glm`,label:`ZhipuAI (GLM)`,description:`Zhipu AI's GLM model family.`,configKey:`glmApiKey`,defaultModel:`glm-4-flash`,fallbackModels:[`glm-4-flash`,`glm-4`,`glm-z1-preview`,`glm-z1-plus`,`glm-4-long`],baseUrl:`https://open.bigmodel.cn/api/paas/v4`,dashboardUrl:`https://bigmodel.cn/usercenter/apikeys`,credentialsHint:`Zhipu BigModel → User Center → API Keys → Create Key.`}),Lm],Dh=e=>({id:e.id,label:e.label,description:e.description??``,credentialFields:e.credentialFields??[{key:`apiKey`,label:`API Key`,type:`password`}],credentialsUrl:e.dashboardUrl,credentialsHint:e.credentialsHint}),Oh=[...Eh.map(Dh),Dm],kh={id:`openai-compatible`,label:`OpenAI-compatible`,description:`Any OpenAI-compatible endpoint (self-hosted or third-party).`,credentialFields:[{key:`apiKey`,label:`API Key`,type:`password`},{key:`baseUrl`,label:`Base URL`,type:`text`,placeholder:`https://api.example.com/v1`}]},Ah=e=>{let t=[],n=e?.cloudflare?.accountId?.trim();n&&t.push(Em({accountId:n,defaultModel:e?.cloudflare?.defaultModel?.trim()||void 0,includePaidModels:e?.cloudflare?.includePaidModels}));let r=e?.openAICompatible?.baseUrl?.trim();return r?[...t,pm({id:`openai-compatible`,label:e?.openAICompatible?.label?.trim()||`OpenAI-compatible`,description:`Any OpenAI-compatible endpoint (self-hosted or third-party).`,configKey:`openAICompatible`,requiredConfigKeys:[`ai.openAICompatible.apiKey`,`ai.openAICompatible.baseUrl`],defaultModel:e?.openAICompatible?.defaultModel?.trim()||`default`,fallbackModels:e?.openAICompatible?.fallbackModels?.filter(Boolean)||[`default`],baseUrl:r,modelsUrl:e?.openAICompatible?.modelsUrl?.trim()||void 0,chatCompletionsUrl:e?.openAICompatible?.chatCompletionsUrl?.trim()||void 0})]:t},jh=e=>e?[...Eh,...Ah(e)].reduce((t,n)=>{let r=n.id===`openai-compatible`?e.openAICompatible?.apiKey?.trim()||``:n.id===`cloudflare`?e.cloudflare?.apiToken?.trim()||``:typeof n.configKey==`string`&&typeof e[n.configKey]==`string`?String(e[n.configKey]||``).trim():``;return r&&(t[n.id]=new lc(n,r)),t},{}):{},Mh=void 0;typeof ei==`function`&&ei(e=>{Mh=e.google});var Nh={ita:`geoTargetConstants/2380`,rome:`geoTargetConstants/1033236`,mil:`geoTargetConstants/1033239`,nap:`geoTargetConstants/1033245`,tor:`geoTargetConstants/1033247`},Ph={it:`languageConstants/1000`,en:`languageConstants/1001`,fr:`languageConstants/1002`,es:`languageConstants/1003`,de:`languageConstants/1005`};function Fh(e){return Nh[e.toLowerCase()]||`geoTargetConstants/2380`}function Ih(e){return Ph[e.toLowerCase()]||`languageConstants/1000`}async function Lh({keyword:e,googleAdsAccountId:t,geoCode:n=`ita`,languageCode:r=`it`}){if(!Mh?.developerToken)return console.error(`
|
|
20
20
|
❌ Google Ads API: developerToken non configurato.
|
|
21
21
|
|
|
22
22
|
Per ottenere un developerToken segui questi passaggi:
|