mirror of
https://github.com/multipleof4/sune.git
synced 2026-04-07 02:52:14 +00:00
This build was committed by a bot.
This commit is contained in:
@@ -235,78 +235,7 @@ var generateTitleWithAI = async (messages) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
//#region \0vite/preload-helper.js
|
//#region src/dom.js
|
||||||
var scriptRel = "modulepreload";
|
|
||||||
var assetsURL = function(dep) {
|
|
||||||
return "/" + dep;
|
|
||||||
};
|
|
||||||
var seen = {};
|
|
||||||
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
||||||
let promise = Promise.resolve();
|
|
||||||
if (deps && deps.length > 0) {
|
|
||||||
const links = document.getElementsByTagName("link");
|
|
||||||
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
|
||||||
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
||||||
function allSettled(promises) {
|
|
||||||
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
|
||||||
status: "fulfilled",
|
|
||||||
value
|
|
||||||
}), (reason) => ({
|
|
||||||
status: "rejected",
|
|
||||||
reason
|
|
||||||
}))));
|
|
||||||
}
|
|
||||||
promise = allSettled(deps.map((dep) => {
|
|
||||||
dep = assetsURL(dep, importerUrl);
|
|
||||||
if (dep in seen) return;
|
|
||||||
seen[dep] = true;
|
|
||||||
const isCss = dep.endsWith(".css");
|
|
||||||
const cssSelector = isCss ? "[rel=\"stylesheet\"]" : "";
|
|
||||||
if (!!importerUrl) for (let i = links.length - 1; i >= 0; i--) {
|
|
||||||
const link = links[i];
|
|
||||||
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
|
||||||
}
|
|
||||||
else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return;
|
|
||||||
const link = document.createElement("link");
|
|
||||||
link.rel = isCss ? "stylesheet" : scriptRel;
|
|
||||||
if (!isCss) link.as = "script";
|
|
||||||
link.crossOrigin = "";
|
|
||||||
link.href = dep;
|
|
||||||
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
|
||||||
document.head.appendChild(link);
|
|
||||||
if (isCss) return new Promise((res, rej) => {
|
|
||||||
link.addEventListener("load", res);
|
|
||||||
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
function handlePreloadError(err) {
|
|
||||||
const e = new Event("vite:preloadError", { cancelable: true });
|
|
||||||
e.payload = err;
|
|
||||||
window.dispatchEvent(e);
|
|
||||||
if (!e.defaultPrevented) throw err;
|
|
||||||
}
|
|
||||||
return promise.then((res) => {
|
|
||||||
for (const item of res || []) {
|
|
||||||
if (item.status !== "rejected") continue;
|
|
||||||
handlePreloadError(item.reason);
|
|
||||||
}
|
|
||||||
return baseModule().catch(handlePreloadError);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
//#endregion
|
|
||||||
//#region src/main.js
|
|
||||||
(() => {
|
|
||||||
let k, v = visualViewport;
|
|
||||||
const f = () => {
|
|
||||||
removeEventListener("popstate", f), document.activeElement?.blur();
|
|
||||||
};
|
|
||||||
v.onresize = () => {
|
|
||||||
let o = v.height < innerHeight;
|
|
||||||
o != k && ((k = o) ? (history.pushState({ k: 1 }, ""), addEventListener("popstate", f)) : (removeEventListener("popstate", f), history.state?.k && history.back()));
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
var DEFAULT_MODEL = "anthropic/claude-opus-4.6";
|
|
||||||
var el = window.el = Object.fromEntries([
|
var el = window.el = Object.fromEntries([
|
||||||
"topbar",
|
"topbar",
|
||||||
"chat",
|
"chat",
|
||||||
@@ -411,17 +340,22 @@ var el = window.el = Object.fromEntries([
|
|||||||
"threadBackBtn",
|
"threadBackBtn",
|
||||||
"threadFolderBtn",
|
"threadFolderBtn",
|
||||||
"threadSyncBtn"
|
"threadSyncBtn"
|
||||||
].map((id) => [id, $("#" + id)[0]]));
|
].map((id) => [id, document.getElementById(id)]));
|
||||||
var icons = () => window.lucide && lucide.createIcons();
|
//#endregion
|
||||||
var haptic = () => /android/i.test(navigator.userAgent) && navigator.vibrate?.(1);
|
//#region src/utils.js
|
||||||
var clamp = (v, min, max) => Math.max(min, Math.min(max, v)), num = (v, d) => v == null || v === "" || isNaN(+v) ? d : +v, int = (v, d) => v == null || v === "" || isNaN(parseInt(v)) ? d : parseInt(v), gid = () => Math.random().toString(36).slice(2, 9), esc = (s) => String(s).replace(/[&<>'"`]/g, (c) => ({
|
var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
||||||
|
var num = (v, d) => v == null || v === "" || isNaN(+v) ? d : +v;
|
||||||
|
var int = (v, d) => v == null || v === "" || isNaN(parseInt(v)) ? d : parseInt(v);
|
||||||
|
var gid = () => Math.random().toString(36).slice(2, 9);
|
||||||
|
var esc = (s) => String(s).replace(/[&<>'"`]/g, (c) => ({
|
||||||
"&": "&",
|
"&": "&",
|
||||||
"<": "<",
|
"<": "<",
|
||||||
">": ">",
|
">": ">",
|
||||||
"\"": """,
|
"\"": """,
|
||||||
"'": "'",
|
"'": "'",
|
||||||
"`": "`"
|
"`": "`"
|
||||||
})[c]), positionPopover = (a, p) => {
|
})[c]);
|
||||||
|
var positionPopover = (a, p) => {
|
||||||
const r = a.getBoundingClientRect();
|
const r = a.getBoundingClientRect();
|
||||||
p.style.top = `${r.bottom + p.offsetHeight + 4 > window.innerHeight ? r.top - p.offsetHeight - 4 : r.bottom + 4}px`;
|
p.style.top = `${r.bottom + p.offsetHeight + 4 > window.innerHeight ? r.top - p.offsetHeight - 4 : r.bottom + 4}px`;
|
||||||
p.style.left = `${Math.max(8, Math.min(r.right - p.offsetWidth, window.innerWidth - p.offsetWidth - 8))}px`;
|
p.style.left = `${Math.max(8, Math.min(r.right - p.offsetWidth, window.innerWidth - p.offsetWidth - 8))}px`;
|
||||||
@@ -464,7 +398,129 @@ var imgToWebp = (f, D = 128, q = 80) => new Promise((r, j) => {
|
|||||||
i.src = URL.createObjectURL(f);
|
i.src = URL.createObjectURL(f);
|
||||||
});
|
});
|
||||||
var b64 = (x) => x.split(",")[1] || "";
|
var b64 = (x) => x.split(",")[1] || "";
|
||||||
var utob = (s) => btoa(unescape(encodeURIComponent(s))), btou = (s) => decodeURIComponent(escape(atob(s.replace(/\s/g, ""))));
|
var utob = (s) => btoa(unescape(encodeURIComponent(s)));
|
||||||
|
var btou = (s) => decodeURIComponent(escape(atob(s.replace(/\s/g, ""))));
|
||||||
|
function partsToText(m) {
|
||||||
|
if (!m) return "";
|
||||||
|
const c = m.content, i = m.images;
|
||||||
|
let t = Array.isArray(c) ? c.map((p) => p?.type === "text" ? p.text : p?.type === "image_url" ? `` : p?.type === "file" ? `[${p.file?.filename || "file"}]` : p?.type === "input_audio" ? `(audio:${p.input_audio?.format || ""})` : "").join("\n") : String(c || "");
|
||||||
|
if (Array.isArray(i)) t += i.map((x) => `\n\n`).join("");
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function dl(name, obj) {
|
||||||
|
const blob = new Blob([JSON.stringify(obj, null, 2)], { type: name.endsWith(".sune") ? "application/octet-stream" : "application/json" }), url = URL.createObjectURL(blob), a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = name;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
var ts = () => {
|
||||||
|
const d = /* @__PURE__ */ new Date(), p = (n) => String(n).padStart(2, "0");
|
||||||
|
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/user.js
|
||||||
|
var USER = {
|
||||||
|
get PAT() {
|
||||||
|
return this.githubToken;
|
||||||
|
},
|
||||||
|
get name() {
|
||||||
|
return localStorage.getItem("user_name") || "Anon";
|
||||||
|
},
|
||||||
|
set name(v) {
|
||||||
|
localStorage.setItem("user_name", v || "");
|
||||||
|
},
|
||||||
|
get avatar() {
|
||||||
|
return localStorage.getItem("user_avatar") || "";
|
||||||
|
},
|
||||||
|
set avatar(v) {
|
||||||
|
localStorage.setItem("user_avatar", v || "");
|
||||||
|
},
|
||||||
|
get provider() {
|
||||||
|
return localStorage.getItem("provider") || "openrouter";
|
||||||
|
},
|
||||||
|
set provider(v) {
|
||||||
|
localStorage.setItem("provider", [
|
||||||
|
"openai",
|
||||||
|
"google",
|
||||||
|
"claude"
|
||||||
|
].includes(v) ? v : "openrouter");
|
||||||
|
},
|
||||||
|
get apiKeyOpenRouter() {
|
||||||
|
return localStorage.getItem("openrouter_api_key") || "";
|
||||||
|
},
|
||||||
|
set apiKeyOpenRouter(v) {
|
||||||
|
localStorage.setItem("openrouter_api_key", v || "");
|
||||||
|
},
|
||||||
|
get apiKeyOpenAI() {
|
||||||
|
return localStorage.getItem("openai_api_key") || "";
|
||||||
|
},
|
||||||
|
set apiKeyOpenAI(v) {
|
||||||
|
localStorage.setItem("openai_api_key", v || "");
|
||||||
|
},
|
||||||
|
get apiKeyGoogle() {
|
||||||
|
return localStorage.getItem("google_api_key") || "";
|
||||||
|
},
|
||||||
|
set apiKeyGoogle(v) {
|
||||||
|
localStorage.setItem("google_api_key", v || "");
|
||||||
|
},
|
||||||
|
get apiKeyClaude() {
|
||||||
|
return localStorage.getItem("claude_api_key") || "";
|
||||||
|
},
|
||||||
|
set apiKeyClaude(v) {
|
||||||
|
localStorage.setItem("claude_api_key", v || "");
|
||||||
|
},
|
||||||
|
get apiKeyCloudflare() {
|
||||||
|
return localStorage.getItem("cloudflare_api_key") || "";
|
||||||
|
},
|
||||||
|
set apiKeyCloudflare(v) {
|
||||||
|
localStorage.setItem("cloudflare_api_key", v || "");
|
||||||
|
},
|
||||||
|
get apiKey() {
|
||||||
|
const p = this.provider;
|
||||||
|
return p === "openai" ? this.apiKeyOpenAI : p === "google" ? this.apiKeyGoogle : p === "claude" ? this.apiKeyClaude : p === "cloudflare" ? this.apiKeyCloudflare : this.apiKeyOpenRouter;
|
||||||
|
},
|
||||||
|
set apiKey(v) {
|
||||||
|
const p = this.provider;
|
||||||
|
if (p === "openai") this.apiKeyOpenAI = v;
|
||||||
|
else if (p === "google") this.apiKeyGoogle = v;
|
||||||
|
else if (p === "claude") this.apiKeyClaude = v;
|
||||||
|
else if (p === "cloudflare") this.apiKeyCloudflare = v;
|
||||||
|
else this.apiKeyOpenRouter = v;
|
||||||
|
},
|
||||||
|
get masterPrompt() {
|
||||||
|
return localStorage.getItem("master_prompt") || "Always respond using markdown.";
|
||||||
|
},
|
||||||
|
set masterPrompt(v) {
|
||||||
|
localStorage.setItem("master_prompt", v || "");
|
||||||
|
},
|
||||||
|
get titleModel() {
|
||||||
|
return localStorage.getItem("title_model") ?? "or:amazon/nova-micro-v1";
|
||||||
|
},
|
||||||
|
set titleModel(v) {
|
||||||
|
localStorage.setItem("title_model", v || "");
|
||||||
|
},
|
||||||
|
get githubToken() {
|
||||||
|
return localStorage.getItem("gh_token") || "";
|
||||||
|
},
|
||||||
|
set githubToken(v) {
|
||||||
|
localStorage.setItem("gh_token", v || "");
|
||||||
|
},
|
||||||
|
get gcpSA() {
|
||||||
|
try {
|
||||||
|
return JSON.parse(localStorage.getItem("gcp_sa_json") || "null");
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set gcpSA(v) {
|
||||||
|
localStorage.setItem("gcp_sa_json", v ? JSON.stringify(v) : "");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/github.js
|
||||||
var ghApi = async (path, method = "GET", body = null) => {
|
var ghApi = async (path, method = "GET", body = null) => {
|
||||||
const t = USER.githubToken;
|
const t = USER.githubToken;
|
||||||
if (!t) throw new Error("No GH token");
|
if (!t) throw new Error("No GH token");
|
||||||
@@ -490,6 +546,231 @@ var parseGhUrl = (u) => {
|
|||||||
apiPath: `${owner}/${repo}/contents${path ? "/" + path : ""}`
|
apiPath: `${owner}/${repo}/contents${path ? "/" + path : ""}`
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/markdown.js
|
||||||
|
var md = window.md = window.markdownit({
|
||||||
|
html: false,
|
||||||
|
linkify: true,
|
||||||
|
typographer: true,
|
||||||
|
breaks: true
|
||||||
|
}).use(mathjax3);
|
||||||
|
function enhanceCodeBlocks(root, doHL = true) {
|
||||||
|
window.$(root).find("pre>code").each((i, code) => {
|
||||||
|
if (code.textContent.length > 2e5) return;
|
||||||
|
const $pre = window.$(code).parent().addClass("relative rounded-xl border border-gray-200");
|
||||||
|
if (!$pre.find(".code-actions").length) {
|
||||||
|
const len = code.textContent.length, countText = len >= 1e3 ? (len / 1e3).toFixed(1) + "K" : len;
|
||||||
|
const $btn = window.$("<button class=\"bg-slate-900 text-white rounded-lg py-1 px-2 text-xs opacity-85\">Copy</button>").on("click", async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(code.innerText);
|
||||||
|
$btn.text("Copied");
|
||||||
|
setTimeout(() => $btn.text("Copy"), 1200);
|
||||||
|
} catch {}
|
||||||
|
});
|
||||||
|
const $container = window.$("<div class=\"code-actions absolute top-2 right-2 flex items-center gap-2\"></div>");
|
||||||
|
$container.append(window.$(`<span class="text-xs text-gray-500">${countText} chars</span>`), $btn);
|
||||||
|
$pre.append($container);
|
||||||
|
}
|
||||||
|
if (doHL && window.hljs && code.textContent.length < 1e5) window.hljs.highlightElement(code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var renderMarkdown = window.renderMarkdown = function(node, text, opt = {
|
||||||
|
enhance: true,
|
||||||
|
highlight: true
|
||||||
|
}) {
|
||||||
|
node.innerHTML = md.render(text);
|
||||||
|
if (opt.enhance) enhanceCodeBlocks(node, opt.highlight);
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/keyboard.js
|
||||||
|
function kbUpdate() {
|
||||||
|
const vv = window.visualViewport;
|
||||||
|
const overlap = vv ? Math.max(0, window.innerHeight - (vv.height + vv.offsetTop)) : 0;
|
||||||
|
document.documentElement.style.setProperty("--kb", overlap + "px");
|
||||||
|
const fh = el.footer.getBoundingClientRect().height;
|
||||||
|
document.documentElement.style.setProperty("--footer-h", fh + "px");
|
||||||
|
el.footer.style.transform = "translateY(" + -overlap + "px)";
|
||||||
|
el.chat.style.scrollPaddingBottom = fh + overlap + 16 + "px";
|
||||||
|
}
|
||||||
|
function kbBind() {
|
||||||
|
if (window.visualViewport) ["resize", "scroll"].forEach((ev) => window.visualViewport.addEventListener(ev, () => kbUpdate(), { passive: true }));
|
||||||
|
window.$(window).on("resize orientationchange", () => setTimeout(kbUpdate, 50));
|
||||||
|
window.$(el.input).on("focus click", () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
kbUpdate();
|
||||||
|
el.input.scrollIntoView({
|
||||||
|
block: "nearest",
|
||||||
|
behavior: "smooth"
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region src/attachments.js
|
||||||
|
async function toAttach(file) {
|
||||||
|
if (!file) return null;
|
||||||
|
if (file instanceof File) {
|
||||||
|
const name = file.name || "file", mime = (file.type || "application/octet-stream").toLowerCase();
|
||||||
|
if (/^image\//.test(mime) || /\.(png|jpe?g|webp|gif)$/i.test(name)) return {
|
||||||
|
type: "image_url",
|
||||||
|
image_url: { url: mime === "image/webp" || /\.webp$/i.test(name) ? await asDataURL(file) : await imgToWebp(file, 2048, 94) }
|
||||||
|
};
|
||||||
|
if (mime === "application/pdf" || /\.pdf$/i.test(name)) {
|
||||||
|
const bin = b64(await asDataURL(file));
|
||||||
|
return {
|
||||||
|
type: "file",
|
||||||
|
file: {
|
||||||
|
filename: name.endsWith(".pdf") ? name : name + ".pdf",
|
||||||
|
file_data: bin
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (/^audio\//.test(mime) || /\.(wav|mp3)$/i.test(name)) return {
|
||||||
|
type: "input_audio",
|
||||||
|
input_audio: {
|
||||||
|
data: b64(await asDataURL(file)),
|
||||||
|
format: /mp3/.test(mime) || /\.mp3$/i.test(name) ? "mp3" : "wav"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
type: "file",
|
||||||
|
file: {
|
||||||
|
filename: name,
|
||||||
|
file_data: b64(await asDataURL(file))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (file && file.name == null && file.data) {
|
||||||
|
const name = file.name || "file", mime = (file.mime || "application/octet-stream").toLowerCase();
|
||||||
|
if (/^image\//.test(mime)) return {
|
||||||
|
type: "image_url",
|
||||||
|
image_url: { url: `data:${mime};base64,${file.data}` }
|
||||||
|
};
|
||||||
|
if (mime === "application/pdf") return {
|
||||||
|
type: "file",
|
||||||
|
file: {
|
||||||
|
filename: name,
|
||||||
|
file_data: file.data
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (/^audio\//.test(mime)) {
|
||||||
|
const fmt = /mp3/.test(mime) ? "mp3" : "wav";
|
||||||
|
return {
|
||||||
|
type: "input_audio",
|
||||||
|
input_audio: {
|
||||||
|
data: file.data,
|
||||||
|
format: fmt
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "file",
|
||||||
|
file: {
|
||||||
|
filename: name,
|
||||||
|
file_data: file.data
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region src/threads-utils.js
|
||||||
|
var titleFrom = (t) => {
|
||||||
|
if (!t) return "Untitled";
|
||||||
|
return (typeof t === "string" ? t : Array.isArray(t) ? partsToText({ content: t }) : "Untitled").replace(/\s+/g, " ").trim().slice(0, 60) || "Untitled";
|
||||||
|
};
|
||||||
|
var serializeThreadName = (t) => {
|
||||||
|
const s = (t.title || "Untitled").replace(/[^a-zA-Z0-9]/g, "_").slice(0, 150);
|
||||||
|
return `${t.pinned ? "1" : "0"}-${t.updatedAt || Date.now()}-${t.id}-${s}.json`;
|
||||||
|
};
|
||||||
|
var deserializeThreadName = (n) => {
|
||||||
|
const p = n.replace(".json", "").split("-");
|
||||||
|
if (p.length < 4) return null;
|
||||||
|
return {
|
||||||
|
pinned: p[0] === "1",
|
||||||
|
updatedAt: parseInt(p[1]),
|
||||||
|
id: p[2],
|
||||||
|
title: p.slice(3).join("-").replace(/_/g, " "),
|
||||||
|
status: "synced",
|
||||||
|
type: "thread"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region \0vite/preload-helper.js
|
||||||
|
var scriptRel = "modulepreload";
|
||||||
|
var assetsURL = function(dep) {
|
||||||
|
return "/" + dep;
|
||||||
|
};
|
||||||
|
var seen = {};
|
||||||
|
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
||||||
|
let promise = Promise.resolve();
|
||||||
|
if (deps && deps.length > 0) {
|
||||||
|
const links = document.getElementsByTagName("link");
|
||||||
|
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
||||||
|
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
||||||
|
function allSettled(promises) {
|
||||||
|
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
||||||
|
status: "fulfilled",
|
||||||
|
value
|
||||||
|
}), (reason) => ({
|
||||||
|
status: "rejected",
|
||||||
|
reason
|
||||||
|
}))));
|
||||||
|
}
|
||||||
|
promise = allSettled(deps.map((dep) => {
|
||||||
|
dep = assetsURL(dep, importerUrl);
|
||||||
|
if (dep in seen) return;
|
||||||
|
seen[dep] = true;
|
||||||
|
const isCss = dep.endsWith(".css");
|
||||||
|
const cssSelector = isCss ? "[rel=\"stylesheet\"]" : "";
|
||||||
|
if (!!importerUrl) for (let i = links.length - 1; i >= 0; i--) {
|
||||||
|
const link = links[i];
|
||||||
|
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
||||||
|
}
|
||||||
|
else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return;
|
||||||
|
const link = document.createElement("link");
|
||||||
|
link.rel = isCss ? "stylesheet" : scriptRel;
|
||||||
|
if (!isCss) link.as = "script";
|
||||||
|
link.crossOrigin = "";
|
||||||
|
link.href = dep;
|
||||||
|
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
||||||
|
document.head.appendChild(link);
|
||||||
|
if (isCss) return new Promise((res, rej) => {
|
||||||
|
link.addEventListener("load", res);
|
||||||
|
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function handlePreloadError(err) {
|
||||||
|
const e = new Event("vite:preloadError", { cancelable: true });
|
||||||
|
e.payload = err;
|
||||||
|
window.dispatchEvent(e);
|
||||||
|
if (!e.defaultPrevented) throw err;
|
||||||
|
}
|
||||||
|
return promise.then((res) => {
|
||||||
|
for (const item of res || []) {
|
||||||
|
if (item.status !== "rejected") continue;
|
||||||
|
handlePreloadError(item.reason);
|
||||||
|
}
|
||||||
|
return baseModule().catch(handlePreloadError);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/main.js
|
||||||
|
(() => {
|
||||||
|
let k, v = visualViewport;
|
||||||
|
const f = () => {
|
||||||
|
removeEventListener("popstate", f), document.activeElement?.blur();
|
||||||
|
};
|
||||||
|
v.onresize = () => {
|
||||||
|
let o = v.height < innerHeight;
|
||||||
|
o != k && ((k = o) ? (history.pushState({ k: 1 }, ""), addEventListener("popstate", f)) : (removeEventListener("popstate", f), history.state?.k && history.back()));
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var DEFAULT_MODEL = "anthropic/claude-opus-4.6";
|
||||||
|
var icons = () => window.lucide && lucide.createIcons();
|
||||||
|
var haptic = () => /android/i.test(navigator.userAgent) && navigator.vibrate?.(1);
|
||||||
var su = {
|
var su = {
|
||||||
key: "sunes_v1",
|
key: "sunes_v1",
|
||||||
activeKey: "active_sune_id",
|
activeKey: "active_sune_id",
|
||||||
@@ -788,33 +1069,6 @@ var renderSidebar = window.renderSidebar = () => {
|
|||||||
el.suneList.innerHTML = list.map(suneRow).join("");
|
el.suneList.innerHTML = list.map(suneRow).join("");
|
||||||
icons();
|
icons();
|
||||||
};
|
};
|
||||||
function enhanceCodeBlocks(root, doHL = true) {
|
|
||||||
$(root).find("pre>code").each((i, code) => {
|
|
||||||
if (code.textContent.length > 2e5) return;
|
|
||||||
const $pre = $(code).parent().addClass("relative rounded-xl border border-gray-200");
|
|
||||||
if (!$pre.find(".code-actions").length) {
|
|
||||||
const len = code.textContent.length, countText = len >= 1e3 ? (len / 1e3).toFixed(1) + "K" : len;
|
|
||||||
const $btn = $("<button class=\"bg-slate-900 text-white rounded-lg py-1 px-2 text-xs opacity-85\">Copy</button>").on("click", async (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(code.innerText);
|
|
||||||
$btn.text("Copied");
|
|
||||||
setTimeout(() => $btn.text("Copy"), 1200);
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
const $container = $("<div class=\"code-actions absolute top-2 right-2 flex items-center gap-2\"></div>");
|
|
||||||
$container.append($(`<span class="text-xs text-gray-500">${countText} chars</span>`), $btn);
|
|
||||||
$pre.append($container);
|
|
||||||
}
|
|
||||||
if (doHL && window.hljs && code.textContent.length < 1e5) hljs.highlightElement(code);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var md = window.markdownit({
|
|
||||||
html: false,
|
|
||||||
linkify: true,
|
|
||||||
typographer: true,
|
|
||||||
breaks: true
|
|
||||||
}).use(mathjax3);
|
|
||||||
var getSuneLabel = (m) => {
|
var getSuneLabel = (m) => {
|
||||||
return `${m && m.sune_name || SUNE.name} · ${getModelShort(m && m.model)}`;
|
return `${m && m.sune_name || SUNE.name} · ${getModelShort(m && m.model)}`;
|
||||||
};
|
};
|
||||||
@@ -858,20 +1112,6 @@ function msgRow(m) {
|
|||||||
});
|
});
|
||||||
return $row.find(".msg-bubble")[0];
|
return $row.find(".msg-bubble")[0];
|
||||||
}
|
}
|
||||||
var renderMarkdown = window.renderMarkdown = function(node, text, opt = {
|
|
||||||
enhance: true,
|
|
||||||
highlight: true
|
|
||||||
}) {
|
|
||||||
node.innerHTML = md.render(text);
|
|
||||||
if (opt.enhance) enhanceCodeBlocks(node, opt.highlight);
|
|
||||||
};
|
|
||||||
function partsToText(m) {
|
|
||||||
if (!m) return "";
|
|
||||||
const c = m.content, i = m.images;
|
|
||||||
let t = Array.isArray(c) ? c.map((p) => p?.type === "text" ? p.text : p?.type === "image_url" ? `` : p?.type === "file" ? `[${p.file?.filename || "file"}]` : p?.type === "input_audio" ? `(audio:${p.input_audio?.format || ""})` : "").join("\n") : String(c || "");
|
|
||||||
if (Array.isArray(i)) t += i.map((x) => `\n\n`).join("");
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
var addMessage = window.addMessage = function(m, track = true) {
|
var addMessage = window.addMessage = function(m, track = true) {
|
||||||
m.id = m.id || gid();
|
m.id = m.id || gid();
|
||||||
if (!Array.isArray(m.content) && m.content != null) m.content = [{
|
if (!Array.isArray(m.content) && m.content != null) m.content = [{
|
||||||
@@ -939,26 +1179,6 @@ function setBtnSend() {
|
|||||||
function localDemoReply() {
|
function localDemoReply() {
|
||||||
return "Tip: open the sidebar → Account & Backup to set your API key.";
|
return "Tip: open the sidebar → Account & Backup to set your API key.";
|
||||||
}
|
}
|
||||||
var titleFrom = (t) => {
|
|
||||||
if (!t) return "Untitled";
|
|
||||||
return (typeof t === "string" ? t : Array.isArray(t) ? partsToText({ content: t }) : "Untitled").replace(/\s+/g, " ").trim().slice(0, 60) || "Untitled";
|
|
||||||
};
|
|
||||||
var serializeThreadName = (t) => {
|
|
||||||
const s = (t.title || "Untitled").replace(/[^a-zA-Z0-9]/g, "_").slice(0, 150);
|
|
||||||
return `${t.pinned ? "1" : "0"}-${t.updatedAt || Date.now()}-${t.id}-${s}.json`;
|
|
||||||
};
|
|
||||||
var deserializeThreadName = (n) => {
|
|
||||||
const p = n.replace(".json", "").split("-");
|
|
||||||
if (p.length < 4) return null;
|
|
||||||
return {
|
|
||||||
pinned: p[0] === "1",
|
|
||||||
updatedAt: parseInt(p[1]),
|
|
||||||
id: p[2],
|
|
||||||
title: p.slice(3).join("-").replace(/_/g, " "),
|
|
||||||
status: "synced",
|
|
||||||
type: "thread"
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var TKEY = "threads_v1", THREAD = window.THREAD = {
|
var TKEY = "threads_v1", THREAD = window.THREAD = {
|
||||||
list: [],
|
list: [],
|
||||||
load: async function() {
|
load: async function() {
|
||||||
@@ -1302,72 +1522,6 @@ function updateAttachBadge() {
|
|||||||
el.attachBadge.textContent = String(n);
|
el.attachBadge.textContent = String(n);
|
||||||
el.attachBadge.classList.toggle("hidden", n === 0);
|
el.attachBadge.classList.toggle("hidden", n === 0);
|
||||||
}
|
}
|
||||||
async function toAttach(file) {
|
|
||||||
if (!file) return null;
|
|
||||||
if (file instanceof File) {
|
|
||||||
const name = file.name || "file", mime = (file.type || "application/octet-stream").toLowerCase();
|
|
||||||
if (/^image\//.test(mime) || /\.(png|jpe?g|webp|gif)$/i.test(name)) return {
|
|
||||||
type: "image_url",
|
|
||||||
image_url: { url: mime === "image/webp" || /\.webp$/i.test(name) ? await asDataURL(file) : await imgToWebp(file, 2048, 94) }
|
|
||||||
};
|
|
||||||
if (mime === "application/pdf" || /\.pdf$/i.test(name)) {
|
|
||||||
const bin = b64(await asDataURL(file));
|
|
||||||
return {
|
|
||||||
type: "file",
|
|
||||||
file: {
|
|
||||||
filename: name.endsWith(".pdf") ? name : name + ".pdf",
|
|
||||||
file_data: bin
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (/^audio\//.test(mime) || /\.(wav|mp3)$/i.test(name)) return {
|
|
||||||
type: "input_audio",
|
|
||||||
input_audio: {
|
|
||||||
data: b64(await asDataURL(file)),
|
|
||||||
format: /mp3/.test(mime) || /\.mp3$/i.test(name) ? "mp3" : "wav"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
type: "file",
|
|
||||||
file: {
|
|
||||||
filename: name,
|
|
||||||
file_data: b64(await asDataURL(file))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (file && file.name == null && file.data) {
|
|
||||||
const name = file.name || "file", mime = (file.mime || "application/octet-stream").toLowerCase();
|
|
||||||
if (/^image\//.test(mime)) return {
|
|
||||||
type: "image_url",
|
|
||||||
image_url: { url: `data:${mime};base64,${file.data}` }
|
|
||||||
};
|
|
||||||
if (mime === "application/pdf") return {
|
|
||||||
type: "file",
|
|
||||||
file: {
|
|
||||||
filename: name,
|
|
||||||
file_data: file.data
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (/^audio\//.test(mime)) {
|
|
||||||
const fmt = /mp3/.test(mime) ? "mp3" : "wav";
|
|
||||||
return {
|
|
||||||
type: "input_audio",
|
|
||||||
input_audio: {
|
|
||||||
data: file.data,
|
|
||||||
format: fmt
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: "file",
|
|
||||||
file: {
|
|
||||||
filename: name,
|
|
||||||
file_data: file.data
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$(el.attachBtn).on("click", () => {
|
$(el.attachBtn).on("click", () => {
|
||||||
if (state.busy) return;
|
if (state.busy) return;
|
||||||
if (state.attachments.length) {
|
if (state.attachments.length) {
|
||||||
@@ -1599,19 +1753,6 @@ $(el.newSuneBtn).on("click", async () => {
|
|||||||
document.getElementById("sidebarLeft").classList.add("-translate-x-full");
|
document.getElementById("sidebarLeft").classList.add("-translate-x-full");
|
||||||
document.getElementById("sidebarOverlayLeft").classList.add("hidden");
|
document.getElementById("sidebarOverlayLeft").classList.add("hidden");
|
||||||
});
|
});
|
||||||
function dl(name, obj) {
|
|
||||||
const blob = new Blob([JSON.stringify(obj, null, 2)], { type: name.endsWith(".sune") ? "application/octet-stream" : "application/json" }), url = URL.createObjectURL(blob), a = $("<a>").prop({
|
|
||||||
href: url,
|
|
||||||
download: name
|
|
||||||
}).appendTo("body");
|
|
||||||
a.get(0).click();
|
|
||||||
a.remove();
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
}
|
|
||||||
var ts = () => {
|
|
||||||
const d = /* @__PURE__ */ new Date(), p = (n) => String(n).padStart(2, "0");
|
|
||||||
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
|
|
||||||
};
|
|
||||||
var importMode = null;
|
var importMode = null;
|
||||||
$(el.sunesExportOption).on("click", () => {
|
$(el.sunesExportOption).on("click", () => {
|
||||||
dl(`sunes-${ts()}.sune`, {
|
dl(`sunes-${ts()}.sune`, {
|
||||||
@@ -1698,28 +1839,6 @@ $(el.importInput).on("change", async () => {
|
|||||||
importMode = null;
|
importMode = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
function kbUpdate() {
|
|
||||||
const vv = window.visualViewport;
|
|
||||||
const overlap = vv ? Math.max(0, window.innerHeight - (vv.height + vv.offsetTop)) : 0;
|
|
||||||
document.documentElement.style.setProperty("--kb", overlap + "px");
|
|
||||||
const fh = el.footer.getBoundingClientRect().height;
|
|
||||||
document.documentElement.style.setProperty("--footer-h", fh + "px");
|
|
||||||
el.footer.style.transform = "translateY(" + -overlap + "px)";
|
|
||||||
el.chat.style.scrollPaddingBottom = fh + overlap + 16 + "px";
|
|
||||||
}
|
|
||||||
function kbBind() {
|
|
||||||
if (window.visualViewport) ["resize", "scroll"].forEach((ev) => visualViewport.addEventListener(ev, () => kbUpdate(), { passive: true }));
|
|
||||||
$(window).on("resize orientationchange", () => setTimeout(kbUpdate, 50));
|
|
||||||
$(el.input).on("focus click", () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
kbUpdate();
|
|
||||||
el.input.scrollIntoView({
|
|
||||||
block: "nearest",
|
|
||||||
behavior: "smooth"
|
|
||||||
});
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function activeMeta() {
|
function activeMeta() {
|
||||||
return {
|
return {
|
||||||
sune_name: SUNE.name,
|
sune_name: SUNE.name,
|
||||||
@@ -1727,8 +1846,8 @@ function activeMeta() {
|
|||||||
avatar: SUNE.avatar
|
avatar: SUNE.avatar
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var USER = window.USER = {
|
window.USER = USER;
|
||||||
log: async (s) => {
|
USER.log = async (s) => {
|
||||||
const t = String(s ?? "").trim();
|
const t = String(s ?? "").trim();
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
await ensureThreadOnFirstUser(t);
|
await ensureThreadOnFirstUser(t);
|
||||||
@@ -1740,8 +1859,8 @@ var USER = window.USER = {
|
|||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
await THREAD.persist();
|
await THREAD.persist();
|
||||||
},
|
};
|
||||||
logMany: async (msgs) => {
|
USER.logMany = async (msgs) => {
|
||||||
if (!Array.isArray(msgs) || !msgs.length) return;
|
if (!Array.isArray(msgs) || !msgs.length) return;
|
||||||
const clean = msgs.map((s) => String(s ?? "").trim()).filter(Boolean);
|
const clean = msgs.map((s) => String(s ?? "").trim()).filter(Boolean);
|
||||||
if (!clean.length) return;
|
if (!clean.length) return;
|
||||||
@@ -1778,102 +1897,6 @@ var USER = window.USER = {
|
|||||||
icons();
|
icons();
|
||||||
});
|
});
|
||||||
await THREAD.persist();
|
await THREAD.persist();
|
||||||
},
|
|
||||||
get PAT() {
|
|
||||||
return this.githubToken;
|
|
||||||
},
|
|
||||||
get name() {
|
|
||||||
return localStorage.getItem("user_name") || "Anon";
|
|
||||||
},
|
|
||||||
set name(v) {
|
|
||||||
localStorage.setItem("user_name", v || "");
|
|
||||||
},
|
|
||||||
get avatar() {
|
|
||||||
return localStorage.getItem("user_avatar") || "";
|
|
||||||
},
|
|
||||||
set avatar(v) {
|
|
||||||
localStorage.setItem("user_avatar", v || "");
|
|
||||||
},
|
|
||||||
get provider() {
|
|
||||||
return localStorage.getItem("provider") || "openrouter";
|
|
||||||
},
|
|
||||||
set provider(v) {
|
|
||||||
localStorage.setItem("provider", [
|
|
||||||
"openai",
|
|
||||||
"google",
|
|
||||||
"claude"
|
|
||||||
].includes(v) ? v : "openrouter");
|
|
||||||
},
|
|
||||||
get apiKeyOpenRouter() {
|
|
||||||
return localStorage.getItem("openrouter_api_key") || "";
|
|
||||||
},
|
|
||||||
set apiKeyOpenRouter(v) {
|
|
||||||
localStorage.setItem("openrouter_api_key", v || "");
|
|
||||||
},
|
|
||||||
get apiKeyOpenAI() {
|
|
||||||
return localStorage.getItem("openai_api_key") || "";
|
|
||||||
},
|
|
||||||
set apiKeyOpenAI(v) {
|
|
||||||
localStorage.setItem("openai_api_key", v || "");
|
|
||||||
},
|
|
||||||
get apiKeyGoogle() {
|
|
||||||
return localStorage.getItem("google_api_key") || "";
|
|
||||||
},
|
|
||||||
set apiKeyGoogle(v) {
|
|
||||||
localStorage.setItem("google_api_key", v || "");
|
|
||||||
},
|
|
||||||
get apiKeyClaude() {
|
|
||||||
return localStorage.getItem("claude_api_key") || "";
|
|
||||||
},
|
|
||||||
set apiKeyClaude(v) {
|
|
||||||
localStorage.setItem("claude_api_key", v || "");
|
|
||||||
},
|
|
||||||
get apiKeyCloudflare() {
|
|
||||||
return localStorage.getItem("cloudflare_api_key") || "";
|
|
||||||
},
|
|
||||||
set apiKeyCloudflare(v) {
|
|
||||||
localStorage.setItem("cloudflare_api_key", v || "");
|
|
||||||
},
|
|
||||||
get apiKey() {
|
|
||||||
const p = this.provider;
|
|
||||||
return p === "openai" ? this.apiKeyOpenAI : p === "google" ? this.apiKeyGoogle : p === "claude" ? this.apiKeyClaude : p === "cloudflare" ? this.apiKeyCloudflare : this.apiKeyOpenRouter;
|
|
||||||
},
|
|
||||||
set apiKey(v) {
|
|
||||||
const p = this.provider;
|
|
||||||
if (p === "openai") this.apiKeyOpenAI = v;
|
|
||||||
else if (p === "google") this.apiKeyGoogle = v;
|
|
||||||
else if (p === "claude") this.apiKeyClaude = v;
|
|
||||||
else if (p === "cloudflare") this.apiKeyCloudflare = v;
|
|
||||||
else this.apiKeyOpenRouter = v;
|
|
||||||
},
|
|
||||||
get masterPrompt() {
|
|
||||||
return localStorage.getItem("master_prompt") || "Always respond using markdown.";
|
|
||||||
},
|
|
||||||
set masterPrompt(v) {
|
|
||||||
localStorage.setItem("master_prompt", v || "");
|
|
||||||
},
|
|
||||||
get titleModel() {
|
|
||||||
return localStorage.getItem("title_model") ?? "or:amazon/nova-micro-v1";
|
|
||||||
},
|
|
||||||
set titleModel(v) {
|
|
||||||
localStorage.setItem("title_model", v || "");
|
|
||||||
},
|
|
||||||
get githubToken() {
|
|
||||||
return localStorage.getItem("gh_token") || "";
|
|
||||||
},
|
|
||||||
set githubToken(v) {
|
|
||||||
localStorage.setItem("gh_token", v || "");
|
|
||||||
},
|
|
||||||
get gcpSA() {
|
|
||||||
try {
|
|
||||||
return JSON.parse(localStorage.getItem("gcp_sa_json") || "null");
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set gcpSA(v) {
|
|
||||||
localStorage.setItem("gcp_sa_json", v ? JSON.stringify(v) : "");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
async function init() {
|
async function init() {
|
||||||
const u = localStorage.getItem("thread_repo_url") || "";
|
const u = localStorage.getItem("thread_repo_url") || "";
|
||||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -14,7 +14,7 @@
|
|||||||
<script defer src="https://c.planetrenox.com/tracker.js"></script>
|
<script defer src="https://c.planetrenox.com/tracker.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-uVgFAg1W.js"></script>
|
<script type="module" crossorigin src="/assets/index-6iOL7W2F.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CLEI5Rwr.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CLEI5Rwr.css">
|
||||||
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
||||||
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
||||||
|
|||||||
2
dist/sw.js
vendored
2
dist/sw.js
vendored
@@ -1 +1 @@
|
|||||||
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const d=e=>i(e,t),l={module:{uri:t},exports:o,require:d};s[t]=Promise.all(n.map(e=>l[e]||d(e))).then(e=>(r(...e),o))}}define(["./workbox-8c29f6e4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"f88bfd9d7b620afd81de89ec21767e69"},{url:"assets/index-uVgFAg1W.js",revision:null},{url:"assets/index-CLEI5Rwr.css",revision:null},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()}).then(()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(i[t])return;let o={};const d=e=>s(e,t),l={module:{uri:t},exports:o,require:d};i[t]=Promise.all(n.map(e=>l[e]||d(e))).then(e=>(r(...e),o))}}define(["./workbox-8c29f6e4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"ad949321931259a665ded77f3e344165"},{url:"assets/index-CLEI5Rwr.css",revision:null},{url:"assets/index-6iOL7W2F.js",revision:null},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
||||||
|
|||||||
Reference in New Issue
Block a user