Initial commit
This commit is contained in:
commit
bfc698c49c
|
@ -0,0 +1,10 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
|
@ -0,0 +1,13 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"pluginSearchDirs": ["."],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"version": 3,
|
||||
"routes": [
|
||||
{
|
||||
"src": "/_app/immutable/.+",
|
||||
"headers": {
|
||||
"cache-control": "public, immutable, max-age=31536000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"handle": "filesystem"
|
||||
},
|
||||
{
|
||||
"src": "^/?(?:/__data.json)?$",
|
||||
"dest": "/fn-0"
|
||||
},
|
||||
{
|
||||
"src": "^/api/chat/?(?:/__data.json)?$",
|
||||
"dest": "/fn-1"
|
||||
},
|
||||
{
|
||||
"src": "/.*",
|
||||
"dest": "/fn"
|
||||
}
|
||||
],
|
||||
"overrides": {}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
let HttpError = class HttpError2 {
|
||||
/**
|
||||
* @param {number} status
|
||||
* @param {{message: string} extends App.Error ? (App.Error | string | undefined) : App.Error} body
|
||||
*/
|
||||
constructor(status, body) {
|
||||
this.status = status;
|
||||
if (typeof body === "string") {
|
||||
this.body = { message: body };
|
||||
} else if (body) {
|
||||
this.body = body;
|
||||
} else {
|
||||
this.body = { message: `Error: ${status}` };
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this.body);
|
||||
}
|
||||
};
|
||||
let Redirect = class Redirect2 {
|
||||
/**
|
||||
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
|
||||
* @param {string} location
|
||||
*/
|
||||
constructor(status, location) {
|
||||
this.status = status;
|
||||
this.location = location;
|
||||
}
|
||||
};
|
||||
let ActionFailure = class ActionFailure2 {
|
||||
/**
|
||||
* @param {number} status
|
||||
* @param {T} [data]
|
||||
*/
|
||||
constructor(status, data) {
|
||||
this.status = status;
|
||||
this.data = data;
|
||||
}
|
||||
};
|
||||
function error(status, message) {
|
||||
if (isNaN(status) || status < 400 || status > 599) {
|
||||
throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`);
|
||||
}
|
||||
return new HttpError(status, message);
|
||||
}
|
||||
function json(data, init) {
|
||||
const body = JSON.stringify(data);
|
||||
const headers = new Headers(init?.headers);
|
||||
if (!headers.has("content-length")) {
|
||||
headers.set("content-length", encoder.encode(body).byteLength.toString());
|
||||
}
|
||||
if (!headers.has("content-type")) {
|
||||
headers.set("content-type", "application/json");
|
||||
}
|
||||
return new Response(body, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
}
|
||||
const encoder = new TextEncoder();
|
||||
function text(body, init) {
|
||||
const headers = new Headers(init?.headers);
|
||||
if (!headers.has("content-length")) {
|
||||
headers.set("content-length", encoder.encode(body).byteLength.toString());
|
||||
}
|
||||
return new Response(body, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
}
|
||||
export {
|
||||
ActionFailure as A,
|
||||
HttpError as H,
|
||||
Redirect as R,
|
||||
error as e,
|
||||
json as j,
|
||||
text as t
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
import { n as noop, a as subscribe, r as run_all, o as safe_not_equal, p as is_function } from "./index3.js";
|
||||
const subscriber_queue = [];
|
||||
function readable(value, start) {
|
||||
return {
|
||||
subscribe: writable(value, start).subscribe
|
||||
};
|
||||
}
|
||||
function writable(value, start = noop) {
|
||||
let stop;
|
||||
const subscribers = /* @__PURE__ */ new Set();
|
||||
function set(new_value) {
|
||||
if (safe_not_equal(value, new_value)) {
|
||||
value = new_value;
|
||||
if (stop) {
|
||||
const run_queue = !subscriber_queue.length;
|
||||
for (const subscriber of subscribers) {
|
||||
subscriber[1]();
|
||||
subscriber_queue.push(subscriber, value);
|
||||
}
|
||||
if (run_queue) {
|
||||
for (let i = 0; i < subscriber_queue.length; i += 2) {
|
||||
subscriber_queue[i][0](subscriber_queue[i + 1]);
|
||||
}
|
||||
subscriber_queue.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function update(fn) {
|
||||
set(fn(value));
|
||||
}
|
||||
function subscribe2(run, invalidate = noop) {
|
||||
const subscriber = [run, invalidate];
|
||||
subscribers.add(subscriber);
|
||||
if (subscribers.size === 1) {
|
||||
stop = start(set) || noop;
|
||||
}
|
||||
run(value);
|
||||
return () => {
|
||||
subscribers.delete(subscriber);
|
||||
if (subscribers.size === 0 && stop) {
|
||||
stop();
|
||||
stop = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return { set, update, subscribe: subscribe2 };
|
||||
}
|
||||
function derived(stores, fn, initial_value) {
|
||||
const single = !Array.isArray(stores);
|
||||
const stores_array = single ? [stores] : stores;
|
||||
const auto = fn.length < 2;
|
||||
return readable(initial_value, (set) => {
|
||||
let started = false;
|
||||
const values = [];
|
||||
let pending = 0;
|
||||
let cleanup = noop;
|
||||
const sync = () => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
cleanup();
|
||||
const result = fn(single ? values[0] : values, set);
|
||||
if (auto) {
|
||||
set(result);
|
||||
} else {
|
||||
cleanup = is_function(result) ? result : noop;
|
||||
}
|
||||
};
|
||||
const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
|
||||
values[i] = value;
|
||||
pending &= ~(1 << i);
|
||||
if (started) {
|
||||
sync();
|
||||
}
|
||||
}, () => {
|
||||
pending |= 1 << i;
|
||||
}));
|
||||
started = true;
|
||||
sync();
|
||||
return function stop() {
|
||||
run_all(unsubscribers);
|
||||
cleanup();
|
||||
started = false;
|
||||
};
|
||||
});
|
||||
}
|
||||
export {
|
||||
derived as d,
|
||||
readable as r,
|
||||
writable as w
|
||||
};
|
|
@ -0,0 +1,254 @@
|
|||
function noop() {
|
||||
}
|
||||
function run(fn) {
|
||||
return fn();
|
||||
}
|
||||
function blank_object() {
|
||||
return /* @__PURE__ */ Object.create(null);
|
||||
}
|
||||
function run_all(fns) {
|
||||
fns.forEach(run);
|
||||
}
|
||||
function is_function(thing) {
|
||||
return typeof thing === "function";
|
||||
}
|
||||
function safe_not_equal(a, b) {
|
||||
return a != a ? b == b : a !== b || (a && typeof a === "object" || typeof a === "function");
|
||||
}
|
||||
function subscribe(store, ...callbacks) {
|
||||
if (store == null) {
|
||||
return noop;
|
||||
}
|
||||
const unsub = store.subscribe(...callbacks);
|
||||
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
|
||||
}
|
||||
function get_store_value(store) {
|
||||
let value;
|
||||
subscribe(store, (_) => value = _)();
|
||||
return value;
|
||||
}
|
||||
function compute_rest_props(props, keys) {
|
||||
const rest = {};
|
||||
keys = new Set(keys);
|
||||
for (const k in props)
|
||||
if (!keys.has(k) && k[0] !== "$")
|
||||
rest[k] = props[k];
|
||||
return rest;
|
||||
}
|
||||
let current_component;
|
||||
function set_current_component(component) {
|
||||
current_component = component;
|
||||
}
|
||||
function get_current_component() {
|
||||
if (!current_component)
|
||||
throw new Error("Function called outside component initialization");
|
||||
return current_component;
|
||||
}
|
||||
function setContext(key, context) {
|
||||
get_current_component().$$.context.set(key, context);
|
||||
return context;
|
||||
}
|
||||
function getContext(key) {
|
||||
return get_current_component().$$.context.get(key);
|
||||
}
|
||||
const _boolean_attributes = [
|
||||
"allowfullscreen",
|
||||
"allowpaymentrequest",
|
||||
"async",
|
||||
"autofocus",
|
||||
"autoplay",
|
||||
"checked",
|
||||
"controls",
|
||||
"default",
|
||||
"defer",
|
||||
"disabled",
|
||||
"formnovalidate",
|
||||
"hidden",
|
||||
"inert",
|
||||
"ismap",
|
||||
"loop",
|
||||
"multiple",
|
||||
"muted",
|
||||
"nomodule",
|
||||
"novalidate",
|
||||
"open",
|
||||
"playsinline",
|
||||
"readonly",
|
||||
"required",
|
||||
"reversed",
|
||||
"selected"
|
||||
];
|
||||
const boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]);
|
||||
const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
|
||||
function is_void(name) {
|
||||
return void_element_names.test(name) || name.toLowerCase() === "!doctype";
|
||||
}
|
||||
const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
|
||||
function spread(args, attrs_to_add) {
|
||||
const attributes = Object.assign({}, ...args);
|
||||
if (attrs_to_add) {
|
||||
const classes_to_add = attrs_to_add.classes;
|
||||
const styles_to_add = attrs_to_add.styles;
|
||||
if (classes_to_add) {
|
||||
if (attributes.class == null) {
|
||||
attributes.class = classes_to_add;
|
||||
} else {
|
||||
attributes.class += " " + classes_to_add;
|
||||
}
|
||||
}
|
||||
if (styles_to_add) {
|
||||
if (attributes.style == null) {
|
||||
attributes.style = style_object_to_string(styles_to_add);
|
||||
} else {
|
||||
attributes.style = style_object_to_string(merge_ssr_styles(attributes.style, styles_to_add));
|
||||
}
|
||||
}
|
||||
}
|
||||
let str = "";
|
||||
Object.keys(attributes).forEach((name) => {
|
||||
if (invalid_attribute_name_character.test(name))
|
||||
return;
|
||||
const value = attributes[name];
|
||||
if (value === true)
|
||||
str += " " + name;
|
||||
else if (boolean_attributes.has(name.toLowerCase())) {
|
||||
if (value)
|
||||
str += " " + name;
|
||||
} else if (value != null) {
|
||||
str += ` ${name}="${value}"`;
|
||||
}
|
||||
});
|
||||
return str;
|
||||
}
|
||||
function merge_ssr_styles(style_attribute, style_directive) {
|
||||
const style_object = {};
|
||||
for (const individual_style of style_attribute.split(";")) {
|
||||
const colon_index = individual_style.indexOf(":");
|
||||
const name = individual_style.slice(0, colon_index).trim();
|
||||
const value = individual_style.slice(colon_index + 1).trim();
|
||||
if (!name)
|
||||
continue;
|
||||
style_object[name] = value;
|
||||
}
|
||||
for (const name in style_directive) {
|
||||
const value = style_directive[name];
|
||||
if (value) {
|
||||
style_object[name] = value;
|
||||
} else {
|
||||
delete style_object[name];
|
||||
}
|
||||
}
|
||||
return style_object;
|
||||
}
|
||||
const ATTR_REGEX = /[&"]/g;
|
||||
const CONTENT_REGEX = /[&<]/g;
|
||||
function escape(value, is_attr = false) {
|
||||
const str = String(value);
|
||||
const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;
|
||||
pattern.lastIndex = 0;
|
||||
let escaped = "";
|
||||
let last = 0;
|
||||
while (pattern.test(str)) {
|
||||
const i = pattern.lastIndex - 1;
|
||||
const ch = str[i];
|
||||
escaped += str.substring(last, i) + (ch === "&" ? "&" : ch === '"' ? """ : "<");
|
||||
last = i + 1;
|
||||
}
|
||||
return escaped + str.substring(last);
|
||||
}
|
||||
function escape_attribute_value(value) {
|
||||
const should_escape = typeof value === "string" || value && typeof value === "object";
|
||||
return should_escape ? escape(value, true) : value;
|
||||
}
|
||||
function escape_object(obj) {
|
||||
const result = {};
|
||||
for (const key in obj) {
|
||||
result[key] = escape_attribute_value(obj[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function each(items, fn) {
|
||||
let str = "";
|
||||
for (let i = 0; i < items.length; i += 1) {
|
||||
str += fn(items[i], i);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
const missing_component = {
|
||||
$$render: () => ""
|
||||
};
|
||||
function validate_component(component, name) {
|
||||
if (!component || !component.$$render) {
|
||||
if (name === "svelte:component")
|
||||
name += " this={...}";
|
||||
throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules. Otherwise you may need to fix a <${name}>.`);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
let on_destroy;
|
||||
function create_ssr_component(fn) {
|
||||
function $$render(result, props, bindings, slots, context) {
|
||||
const parent_component = current_component;
|
||||
const $$ = {
|
||||
on_destroy,
|
||||
context: new Map(context || (parent_component ? parent_component.$$.context : [])),
|
||||
// these will be immediately discarded
|
||||
on_mount: [],
|
||||
before_update: [],
|
||||
after_update: [],
|
||||
callbacks: blank_object()
|
||||
};
|
||||
set_current_component({ $$ });
|
||||
const html = fn(result, props, bindings, slots);
|
||||
set_current_component(parent_component);
|
||||
return html;
|
||||
}
|
||||
return {
|
||||
render: (props = {}, { $$slots = {}, context = /* @__PURE__ */ new Map() } = {}) => {
|
||||
on_destroy = [];
|
||||
const result = { title: "", head: "", css: /* @__PURE__ */ new Set() };
|
||||
const html = $$render(result, props, {}, $$slots, context);
|
||||
run_all(on_destroy);
|
||||
return {
|
||||
html,
|
||||
css: {
|
||||
code: Array.from(result.css).map((css) => css.code).join("\n"),
|
||||
map: null
|
||||
// TODO
|
||||
},
|
||||
head: result.title + result.head
|
||||
};
|
||||
},
|
||||
$$render
|
||||
};
|
||||
}
|
||||
function add_attribute(name, value, boolean) {
|
||||
if (value == null || boolean && !value)
|
||||
return "";
|
||||
const assignment = boolean && value === true ? "" : `="${escape(value, true)}"`;
|
||||
return ` ${name}${assignment}`;
|
||||
}
|
||||
function style_object_to_string(style_object) {
|
||||
return Object.keys(style_object).filter((key) => style_object[key]).map((key) => `${key}: ${escape_attribute_value(style_object[key])};`).join(" ");
|
||||
}
|
||||
export {
|
||||
subscribe as a,
|
||||
get_store_value as b,
|
||||
create_ssr_component as c,
|
||||
each as d,
|
||||
escape as e,
|
||||
spread as f,
|
||||
getContext as g,
|
||||
escape_object as h,
|
||||
is_void as i,
|
||||
add_attribute as j,
|
||||
compute_rest_props as k,
|
||||
escape_attribute_value as l,
|
||||
missing_component as m,
|
||||
noop as n,
|
||||
safe_not_equal as o,
|
||||
is_function as p,
|
||||
run_all as r,
|
||||
setContext as s,
|
||||
validate_component as v
|
||||
};
|
|
@ -0,0 +1,187 @@
|
|||
import { c as create_ssr_component, s as setContext, v as validate_component, m as missing_component } from "./index3.js";
|
||||
let base = "";
|
||||
let assets = base;
|
||||
const initial = { base, assets };
|
||||
function reset() {
|
||||
base = initial.base;
|
||||
assets = initial.assets;
|
||||
}
|
||||
function set_assets(path) {
|
||||
assets = initial.assets = path;
|
||||
}
|
||||
let public_env = {};
|
||||
function set_private_env(environment) {
|
||||
}
|
||||
function set_public_env(environment) {
|
||||
public_env = environment;
|
||||
}
|
||||
function afterUpdate() {
|
||||
}
|
||||
function set_building() {
|
||||
}
|
||||
const Root = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { stores } = $$props;
|
||||
let { page } = $$props;
|
||||
let { constructors } = $$props;
|
||||
let { components = [] } = $$props;
|
||||
let { form } = $$props;
|
||||
let { data_0 = null } = $$props;
|
||||
let { data_1 = null } = $$props;
|
||||
{
|
||||
setContext("__svelte__", stores);
|
||||
}
|
||||
afterUpdate(stores.page.notify);
|
||||
if ($$props.stores === void 0 && $$bindings.stores && stores !== void 0)
|
||||
$$bindings.stores(stores);
|
||||
if ($$props.page === void 0 && $$bindings.page && page !== void 0)
|
||||
$$bindings.page(page);
|
||||
if ($$props.constructors === void 0 && $$bindings.constructors && constructors !== void 0)
|
||||
$$bindings.constructors(constructors);
|
||||
if ($$props.components === void 0 && $$bindings.components && components !== void 0)
|
||||
$$bindings.components(components);
|
||||
if ($$props.form === void 0 && $$bindings.form && form !== void 0)
|
||||
$$bindings.form(form);
|
||||
if ($$props.data_0 === void 0 && $$bindings.data_0 && data_0 !== void 0)
|
||||
$$bindings.data_0(data_0);
|
||||
if ($$props.data_1 === void 0 && $$bindings.data_1 && data_1 !== void 0)
|
||||
$$bindings.data_1(data_1);
|
||||
let $$settled;
|
||||
let $$rendered;
|
||||
do {
|
||||
$$settled = true;
|
||||
{
|
||||
stores.page.set(page);
|
||||
}
|
||||
$$rendered = `
|
||||
|
||||
|
||||
${constructors[1] ? `${validate_component(constructors[0] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_0, this: components[0] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[0] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return `${validate_component(constructors[1] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_1, form, this: components[1] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[1] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{}
|
||||
)}`;
|
||||
}
|
||||
}
|
||||
)}` : `${validate_component(constructors[0] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_0, form, this: components[0] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[0] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{}
|
||||
)}`}
|
||||
|
||||
${``}`;
|
||||
} while (!$$settled);
|
||||
return $$rendered;
|
||||
});
|
||||
const options = {
|
||||
app_template_contains_nonce: false,
|
||||
csp: { "mode": "auto", "directives": { "upgrade-insecure-requests": false, "block-all-mixed-content": false }, "reportOnly": { "upgrade-insecure-requests": false, "block-all-mixed-content": false } },
|
||||
csrf_check_origin: true,
|
||||
embedded: false,
|
||||
env_public_prefix: "PUBLIC_",
|
||||
hooks: null,
|
||||
// added lazily, via `get_hooks`
|
||||
preload_strategy: "modulepreload",
|
||||
root: Root,
|
||||
service_worker: false,
|
||||
templates: {
|
||||
app: ({ head, body, assets: assets2, nonce, env }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <link rel="icon" href="' + assets2 + '/favicon.png" />\n <meta name="viewport" content="width=device-width" />\n ' + head + '\n </head>\n <body data-sveltekit-preload-data="hover">\n <div style="display: contents">' + body + "</div>\n </body>\n</html>\n",
|
||||
error: ({ status, message }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>' + message + `</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
--bg: white;
|
||||
--fg: #222;
|
||||
--divider: #ccc;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 32rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-weight: 200;
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
top: -0.05rem;
|
||||
}
|
||||
|
||||
.message {
|
||||
border-left: 1px solid var(--divider);
|
||||
padding: 0 0 0 1rem;
|
||||
margin: 0 0 0 1rem;
|
||||
min-height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message h1 {
|
||||
font-weight: 400;
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
--bg: #222;
|
||||
--fg: #ddd;
|
||||
--divider: #666;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error">
|
||||
<span class="status">` + status + '</span>\n <div class="message">\n <h1>' + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n"
|
||||
},
|
||||
version_hash: "10ptubg"
|
||||
};
|
||||
function get_hooks() {
|
||||
return {};
|
||||
}
|
||||
export {
|
||||
assets as a,
|
||||
base as b,
|
||||
set_assets as c,
|
||||
set_building as d,
|
||||
set_private_env as e,
|
||||
get_hooks as g,
|
||||
options as o,
|
||||
public_env as p,
|
||||
reset as r,
|
||||
set_public_env as s
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
import { g as getContext, c as create_ssr_component, a as subscribe, e as escape } from "../../chunks/index3.js";
|
||||
const getStores = () => {
|
||||
const stores = getContext("__svelte__");
|
||||
return {
|
||||
page: {
|
||||
subscribe: stores.page.subscribe
|
||||
},
|
||||
navigating: {
|
||||
subscribe: stores.navigating.subscribe
|
||||
},
|
||||
updated: stores.updated
|
||||
};
|
||||
};
|
||||
const page = {
|
||||
/** @param {(value: any) => void} fn */
|
||||
subscribe(fn) {
|
||||
const store = getStores().page;
|
||||
return store.subscribe(fn);
|
||||
}
|
||||
};
|
||||
const Error$1 = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $page, $$unsubscribe_page;
|
||||
$$unsubscribe_page = subscribe(page, (value) => $page = value);
|
||||
$$unsubscribe_page();
|
||||
return `<h1>${escape($page.status)}</h1>
|
||||
<p>${escape($page.error?.message)}</p>`;
|
||||
});
|
||||
export {
|
||||
Error$1 as default
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import { c as create_ssr_component } from "../../chunks/index3.js";
|
||||
const app = "";
|
||||
const Layout = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<div class="flex flex-col items-center py-14">${slots.default ? slots.default({}) : ``}</div>`;
|
||||
});
|
||||
export {
|
||||
Layout as default
|
||||
};
|
|
@ -0,0 +1,402 @@
|
|||
import { c as create_ssr_component, b as get_store_value, a as subscribe$1, v as validate_component, d as each, e as escape, g as getContext, m as missing_component, f as spread, h as escape_object, i as is_void, j as add_attribute, k as compute_rest_props, l as escape_attribute_value } from "../../chunks/index3.js";
|
||||
import { SSE } from "sse.js";
|
||||
import { w as writable, d as derived } from "../../chunks/index2.js";
|
||||
import { marked } from "marked";
|
||||
import DOMPurify from "isomorphic-dompurify";
|
||||
const Chat = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>`;
|
||||
});
|
||||
const Pencil = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg>`;
|
||||
});
|
||||
const Plus = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>`;
|
||||
});
|
||||
const Trash = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>`;
|
||||
});
|
||||
const { subscribe, update, ...store } = writable({
|
||||
messages: [
|
||||
{ role: "assistant", content: "Welcome! Please introduce yourself to your AI competitor." }
|
||||
],
|
||||
chatState: "idle"
|
||||
});
|
||||
const set = async (query) => {
|
||||
updateMessages(query, "user", "loading");
|
||||
request();
|
||||
};
|
||||
const request = async (query) => {
|
||||
const eventSource = new SSE("/api/chat", {
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
payload: JSON.stringify({ messages: get_store_value(chatMessages).messages })
|
||||
});
|
||||
eventSource.addEventListener("error", handleError);
|
||||
eventSource.addEventListener("message", streamMessage);
|
||||
eventSource.stream();
|
||||
};
|
||||
const replace = (messages) => {
|
||||
store.set(messages);
|
||||
};
|
||||
const reset = () => store.set({
|
||||
messages: [
|
||||
{ role: "assistant", content: "Welcome! Please introduce yourself to your AI competitor." }
|
||||
],
|
||||
chatState: "idle"
|
||||
});
|
||||
const updateMessages = (content, role, state) => {
|
||||
chatMessages.update((messages) => {
|
||||
return { messages: [...messages.messages, { role, content }], chatState: state };
|
||||
});
|
||||
};
|
||||
const handleError = (err) => {
|
||||
updateMessages(err, "system", "error");
|
||||
console.error(err);
|
||||
};
|
||||
const streamMessage = (e) => {
|
||||
try {
|
||||
if (e.data === "[DONE]") {
|
||||
updateMessages(get_store_value(answer), "assistant", "idle");
|
||||
return answer.set("");
|
||||
}
|
||||
if (get_store_value(answer) === "...")
|
||||
answer.set("");
|
||||
const completionResponse = JSON.parse(e.data);
|
||||
const [{ delta }] = completionResponse.choices;
|
||||
if (delta.content) {
|
||||
answer.update((_a) => _a + delta.content);
|
||||
}
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
}
|
||||
};
|
||||
const chatMessages = { subscribe, set, update, reset, replace };
|
||||
const answer = writable("");
|
||||
const chatHistory = derived(chatMessages, ($chatMessages) => {
|
||||
return null;
|
||||
});
|
||||
const ChatHistory = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $$unsubscribe_chatHistory;
|
||||
$$unsubscribe_chatHistory = subscribe$1(chatHistory, (value) => value);
|
||||
let chatHistoryKeys = [];
|
||||
$$unsubscribe_chatHistory();
|
||||
return `<div class="h-[700px] w-[350px] bg-black bg-opacity-20 rounded-md py-4 px-2 overflow-y-auto flex flex-col gap-2"><button class="flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white cursor-pointer text-sm mb-2 flex-shrink-0 border border-white/20">${validate_component(Plus, "Plus").$$render($$result, {}, {}, {})} New Game
|
||||
</button>
|
||||
|
||||
${chatHistoryKeys.length > 0 ? `${each(chatHistoryKeys, (message) => {
|
||||
return `
|
||||
<div class="flex py-3 px-3 items-center gap-3 relative rounded-md cursor-pointer break-all pr-14 bg-opacity-40 hover:bg-white/5 bg-black group animate-flash text-sm">${validate_component(Chat, "Chat").$$render($$result, {}, {}, {})}
|
||||
<div class="flex-1 text-ellipsis max-h-5 overflow-hidden break-all relative">${escape(message)}</div>
|
||||
|
||||
<div class="absolute flex right-1 z-10 text-gray-300 visible"><button class="p-1 hover:text-white">${validate_component(Pencil, "Pencil").$$render($$result, {}, {}, {})}</button>
|
||||
<button class="p-1 hover:text-white">${validate_component(Trash, "Trash").$$render($$result, {}, {}, {})}
|
||||
</button></div>
|
||||
</div>`;
|
||||
})}` : ``}</div>`;
|
||||
});
|
||||
const componentsContextKey = {};
|
||||
const getComponentsContext = () => getContext(componentsContextKey);
|
||||
const Renderer = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $components, $$unsubscribe_components;
|
||||
let { astNode } = $$props;
|
||||
let { __index = 0 } = $$props;
|
||||
let { type = void 0 } = $$props;
|
||||
let { position = void 0 } = $$props;
|
||||
const components = getComponentsContext();
|
||||
$$unsubscribe_components = subscribe$1(components, (value) => $components = value);
|
||||
if ($$props.astNode === void 0 && $$bindings.astNode && astNode !== void 0)
|
||||
$$bindings.astNode(astNode);
|
||||
if ($$props.__index === void 0 && $$bindings.__index && __index !== void 0)
|
||||
$$bindings.__index(__index);
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.position === void 0 && $$bindings.position && position !== void 0)
|
||||
$$bindings.position(position);
|
||||
$$unsubscribe_components();
|
||||
return `${astNode.type === "root" ? `${validate_component(Children, "Children").$$render($$result, Object.assign({}, astNode), {}, {})}` : `${astNode.type === "element" ? `${validate_component($components[astNode.tagName] || missing_component, "svelte:component").$$render($$result, Object.assign({}, astNode, { __index }), {}, {})}` : `${$components[astNode.type] !== void 0 ? `${validate_component($components[astNode.type] || missing_component, "svelte:component").$$render($$result, Object.assign({}, astNode, { __index }), {}, {})}` : ``}`}`}`;
|
||||
});
|
||||
const Children = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { children } = $$props;
|
||||
let { type = void 0 } = $$props;
|
||||
let { position = void 0 } = $$props;
|
||||
let { __index = void 0 } = $$props;
|
||||
if ($$props.children === void 0 && $$bindings.children && children !== void 0)
|
||||
$$bindings.children(children);
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.position === void 0 && $$bindings.position && position !== void 0)
|
||||
$$bindings.position(position);
|
||||
if ($$props.__index === void 0 && $$bindings.__index && __index !== void 0)
|
||||
$$bindings.__index(__index);
|
||||
return `${each(children, (child, __index2) => {
|
||||
return `${validate_component(Renderer, "Renderer").$$render($$result, { astNode: child, __index: __index2 }, {}, {})}`;
|
||||
})}`;
|
||||
});
|
||||
const Default = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { tagName } = $$props;
|
||||
let { children } = $$props;
|
||||
let { properties } = $$props;
|
||||
let { type = void 0 } = $$props;
|
||||
let { position = void 0 } = $$props;
|
||||
let { __index = void 0 } = $$props;
|
||||
if ($$props.tagName === void 0 && $$bindings.tagName && tagName !== void 0)
|
||||
$$bindings.tagName(tagName);
|
||||
if ($$props.children === void 0 && $$bindings.children && children !== void 0)
|
||||
$$bindings.children(children);
|
||||
if ($$props.properties === void 0 && $$bindings.properties && properties !== void 0)
|
||||
$$bindings.properties(properties);
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.position === void 0 && $$bindings.position && position !== void 0)
|
||||
$$bindings.position(position);
|
||||
if ($$props.__index === void 0 && $$bindings.__index && __index !== void 0)
|
||||
$$bindings.__index(__index);
|
||||
return `${Array.isArray(children) && children.length !== 0 ? `
|
||||
${((tag) => {
|
||||
return tag ? `<${tagName}${spread([escape_object(properties)], {})}>${is_void(tag) ? "" : `${validate_component(Children, "Children").$$render($$result, { children }, {}, {})}`}${is_void(tag) ? "" : `</${tag}>`}` : "";
|
||||
})(tagName)}` : `
|
||||
${((tag) => {
|
||||
return tag ? `<${tagName}${spread([escape_object(properties)], {})}>${is_void(tag) ? "" : ``}${is_void(tag) ? "" : `</${tag}>`}` : "";
|
||||
})(tagName)}`}`;
|
||||
});
|
||||
const defaultTags = [
|
||||
// Content sectioning
|
||||
"address",
|
||||
"article",
|
||||
"aside",
|
||||
"footer",
|
||||
"header",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"h6",
|
||||
"main",
|
||||
"nav",
|
||||
"section",
|
||||
// Text content
|
||||
"blockquote",
|
||||
"dd",
|
||||
"div",
|
||||
"dl",
|
||||
"dt",
|
||||
"figcaption",
|
||||
"figure",
|
||||
"hr",
|
||||
"li",
|
||||
"menu",
|
||||
"ol",
|
||||
"p",
|
||||
"pre",
|
||||
"ul",
|
||||
// Inline text semantics
|
||||
"a",
|
||||
"abbr",
|
||||
"b",
|
||||
"bdi",
|
||||
"bdo",
|
||||
"br",
|
||||
"cite",
|
||||
"code",
|
||||
"data",
|
||||
"dfn",
|
||||
"em",
|
||||
"i",
|
||||
"kbd",
|
||||
"mark",
|
||||
"q",
|
||||
"rp",
|
||||
"rt",
|
||||
"ruby",
|
||||
"s",
|
||||
"samp",
|
||||
"small",
|
||||
"span",
|
||||
"strong",
|
||||
"sub",
|
||||
"sup",
|
||||
"time",
|
||||
"u",
|
||||
"var",
|
||||
"wbr",
|
||||
// Image and multimedia
|
||||
"area",
|
||||
"audio",
|
||||
"img",
|
||||
"map",
|
||||
"track",
|
||||
"video",
|
||||
// Embedded content
|
||||
"embed",
|
||||
"iframe",
|
||||
"object",
|
||||
"param",
|
||||
"picture",
|
||||
"portal",
|
||||
"source",
|
||||
// SVG and MathML
|
||||
"svg",
|
||||
"math",
|
||||
// Demarcating edits
|
||||
"del",
|
||||
"ins",
|
||||
// Table content
|
||||
"caption",
|
||||
"col",
|
||||
"colgroup",
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"tfoot",
|
||||
"th",
|
||||
"thead",
|
||||
"tr",
|
||||
// Forms
|
||||
"button",
|
||||
"datalist",
|
||||
"fieldset",
|
||||
"form",
|
||||
"input",
|
||||
"label",
|
||||
"legend",
|
||||
"meter",
|
||||
"optgroup",
|
||||
"option",
|
||||
"output",
|
||||
"progress",
|
||||
"select",
|
||||
"textarea",
|
||||
// Interactive elements
|
||||
"details",
|
||||
"dialog",
|
||||
"summary"
|
||||
];
|
||||
const htmlComponents = defaultTags.reduce((acc, tag) => ({ ...acc, [tag]: Default }), {});
|
||||
const Text = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { value = "" } = $$props;
|
||||
let { type = void 0 } = $$props;
|
||||
let { position = void 0 } = $$props;
|
||||
let { __index = void 0 } = $$props;
|
||||
if ($$props.value === void 0 && $$bindings.value && value !== void 0)
|
||||
$$bindings.value(value);
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.position === void 0 && $$bindings.position && position !== void 0)
|
||||
$$bindings.position(position);
|
||||
if ($$props.__index === void 0 && $$bindings.__index && __index !== void 0)
|
||||
$$bindings.__index(__index);
|
||||
return `${escape(value)}`;
|
||||
});
|
||||
({
|
||||
...htmlComponents,
|
||||
text: Text,
|
||||
raw: Text
|
||||
});
|
||||
const ChatMessage = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { type } = $$props;
|
||||
let { message = "" } = $$props;
|
||||
let { class: classes = "" } = $$props;
|
||||
let scrollToDiv;
|
||||
const classSet = {
|
||||
user: "justify-end text-rose-700",
|
||||
assistant: "justify-start text-teal-400",
|
||||
system: "justify-center text-gray-400"
|
||||
};
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.message === void 0 && $$bindings.message && message !== void 0)
|
||||
$$bindings.message(message);
|
||||
if ($$props.class === void 0 && $$bindings.class && classes !== void 0)
|
||||
$$bindings.class(classes);
|
||||
return `<div class="${"flex items-center " + escape(classSet[type], true)}"><p class="text-xs px-2">${escape(type === "user" ? "Me" : "Bot")}</p></div>
|
||||
|
||||
<div class="${"flex " + escape(classSet[type], true)}"><div class="${"bg-black py-0.5 px-4 max-w-2xl rounded leading-loose " + escape(classes, true) + " " + escape(classSet[type], true)}"><!-- HTML_TAG_START -->${DOMPurify.sanitize(marked.parse(message))}<!-- HTML_TAG_END --></div>
|
||||
<div${add_attribute("this", scrollToDiv, 0)}></div></div>`;
|
||||
});
|
||||
const Input = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $$restProps = compute_rest_props($$props, ["value", "placeholder", "name", "type", "label", "class"]);
|
||||
let { value } = $$props;
|
||||
let { placeholder = "" } = $$props;
|
||||
let { name = "" } = $$props;
|
||||
let { type = "text" } = $$props;
|
||||
let { label = "" } = $$props;
|
||||
let { class: classes = "" } = $$props;
|
||||
if ($$props.value === void 0 && $$bindings.value && value !== void 0)
|
||||
$$bindings.value(value);
|
||||
if ($$props.placeholder === void 0 && $$bindings.placeholder && placeholder !== void 0)
|
||||
$$bindings.placeholder(placeholder);
|
||||
if ($$props.name === void 0 && $$bindings.name && name !== void 0)
|
||||
$$bindings.name(name);
|
||||
if ($$props.type === void 0 && $$bindings.type && type !== void 0)
|
||||
$$bindings.type(type);
|
||||
if ($$props.label === void 0 && $$bindings.label && label !== void 0)
|
||||
$$bindings.label(label);
|
||||
if ($$props.class === void 0 && $$bindings.class && classes !== void 0)
|
||||
$$bindings.class(classes);
|
||||
return `<div class="${"flex flex-col min-w-xl " + escape(classes, true)}"><label class="text-xs"${add_attribute("for", name, 0)}>${escape(label)}</label>
|
||||
<input${spread(
|
||||
[
|
||||
{ name: escape_attribute_value(name) },
|
||||
{
|
||||
placeholder: escape_attribute_value(placeholder)
|
||||
},
|
||||
{
|
||||
class: "shadow bg-white/10 rounded-md px-4 py-1.5 min-w-xl text-teal-300 border border-transparent focus:outline-none focus:ring-1 focus:ring-teal-300 focus:border-transparent"
|
||||
},
|
||||
escape_object($$restProps)
|
||||
],
|
||||
{}
|
||||
)}${add_attribute("value", value, 0)}></div>`;
|
||||
});
|
||||
const Page = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $chatMessages, $$unsubscribe_chatMessages;
|
||||
let $answer, $$unsubscribe_answer;
|
||||
$$unsubscribe_chatMessages = subscribe$1(chatMessages, (value) => $chatMessages = value);
|
||||
$$unsubscribe_answer = subscribe$1(answer, (value) => $answer = value);
|
||||
let query = "";
|
||||
let $$settled;
|
||||
let $$rendered;
|
||||
do {
|
||||
$$settled = true;
|
||||
$$rendered = `<section class="flex max-w-6xl w-full pt-4 justify-center"><div class="flex flex-col gap-2">${validate_component(ChatHistory, "ChatHistory").$$render($$result, {}, {}, {})}</div>
|
||||
|
||||
<div class="flex flex-col w-full px-8 items-center gap-2"><div class="h-[700px] w-full bg-black bg-opacity-20 rounded-md p-4 overflow-y-auto flex flex-col gap-4"><div class="flex flex-col gap-2">${each($chatMessages.messages, (message) => {
|
||||
return `${validate_component(ChatMessage, "ChatMessage").$$render(
|
||||
$$result,
|
||||
{
|
||||
type: message.role,
|
||||
message: message.content
|
||||
},
|
||||
{},
|
||||
{}
|
||||
)}`;
|
||||
})}
|
||||
|
||||
${$answer ? `${validate_component(ChatMessage, "ChatMessage").$$render($$result, { type: "assistant", message: $answer }, {}, {})}` : ``}</div></div>
|
||||
<form class="flex w-full rounded-md gap-4 bg-black bg-opacity-20 p-2">${validate_component(Input, "Input").$$render(
|
||||
$$result,
|
||||
{
|
||||
type: "text",
|
||||
class: "w-full",
|
||||
value: query
|
||||
},
|
||||
{
|
||||
value: ($$value) => {
|
||||
query = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{}
|
||||
)}
|
||||
<button type="submit" class="bg-black bg-opacity-40 hover:bg-white/5 px-8 py-1.5 border border-black/40 ml-[-0.5rem] rounded-md text-teal-300">Send
|
||||
</button></form></div></section>`;
|
||||
} while (!$$settled);
|
||||
$$unsubscribe_chatMessages();
|
||||
$$unsubscribe_answer();
|
||||
return $$rendered;
|
||||
});
|
||||
export {
|
||||
Page as default
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
export const index = 0;
|
||||
export const component = async () => (await import('../entries/pages/_layout.svelte.js')).default;
|
||||
export const file = '_app/immutable/entry/_layout.svelte.62a505d3.js';
|
||||
export const imports = ["_app/immutable/entry/_layout.svelte.62a505d3.js","_app/immutable/chunks/index.3641fafa.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/_layout.b9bcc4f4.css"];
|
||||
export const fonts = [];
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
export const index = 1;
|
||||
export const component = async () => (await import('../entries/fallbacks/error.svelte.js')).default;
|
||||
export const file = '_app/immutable/entry/error.svelte.a6bd0229.js';
|
||||
export const imports = ["_app/immutable/entry/error.svelte.a6bd0229.js","_app/immutable/chunks/index.3641fafa.js","_app/immutable/chunks/singletons.8077db6c.js","_app/immutable/chunks/index.fa397836.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
export const index = 2;
|
||||
export const component = async () => (await import('../entries/pages/_page.svelte.js')).default;
|
||||
export const file = '_app/immutable/entry/_page.svelte.2f89fa28.js';
|
||||
export const imports = ["_app/immutable/entry/_page.svelte.2f89fa28.js","_app/immutable/chunks/index.3641fafa.js","_app/immutable/chunks/index.fa397836.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
|
@ -0,0 +1,51 @@
|
|||
import { installPolyfills } from '@sveltejs/kit/node/polyfills';
|
||||
import { getRequest, setResponse } from '@sveltejs/kit/node';
|
||||
import { Server } from '../output/server/index.js';
|
||||
import { manifest } from './manifest.js';
|
||||
|
||||
installPolyfills();
|
||||
|
||||
const server = new Server(manifest);
|
||||
|
||||
await server.init({
|
||||
env: /** @type {Record<string, string>} */ (process.env)
|
||||
});
|
||||
|
||||
const DATA_SUFFIX = '/__data.json';
|
||||
|
||||
/**
|
||||
* @param {import('http').IncomingMessage} req
|
||||
* @param {import('http').ServerResponse} res
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
if (req.url) {
|
||||
const [path, search] = req.url.split('?');
|
||||
|
||||
const params = new URLSearchParams(search);
|
||||
const pathname = params.get('__pathname');
|
||||
|
||||
if (pathname) {
|
||||
params.delete('__pathname');
|
||||
req.url = `${pathname}${path.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : ''}?${params}`;
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Request} */
|
||||
let request;
|
||||
|
||||
try {
|
||||
request = await getRequest({ base: `https://${req.headers.host}`, request: req });
|
||||
} catch (err) {
|
||||
res.statusCode = /** @type {any} */ (err).status || 400;
|
||||
return res.end('Invalid request body');
|
||||
}
|
||||
|
||||
setResponse(
|
||||
res,
|
||||
await server.respond(request, {
|
||||
getClientAddress() {
|
||||
return /** @type {string} */ (request.headers.get('x-forwarded-for'));
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
export const manifest = {
|
||||
appDir: "_app",
|
||||
appPath: "_app",
|
||||
assets: new Set(["favicon.png"]),
|
||||
mimeTypes: {".png":"image/png"},
|
||||
_: {
|
||||
client: {"start":{"file":"_app/immutable/entry/start.c62adf58.js","imports":["_app/immutable/entry/start.c62adf58.js","_app/immutable/chunks/index.3641fafa.js","_app/immutable/chunks/singletons.8077db6c.js","_app/immutable/chunks/index.fa397836.js"],"stylesheets":[],"fonts":[]},"app":{"file":"_app/immutable/entry/app.c59518f6.js","imports":["_app/immutable/entry/app.c59518f6.js","_app/immutable/chunks/index.3641fafa.js"],"stylesheets":[],"fonts":[]}},
|
||||
nodes: [
|
||||
() => import('../output/server/nodes/0.js'),
|
||||
() => import('../output/server/nodes/1.js'),
|
||||
() => import('../output/server/nodes/2.js')
|
||||
],
|
||||
routes: [
|
||||
{
|
||||
id: "/",
|
||||
pattern: /^\/$/,
|
||||
params: [],
|
||||
page: { layouts: [0], errors: [1], leaf: 2 },
|
||||
endpoint: null
|
||||
}
|
||||
],
|
||||
matchers: async () => {
|
||||
|
||||
return { };
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"runtime": "nodejs18.x",
|
||||
"handler": ".svelte-kit/vercel-tmp/index.js",
|
||||
"launcherType": "Nodejs",
|
||||
"experimentalResponseStreaming": true
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"type":"module"}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"runtime": "edge",
|
||||
"envVarsInUse": [],
|
||||
"entrypoint": "index.js"
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,78 @@
|
|||
let HttpError = class HttpError2 {
|
||||
/**
|
||||
* @param {number} status
|
||||
* @param {{message: string} extends App.Error ? (App.Error | string | undefined) : App.Error} body
|
||||
*/
|
||||
constructor(status, body) {
|
||||
this.status = status;
|
||||
if (typeof body === "string") {
|
||||
this.body = { message: body };
|
||||
} else if (body) {
|
||||
this.body = body;
|
||||
} else {
|
||||
this.body = { message: `Error: ${status}` };
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(this.body);
|
||||
}
|
||||
};
|
||||
let Redirect = class Redirect2 {
|
||||
/**
|
||||
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
|
||||
* @param {string} location
|
||||
*/
|
||||
constructor(status, location) {
|
||||
this.status = status;
|
||||
this.location = location;
|
||||
}
|
||||
};
|
||||
let ActionFailure = class ActionFailure2 {
|
||||
/**
|
||||
* @param {number} status
|
||||
* @param {T} [data]
|
||||
*/
|
||||
constructor(status, data) {
|
||||
this.status = status;
|
||||
this.data = data;
|
||||
}
|
||||
};
|
||||
function error(status, message) {
|
||||
if (isNaN(status) || status < 400 || status > 599) {
|
||||
throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`);
|
||||
}
|
||||
return new HttpError(status, message);
|
||||
}
|
||||
function json(data, init) {
|
||||
const body = JSON.stringify(data);
|
||||
const headers = new Headers(init?.headers);
|
||||
if (!headers.has("content-length")) {
|
||||
headers.set("content-length", encoder.encode(body).byteLength.toString());
|
||||
}
|
||||
if (!headers.has("content-type")) {
|
||||
headers.set("content-type", "application/json");
|
||||
}
|
||||
return new Response(body, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
}
|
||||
const encoder = new TextEncoder();
|
||||
function text(body, init) {
|
||||
const headers = new Headers(init?.headers);
|
||||
if (!headers.has("content-length")) {
|
||||
headers.set("content-length", encoder.encode(body).byteLength.toString());
|
||||
}
|
||||
return new Response(body, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
}
|
||||
export {
|
||||
ActionFailure as A,
|
||||
HttpError as H,
|
||||
Redirect as R,
|
||||
error as e,
|
||||
json as j,
|
||||
text as t
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
import { n as noop, a as subscribe, r as run_all, o as safe_not_equal, p as is_function } from "./index3.js";
|
||||
const subscriber_queue = [];
|
||||
function readable(value, start) {
|
||||
return {
|
||||
subscribe: writable(value, start).subscribe
|
||||
};
|
||||
}
|
||||
function writable(value, start = noop) {
|
||||
let stop;
|
||||
const subscribers = /* @__PURE__ */ new Set();
|
||||
function set(new_value) {
|
||||
if (safe_not_equal(value, new_value)) {
|
||||
value = new_value;
|
||||
if (stop) {
|
||||
const run_queue = !subscriber_queue.length;
|
||||
for (const subscriber of subscribers) {
|
||||
subscriber[1]();
|
||||
subscriber_queue.push(subscriber, value);
|
||||
}
|
||||
if (run_queue) {
|
||||
for (let i = 0; i < subscriber_queue.length; i += 2) {
|
||||
subscriber_queue[i][0](subscriber_queue[i + 1]);
|
||||
}
|
||||
subscriber_queue.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function update(fn) {
|
||||
set(fn(value));
|
||||
}
|
||||
function subscribe2(run, invalidate = noop) {
|
||||
const subscriber = [run, invalidate];
|
||||
subscribers.add(subscriber);
|
||||
if (subscribers.size === 1) {
|
||||
stop = start(set) || noop;
|
||||
}
|
||||
run(value);
|
||||
return () => {
|
||||
subscribers.delete(subscriber);
|
||||
if (subscribers.size === 0 && stop) {
|
||||
stop();
|
||||
stop = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return { set, update, subscribe: subscribe2 };
|
||||
}
|
||||
function derived(stores, fn, initial_value) {
|
||||
const single = !Array.isArray(stores);
|
||||
const stores_array = single ? [stores] : stores;
|
||||
const auto = fn.length < 2;
|
||||
return readable(initial_value, (set) => {
|
||||
let started = false;
|
||||
const values = [];
|
||||
let pending = 0;
|
||||
let cleanup = noop;
|
||||
const sync = () => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
cleanup();
|
||||
const result = fn(single ? values[0] : values, set);
|
||||
if (auto) {
|
||||
set(result);
|
||||
} else {
|
||||
cleanup = is_function(result) ? result : noop;
|
||||
}
|
||||
};
|
||||
const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
|
||||
values[i] = value;
|
||||
pending &= ~(1 << i);
|
||||
if (started) {
|
||||
sync();
|
||||
}
|
||||
}, () => {
|
||||
pending |= 1 << i;
|
||||
}));
|
||||
started = true;
|
||||
sync();
|
||||
return function stop() {
|
||||
run_all(unsubscribers);
|
||||
cleanup();
|
||||
started = false;
|
||||
};
|
||||
});
|
||||
}
|
||||
export {
|
||||
derived as d,
|
||||
readable as r,
|
||||
writable as w
|
||||
};
|
|
@ -0,0 +1,254 @@
|
|||
function noop() {
|
||||
}
|
||||
function run(fn) {
|
||||
return fn();
|
||||
}
|
||||
function blank_object() {
|
||||
return /* @__PURE__ */ Object.create(null);
|
||||
}
|
||||
function run_all(fns) {
|
||||
fns.forEach(run);
|
||||
}
|
||||
function is_function(thing) {
|
||||
return typeof thing === "function";
|
||||
}
|
||||
function safe_not_equal(a, b) {
|
||||
return a != a ? b == b : a !== b || (a && typeof a === "object" || typeof a === "function");
|
||||
}
|
||||
function subscribe(store, ...callbacks) {
|
||||
if (store == null) {
|
||||
return noop;
|
||||
}
|
||||
const unsub = store.subscribe(...callbacks);
|
||||
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
|
||||
}
|
||||
function get_store_value(store) {
|
||||
let value;
|
||||
subscribe(store, (_) => value = _)();
|
||||
return value;
|
||||
}
|
||||
function compute_rest_props(props, keys) {
|
||||
const rest = {};
|
||||
keys = new Set(keys);
|
||||
for (const k in props)
|
||||
if (!keys.has(k) && k[0] !== "$")
|
||||
rest[k] = props[k];
|
||||
return rest;
|
||||
}
|
||||
let current_component;
|
||||
function set_current_component(component) {
|
||||
current_component = component;
|
||||
}
|
||||
function get_current_component() {
|
||||
if (!current_component)
|
||||
throw new Error("Function called outside component initialization");
|
||||
return current_component;
|
||||
}
|
||||
function setContext(key, context) {
|
||||
get_current_component().$$.context.set(key, context);
|
||||
return context;
|
||||
}
|
||||
function getContext(key) {
|
||||
return get_current_component().$$.context.get(key);
|
||||
}
|
||||
const _boolean_attributes = [
|
||||
"allowfullscreen",
|
||||
"allowpaymentrequest",
|
||||
"async",
|
||||
"autofocus",
|
||||
"autoplay",
|
||||
"checked",
|
||||
"controls",
|
||||
"default",
|
||||
"defer",
|
||||
"disabled",
|
||||
"formnovalidate",
|
||||
"hidden",
|
||||
"inert",
|
||||
"ismap",
|
||||
"loop",
|
||||
"multiple",
|
||||
"muted",
|
||||
"nomodule",
|
||||
"novalidate",
|
||||
"open",
|
||||
"playsinline",
|
||||
"readonly",
|
||||
"required",
|
||||
"reversed",
|
||||
"selected"
|
||||
];
|
||||
const boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]);
|
||||
const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
|
||||
function is_void(name) {
|
||||
return void_element_names.test(name) || name.toLowerCase() === "!doctype";
|
||||
}
|
||||
const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
|
||||
function spread(args, attrs_to_add) {
|
||||
const attributes = Object.assign({}, ...args);
|
||||
if (attrs_to_add) {
|
||||
const classes_to_add = attrs_to_add.classes;
|
||||
const styles_to_add = attrs_to_add.styles;
|
||||
if (classes_to_add) {
|
||||
if (attributes.class == null) {
|
||||
attributes.class = classes_to_add;
|
||||
} else {
|
||||
attributes.class += " " + classes_to_add;
|
||||
}
|
||||
}
|
||||
if (styles_to_add) {
|
||||
if (attributes.style == null) {
|
||||
attributes.style = style_object_to_string(styles_to_add);
|
||||
} else {
|
||||
attributes.style = style_object_to_string(merge_ssr_styles(attributes.style, styles_to_add));
|
||||
}
|
||||
}
|
||||
}
|
||||
let str = "";
|
||||
Object.keys(attributes).forEach((name) => {
|
||||
if (invalid_attribute_name_character.test(name))
|
||||
return;
|
||||
const value = attributes[name];
|
||||
if (value === true)
|
||||
str += " " + name;
|
||||
else if (boolean_attributes.has(name.toLowerCase())) {
|
||||
if (value)
|
||||
str += " " + name;
|
||||
} else if (value != null) {
|
||||
str += ` ${name}="${value}"`;
|
||||
}
|
||||
});
|
||||
return str;
|
||||
}
|
||||
function merge_ssr_styles(style_attribute, style_directive) {
|
||||
const style_object = {};
|
||||
for (const individual_style of style_attribute.split(";")) {
|
||||
const colon_index = individual_style.indexOf(":");
|
||||
const name = individual_style.slice(0, colon_index).trim();
|
||||
const value = individual_style.slice(colon_index + 1).trim();
|
||||
if (!name)
|
||||
continue;
|
||||
style_object[name] = value;
|
||||
}
|
||||
for (const name in style_directive) {
|
||||
const value = style_directive[name];
|
||||
if (value) {
|
||||
style_object[name] = value;
|
||||
} else {
|
||||
delete style_object[name];
|
||||
}
|
||||
}
|
||||
return style_object;
|
||||
}
|
||||
const ATTR_REGEX = /[&"]/g;
|
||||
const CONTENT_REGEX = /[&<]/g;
|
||||
function escape(value, is_attr = false) {
|
||||
const str = String(value);
|
||||
const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;
|
||||
pattern.lastIndex = 0;
|
||||
let escaped = "";
|
||||
let last = 0;
|
||||
while (pattern.test(str)) {
|
||||
const i = pattern.lastIndex - 1;
|
||||
const ch = str[i];
|
||||
escaped += str.substring(last, i) + (ch === "&" ? "&" : ch === '"' ? """ : "<");
|
||||
last = i + 1;
|
||||
}
|
||||
return escaped + str.substring(last);
|
||||
}
|
||||
function escape_attribute_value(value) {
|
||||
const should_escape = typeof value === "string" || value && typeof value === "object";
|
||||
return should_escape ? escape(value, true) : value;
|
||||
}
|
||||
function escape_object(obj) {
|
||||
const result = {};
|
||||
for (const key in obj) {
|
||||
result[key] = escape_attribute_value(obj[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function each(items, fn) {
|
||||
let str = "";
|
||||
for (let i = 0; i < items.length; i += 1) {
|
||||
str += fn(items[i], i);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
const missing_component = {
|
||||
$$render: () => ""
|
||||
};
|
||||
function validate_component(component, name) {
|
||||
if (!component || !component.$$render) {
|
||||
if (name === "svelte:component")
|
||||
name += " this={...}";
|
||||
throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules. Otherwise you may need to fix a <${name}>.`);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
let on_destroy;
|
||||
function create_ssr_component(fn) {
|
||||
function $$render(result, props, bindings, slots, context) {
|
||||
const parent_component = current_component;
|
||||
const $$ = {
|
||||
on_destroy,
|
||||
context: new Map(context || (parent_component ? parent_component.$$.context : [])),
|
||||
// these will be immediately discarded
|
||||
on_mount: [],
|
||||
before_update: [],
|
||||
after_update: [],
|
||||
callbacks: blank_object()
|
||||
};
|
||||
set_current_component({ $$ });
|
||||
const html = fn(result, props, bindings, slots);
|
||||
set_current_component(parent_component);
|
||||
return html;
|
||||
}
|
||||
return {
|
||||
render: (props = {}, { $$slots = {}, context = /* @__PURE__ */ new Map() } = {}) => {
|
||||
on_destroy = [];
|
||||
const result = { title: "", head: "", css: /* @__PURE__ */ new Set() };
|
||||
const html = $$render(result, props, {}, $$slots, context);
|
||||
run_all(on_destroy);
|
||||
return {
|
||||
html,
|
||||
css: {
|
||||
code: Array.from(result.css).map((css) => css.code).join("\n"),
|
||||
map: null
|
||||
// TODO
|
||||
},
|
||||
head: result.title + result.head
|
||||
};
|
||||
},
|
||||
$$render
|
||||
};
|
||||
}
|
||||
function add_attribute(name, value, boolean) {
|
||||
if (value == null || boolean && !value)
|
||||
return "";
|
||||
const assignment = boolean && value === true ? "" : `="${escape(value, true)}"`;
|
||||
return ` ${name}${assignment}`;
|
||||
}
|
||||
function style_object_to_string(style_object) {
|
||||
return Object.keys(style_object).filter((key) => style_object[key]).map((key) => `${key}: ${escape_attribute_value(style_object[key])};`).join(" ");
|
||||
}
|
||||
export {
|
||||
subscribe as a,
|
||||
get_store_value as b,
|
||||
create_ssr_component as c,
|
||||
each as d,
|
||||
escape as e,
|
||||
spread as f,
|
||||
getContext as g,
|
||||
escape_object as h,
|
||||
is_void as i,
|
||||
add_attribute as j,
|
||||
compute_rest_props as k,
|
||||
escape_attribute_value as l,
|
||||
missing_component as m,
|
||||
noop as n,
|
||||
safe_not_equal as o,
|
||||
is_function as p,
|
||||
run_all as r,
|
||||
setContext as s,
|
||||
validate_component as v
|
||||
};
|
|
@ -0,0 +1,187 @@
|
|||
import { c as create_ssr_component, s as setContext, v as validate_component, m as missing_component } from "./index3.js";
|
||||
let base = "";
|
||||
let assets = base;
|
||||
const initial = { base, assets };
|
||||
function reset() {
|
||||
base = initial.base;
|
||||
assets = initial.assets;
|
||||
}
|
||||
function set_assets(path) {
|
||||
assets = initial.assets = path;
|
||||
}
|
||||
let public_env = {};
|
||||
function set_private_env(environment) {
|
||||
}
|
||||
function set_public_env(environment) {
|
||||
public_env = environment;
|
||||
}
|
||||
function afterUpdate() {
|
||||
}
|
||||
function set_building() {
|
||||
}
|
||||
const Root = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let { stores } = $$props;
|
||||
let { page } = $$props;
|
||||
let { constructors } = $$props;
|
||||
let { components = [] } = $$props;
|
||||
let { form } = $$props;
|
||||
let { data_0 = null } = $$props;
|
||||
let { data_1 = null } = $$props;
|
||||
{
|
||||
setContext("__svelte__", stores);
|
||||
}
|
||||
afterUpdate(stores.page.notify);
|
||||
if ($$props.stores === void 0 && $$bindings.stores && stores !== void 0)
|
||||
$$bindings.stores(stores);
|
||||
if ($$props.page === void 0 && $$bindings.page && page !== void 0)
|
||||
$$bindings.page(page);
|
||||
if ($$props.constructors === void 0 && $$bindings.constructors && constructors !== void 0)
|
||||
$$bindings.constructors(constructors);
|
||||
if ($$props.components === void 0 && $$bindings.components && components !== void 0)
|
||||
$$bindings.components(components);
|
||||
if ($$props.form === void 0 && $$bindings.form && form !== void 0)
|
||||
$$bindings.form(form);
|
||||
if ($$props.data_0 === void 0 && $$bindings.data_0 && data_0 !== void 0)
|
||||
$$bindings.data_0(data_0);
|
||||
if ($$props.data_1 === void 0 && $$bindings.data_1 && data_1 !== void 0)
|
||||
$$bindings.data_1(data_1);
|
||||
let $$settled;
|
||||
let $$rendered;
|
||||
do {
|
||||
$$settled = true;
|
||||
{
|
||||
stores.page.set(page);
|
||||
}
|
||||
$$rendered = `
|
||||
|
||||
|
||||
${constructors[1] ? `${validate_component(constructors[0] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_0, this: components[0] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[0] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return `${validate_component(constructors[1] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_1, form, this: components[1] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[1] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{}
|
||||
)}`;
|
||||
}
|
||||
}
|
||||
)}` : `${validate_component(constructors[0] || missing_component, "svelte:component").$$render(
|
||||
$$result,
|
||||
{ data: data_0, form, this: components[0] },
|
||||
{
|
||||
this: ($$value) => {
|
||||
components[0] = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
},
|
||||
{}
|
||||
)}`}
|
||||
|
||||
${``}`;
|
||||
} while (!$$settled);
|
||||
return $$rendered;
|
||||
});
|
||||
const options = {
|
||||
app_template_contains_nonce: false,
|
||||
csp: { "mode": "auto", "directives": { "upgrade-insecure-requests": false, "block-all-mixed-content": false }, "reportOnly": { "upgrade-insecure-requests": false, "block-all-mixed-content": false } },
|
||||
csrf_check_origin: true,
|
||||
embedded: false,
|
||||
env_public_prefix: "PUBLIC_",
|
||||
hooks: null,
|
||||
// added lazily, via `get_hooks`
|
||||
preload_strategy: "modulepreload",
|
||||
root: Root,
|
||||
service_worker: false,
|
||||
templates: {
|
||||
app: ({ head, body, assets: assets2, nonce, env }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <link rel="icon" href="' + assets2 + '/favicon.png" />\n <meta name="viewport" content="width=device-width" />\n ' + head + '\n </head>\n <body data-sveltekit-preload-data="hover">\n <div style="display: contents">' + body + "</div>\n </body>\n</html>\n",
|
||||
error: ({ status, message }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>' + message + `</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
--bg: white;
|
||||
--fg: #222;
|
||||
--divider: #ccc;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 32rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-weight: 200;
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
top: -0.05rem;
|
||||
}
|
||||
|
||||
.message {
|
||||
border-left: 1px solid var(--divider);
|
||||
padding: 0 0 0 1rem;
|
||||
margin: 0 0 0 1rem;
|
||||
min-height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message h1 {
|
||||
font-weight: 400;
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
--bg: #222;
|
||||
--fg: #ddd;
|
||||
--divider: #666;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error">
|
||||
<span class="status">` + status + '</span>\n <div class="message">\n <h1>' + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n"
|
||||
},
|
||||
version_hash: "10ptubg"
|
||||
};
|
||||
function get_hooks() {
|
||||
return {};
|
||||
}
|
||||
export {
|
||||
assets as a,
|
||||
base as b,
|
||||
set_assets as c,
|
||||
set_building as d,
|
||||
set_private_env as e,
|
||||
get_hooks as g,
|
||||
options as o,
|
||||
public_env as p,
|
||||
reset as r,
|
||||
set_public_env as s
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
import { g as getContext, c as create_ssr_component, a as subscribe, e as escape } from "../../chunks/index3.js";
|
||||
const getStores = () => {
|
||||
const stores = getContext("__svelte__");
|
||||
return {
|
||||
page: {
|
||||
subscribe: stores.page.subscribe
|
||||
},
|
||||
navigating: {
|
||||
subscribe: stores.navigating.subscribe
|
||||
},
|
||||
updated: stores.updated
|
||||
};
|
||||
};
|
||||
const page = {
|
||||
/** @param {(value: any) => void} fn */
|
||||
subscribe(fn) {
|
||||
const store = getStores().page;
|
||||
return store.subscribe(fn);
|
||||
}
|
||||
};
|
||||
const Error$1 = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
let $page, $$unsubscribe_page;
|
||||
$$unsubscribe_page = subscribe(page, (value) => $page = value);
|
||||
$$unsubscribe_page();
|
||||
return `<h1>${escape($page.status)}</h1>
|
||||
<p>${escape($page.error?.message)}</p>`;
|
||||
});
|
||||
export {
|
||||
Error$1 as default
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
import { c as create_ssr_component } from "../../chunks/index3.js";
|
||||
const app = "";
|
||||
const Layout = create_ssr_component(($$result, $$props, $$bindings, slots) => {
|
||||
return `<div class="flex flex-col items-center py-14">${slots.default ? slots.default({}) : ``}</div>`;
|
||||
});
|
||||
export {
|
||||
Layout as default
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
export const index = 0;
|
||||
export const component = async () => (await import('../entries/pages/_layout.svelte.js')).default;
|
||||
export const file = '_app/immutable/entry/_layout.svelte.62a505d3.js';
|
||||
export const imports = ["_app/immutable/entry/_layout.svelte.62a505d3.js","_app/immutable/chunks/index.3641fafa.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/_layout.b9bcc4f4.css"];
|
||||
export const fonts = [];
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
export const index = 1;
|
||||
export const component = async () => (await import('../entries/fallbacks/error.svelte.js')).default;
|
||||
export const file = '_app/immutable/entry/error.svelte.a6bd0229.js';
|
||||
export const imports = ["_app/immutable/entry/error.svelte.a6bd0229.js","_app/immutable/chunks/index.3641fafa.js","_app/immutable/chunks/singletons.8077db6c.js","_app/immutable/chunks/index.fa397836.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
|
@ -0,0 +1,51 @@
|
|||
import { installPolyfills } from '@sveltejs/kit/node/polyfills';
|
||||
import { getRequest, setResponse } from '@sveltejs/kit/node';
|
||||
import { Server } from '../output/server/index.js';
|
||||
import { manifest } from './manifest.js';
|
||||
|
||||
installPolyfills();
|
||||
|
||||
const server = new Server(manifest);
|
||||
|
||||
await server.init({
|
||||
env: /** @type {Record<string, string>} */ (process.env)
|
||||
});
|
||||
|
||||
const DATA_SUFFIX = '/__data.json';
|
||||
|
||||
/**
|
||||
* @param {import('http').IncomingMessage} req
|
||||
* @param {import('http').ServerResponse} res
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
if (req.url) {
|
||||
const [path, search] = req.url.split('?');
|
||||
|
||||
const params = new URLSearchParams(search);
|
||||
const pathname = params.get('__pathname');
|
||||
|
||||
if (pathname) {
|
||||
params.delete('__pathname');
|
||||
req.url = `${pathname}${path.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : ''}?${params}`;
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Request} */
|
||||
let request;
|
||||
|
||||
try {
|
||||
request = await getRequest({ base: `https://${req.headers.host}`, request: req });
|
||||
} catch (err) {
|
||||
res.statusCode = /** @type {any} */ (err).status || 400;
|
||||
return res.end('Invalid request body');
|
||||
}
|
||||
|
||||
setResponse(
|
||||
res,
|
||||
await server.respond(request, {
|
||||
getClientAddress() {
|
||||
return /** @type {string} */ (request.headers.get('x-forwarded-for'));
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
export const manifest = {
|
||||
appDir: "_app",
|
||||
appPath: "_app",
|
||||
assets: new Set(["favicon.png"]),
|
||||
mimeTypes: {".png":"image/png"},
|
||||
_: {
|
||||
client: {"start":{"file":"_app/immutable/entry/start.c62adf58.js","imports":["_app/immutable/entry/start.c62adf58.js","_app/immutable/chunks/index.3641fafa.js","_app/immutable/chunks/singletons.8077db6c.js","_app/immutable/chunks/index.fa397836.js"],"stylesheets":[],"fonts":[]},"app":{"file":"_app/immutable/entry/app.c59518f6.js","imports":["_app/immutable/entry/app.c59518f6.js","_app/immutable/chunks/index.3641fafa.js"],"stylesheets":[],"fonts":[]}},
|
||||
nodes: [
|
||||
() => import('../output/server/nodes/0.js'),
|
||||
() => import('../output/server/nodes/1.js')
|
||||
],
|
||||
routes: [
|
||||
|
||||
],
|
||||
matchers: async () => {
|
||||
|
||||
return { };
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"runtime": "nodejs18.x",
|
||||
"handler": ".svelte-kit/vercel-tmp/index.js",
|
||||
"launcherType": "Nodejs",
|
||||
"experimentalResponseStreaming": true
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"type":"module"}
|
|
@ -0,0 +1,711 @@
|
|||
/* Write your global styles here, in PostCSS syntax */
|
||||
/* ! tailwindcss v3.3.1 | MIT License | https://tailwindcss.com */
|
||||
/*
|
||||
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||
*/
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box; /* 1 */
|
||||
border-width: 0; /* 2 */
|
||||
border-style: solid; /* 2 */
|
||||
border-color: #e5e7eb; /* 2 */
|
||||
}
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
5. Use the user's configured `sans` font-feature-settings by default.
|
||||
6. Use the user's configured `sans` font-variation-settings by default.
|
||||
*/
|
||||
html {
|
||||
line-height: 1.5; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-moz-tab-size: 4; /* 3 */
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4; /* 3 */
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
|
||||
font-feature-settings: normal; /* 5 */
|
||||
font-variation-settings: normal; /* 6 */
|
||||
}
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
body {
|
||||
margin: 0; /* 1 */
|
||||
line-height: inherit; /* 2 */
|
||||
}
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
hr {
|
||||
height: 0; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
border-top-width: 1px; /* 3 */
|
||||
}
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
abbr:where([title]) {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
/*
|
||||
1. Use the user's configured `mono` font family by default.
|
||||
2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
/*
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
/*
|
||||
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||
*/
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
table {
|
||||
text-indent: 0; /* 1 */
|
||||
border-color: inherit; /* 2 */
|
||||
border-collapse: collapse; /* 3 */
|
||||
}
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
font-weight: inherit; /* 1 */
|
||||
line-height: inherit; /* 1 */
|
||||
color: inherit; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
padding: 0; /* 3 */
|
||||
}
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
button,
|
||||
[type='button'],
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
background-color: transparent; /* 2 */
|
||||
background-image: none; /* 2 */
|
||||
}
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
:-moz-focusring {
|
||||
outline: auto;
|
||||
}
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
::-webkit-inner-spin-button,
|
||||
::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
/*
|
||||
1. Correct the odd appearance in Chrome and Safari.
|
||||
2. Correct the outline style in Safari.
|
||||
*/
|
||||
[type='search'] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
/*
|
||||
Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
opacity: 1; /* 1 */
|
||||
color: #9ca3af; /* 2 */
|
||||
}
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1; /* 1 */
|
||||
color: #9ca3af; /* 2 */
|
||||
}
|
||||
/*
|
||||
Set the default cursor for buttons.
|
||||
*/
|
||||
button,
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
/*
|
||||
Make sure disabled buttons don't get the pointer cursor.
|
||||
*/
|
||||
:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block; /* 1 */
|
||||
vertical-align: middle; /* 2 */
|
||||
}
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
/* Make elements with the HTML hidden attribute stay hidden by default */
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
.right-1 {
|
||||
right: 0.25rem;
|
||||
}
|
||||
.z-10 {
|
||||
z-index: 10;
|
||||
}
|
||||
.mb-2 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.ml-\[-0\.5rem\] {
|
||||
margin-left: -0.5rem;
|
||||
}
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
.inline {
|
||||
display: inline;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.contents {
|
||||
display: contents;
|
||||
}
|
||||
.h-4 {
|
||||
height: 1rem;
|
||||
}
|
||||
.h-\[700px\] {
|
||||
height: 700px;
|
||||
}
|
||||
.max-h-5 {
|
||||
max-height: 1.25rem;
|
||||
}
|
||||
.w-4 {
|
||||
width: 1rem;
|
||||
}
|
||||
.w-\[350px\] {
|
||||
width: 350px;
|
||||
}
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
.max-w-2xl {
|
||||
max-width: 42rem;
|
||||
}
|
||||
.max-w-6xl {
|
||||
max-width: 72rem;
|
||||
}
|
||||
.flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
.flex-shrink-0 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
.justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.gap-3 {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
.overflow-y-auto {
|
||||
overflow-y: auto;
|
||||
}
|
||||
.text-ellipsis {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.break-all {
|
||||
word-break: break-all;
|
||||
}
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
.rounded-md {
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
.border {
|
||||
border-width: 1px;
|
||||
}
|
||||
.border-black\/40 {
|
||||
border-color: rgb(0 0 0 / 0.4);
|
||||
}
|
||||
.border-transparent {
|
||||
border-color: transparent;
|
||||
}
|
||||
.border-white\/20 {
|
||||
border-color: rgb(255 255 255 / 0.2);
|
||||
}
|
||||
.bg-black {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
.bg-white\/10 {
|
||||
background-color: rgb(255 255 255 / 0.1);
|
||||
}
|
||||
.bg-opacity-20 {
|
||||
--tw-bg-opacity: 0.2;
|
||||
}
|
||||
.bg-opacity-40 {
|
||||
--tw-bg-opacity: 0.4;
|
||||
}
|
||||
.p-1 {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.p-2 {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
.p-4 {
|
||||
padding: 1rem;
|
||||
}
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.px-3 {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.px-8 {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
.py-0 {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
.py-0\.5 {
|
||||
padding-top: 0.125rem;
|
||||
padding-bottom: 0.125rem;
|
||||
}
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
.py-1\.5 {
|
||||
padding-top: 0.375rem;
|
||||
padding-bottom: 0.375rem;
|
||||
}
|
||||
.py-14 {
|
||||
padding-top: 3.5rem;
|
||||
padding-bottom: 3.5rem;
|
||||
}
|
||||
.py-3 {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
.py-4 {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.pr-14 {
|
||||
padding-right: 3.5rem;
|
||||
}
|
||||
.pt-4 {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
.text-sm {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
.text-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
.leading-loose {
|
||||
line-height: 2;
|
||||
}
|
||||
.text-gray-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity));
|
||||
}
|
||||
.text-gray-400 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-text-opacity));
|
||||
}
|
||||
.text-rose-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(190 18 60 / var(--tw-text-opacity));
|
||||
}
|
||||
.text-teal-300 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(94 234 212 / var(--tw-text-opacity));
|
||||
}
|
||||
.text-teal-400 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(45 212 191 / var(--tw-text-opacity));
|
||||
}
|
||||
.text-white {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
.shadow {
|
||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
.transition-colors {
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
.duration-200 {
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
:root {
|
||||
--cyan-100: 183 90% 90%;
|
||||
--cyan-200: 183 90% 80%;
|
||||
--cyan-300: 183 90% 70%;
|
||||
--cyan-400: 183 90% 60%;
|
||||
--cyan-500: 183 90% 50%;
|
||||
--cyan-600: 183 90% 40%;
|
||||
--cyan-700: 183 90% 30%;
|
||||
--cyan-800: 183 90% 20%;
|
||||
--cyan-900: 183 90% 10%;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
font-family: Helvetica, sans-serif;
|
||||
}
|
||||
pre {
|
||||
display: inline-flex;
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
border-radius: 0.25rem
|
||||
}
|
||||
code {
|
||||
background-color: rgba(44, 43, 43, 0.6);
|
||||
color: rgb(190 18 60 / var(--tw-text-opacity));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
|
||||
}
|
||||
body {
|
||||
color: white;
|
||||
background-color: #131416;
|
||||
}
|
||||
ol {
|
||||
list-style: number;
|
||||
padding: 1rem;
|
||||
}
|
||||
ol > li {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.hover\:bg-gray-500\/10:hover {
|
||||
background-color: rgb(107 114 128 / 0.1);
|
||||
}
|
||||
.hover\:bg-white\/5:hover {
|
||||
background-color: rgb(255 255 255 / 0.05);
|
||||
}
|
||||
.hover\:text-white:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
.focus\:border-transparent:focus {
|
||||
border-color: transparent;
|
||||
}
|
||||
.focus\:outline-none:focus {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.focus\:ring-1:focus {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
}
|
||||
.focus\:ring-teal-300:focus {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(94 234 212 / var(--tw-ring-opacity));
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
import{default as t}from"../entry/_layout.svelte.62a505d3.js";export{t as component};
|
|
@ -0,0 +1 @@
|
|||
import{default as t}from"../entry/error.svelte.a6bd0229.js";export{t as component};
|
|
@ -0,0 +1 @@
|
|||
import{default as t}from"../entry/_page.svelte.2f89fa28.js";export{t as component};
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
import{H as f,a4 as y,P as m,s as q,Z as w}from"./index.3641fafa.js";const o=[];function z(e,u){return{subscribe:A(e,u).subscribe}}function A(e,u=f){let r;const n=new Set;function a(t){if(q(e,t)&&(e=t,r)){const i=!o.length;for(const s of n)s[1](),o.push(s,e);if(i){for(let s=0;s<o.length;s+=2)o[s][0](o[s+1]);o.length=0}}}function l(t){a(t(e))}function b(t,i=f){const s=[t,i];return n.add(s),n.size===1&&(r=u(a)||f),t(e),()=>{n.delete(s),n.size===0&&r&&(r(),r=null)}}return{set:a,update:l,subscribe:b}}function H(e,u,r){const n=!Array.isArray(e),a=n?[e]:e,l=u.length<2;return z(r,b=>{let t=!1;const i=[];let s=0,d=f;const g=()=>{if(s)return;d();const c=u(n?i[0]:i,b);l?b(c):d=w(c)?c:f},_=a.map((c,p)=>y(c,h=>{i[p]=h,s&=~(1<<p),t&&g()},()=>{s|=1<<p}));return t=!0,g(),function(){m(_),d(),t=!1}})}export{H as d,A as w};
|
|
@ -0,0 +1 @@
|
|||
import{w as u}from"./index.fa397836.js";var _;const g=((_=globalThis.__sveltekit_10ptubg)==null?void 0:_.base)??"";var h;const v=((h=globalThis.__sveltekit_10ptubg)==null?void 0:h.assets)??g,k="1680580103854",A="sveltekit:snapshot",R="sveltekit:scroll",T="sveltekit:index",f={tap:1,hover:2,viewport:3,eager:4,off:-1};function I(e){let t=e.baseURI;if(!t){const n=e.getElementsByTagName("base");t=n.length?n[0].href:e.URL}return t}function S(){return{x:pageXOffset,y:pageYOffset}}function i(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const d={...f,"":f.hover};function b(e){let t=e.assignedSlot??e.parentNode;return(t==null?void 0:t.nodeType)===11&&(t=t.host),t}function y(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=b(e)}}function x(e,t){let n;try{n=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI)}catch{}const l=e instanceof SVGAElement?e.target.baseVal:e.target,a=!n||!!l||m(n,t)||(e.getAttribute("rel")||"").split(/\s+/).includes("external")||e.hasAttribute("download");return{url:n,external:a,target:l}}function O(e){let t=null,n=null,l=null,a=null,r=null,o=null,s=e;for(;s&&s!==document.documentElement;)l===null&&(l=i(s,"preload-code")),a===null&&(a=i(s,"preload-data")),t===null&&(t=i(s,"keepfocus")),n===null&&(n=i(s,"noscroll")),r===null&&(r=i(s,"reload")),o===null&&(o=i(s,"replacestate")),s=b(s);return{preload_code:d[l??"off"],preload_data:d[a??"off"],keep_focus:t==="off"?!1:t===""?!0:null,noscroll:n==="off"?!1:n===""?!0:null,reload:r==="off"?!1:r===""?!0:null,replace_state:o==="off"?!1:o===""?!0:null}}function p(e){const t=u(e);let n=!0;function l(){n=!0,t.update(o=>o)}function a(o){n=!1,t.set(o)}function r(o){let s;return t.subscribe(c=>{(s===void 0||n&&c!==s)&&o(s=c)})}return{notify:l,set:a,subscribe:r}}function E(){const{set:e,subscribe:t}=u(!1);let n;async function l(){clearTimeout(n);const a=await fetch(`${v}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(a.ok){const o=(await a.json()).version!==k;return o&&(e(!0),clearTimeout(n)),o}else throw new Error(`Version check failed: ${a.status}`)}return{subscribe:t,check:l}}function m(e,t){return e.origin!==location.origin||!e.pathname.startsWith(t)}function U(e){e.client}const L={url:p({}),page:p({}),navigating:u(null),updated:E()};export{T as I,f as P,R as S,A as a,x as b,O as c,S as d,g as e,y as f,I as g,U as h,m as i,L as s};
|
|
@ -0,0 +1 @@
|
|||
import{S as r,i as f,s as u,C as c,k as _,l as d,m,h as o,n as p,b as h,D as $,E as v,F as g,g as y,d as b}from"../chunks/index.3641fafa.js";function C(n){let s,a;const i=n[1].default,e=c(i,n,n[0],null);return{c(){s=_("div"),e&&e.c(),this.h()},l(t){s=d(t,"DIV",{class:!0});var l=m(s);e&&e.l(l),l.forEach(o),this.h()},h(){p(s,"class","flex flex-col items-center py-14")},m(t,l){h(t,s,l),e&&e.m(s,null),a=!0},p(t,[l]){e&&e.p&&(!a||l&1)&&$(e,i,t,t[0],a?g(i,t[0],l,null):v(t[0]),null)},i(t){a||(y(e,t),a=!0)},o(t){b(e,t),a=!1},d(t){t&&o(s),e&&e.d(t)}}}function D(n,s,a){let{$$slots:i={},$$scope:e}=s;return n.$$set=t=>{"$$scope"in t&&a(0,e=t.$$scope)},[e,i]}class S extends r{constructor(s){super(),f(this,s,D,C,u,{})}}export{S as default};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
import{S,i as q,s as x,k as f,q as _,a as H,l as d,m as g,r as h,h as u,c as k,b as m,G as v,u as $,H as E,I as y}from"../chunks/index.3641fafa.js";import{s as C}from"../chunks/singletons.8077db6c.js";const G=()=>{const s=C;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},I={subscribe(s){return G().page.subscribe(s)}};function P(s){var b;let t,r=s[0].status+"",o,n,i,c=((b=s[0].error)==null?void 0:b.message)+"",l;return{c(){t=f("h1"),o=_(r),n=H(),i=f("p"),l=_(c)},l(e){t=d(e,"H1",{});var a=g(t);o=h(a,r),a.forEach(u),n=k(e),i=d(e,"P",{});var p=g(i);l=h(p,c),p.forEach(u)},m(e,a){m(e,t,a),v(t,o),m(e,n,a),m(e,i,a),v(i,l)},p(e,[a]){var p;a&1&&r!==(r=e[0].status+"")&&$(o,r),a&1&&c!==(c=((p=e[0].error)==null?void 0:p.message)+"")&&$(l,c)},i:E,o:E,d(e){e&&u(t),e&&u(n),e&&u(i)}}}function j(s,t,r){let o;return y(s,I,n=>r(0,o=n)),[o]}let A=class extends S{constructor(t){super(),q(this,t,j,P,x,{})}};export{A as default};
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"version":"1680580103854"}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,42 @@
|
|||
# Another SvelteKit ChatGPT UI
|
||||
|
||||
Video Link: https://ivanprojects.s3.us-west-1.amazonaws.com/Screen+Recording+2023-03-10+at+10.11.18+AM.mov
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
- Formatted Markdown Responses
|
||||
- Persisted Chat History (Setup for local storage but able to be adapted)
|
||||
- Auto Scrolling/Message streaming
|
||||
|
||||
## Using the App
|
||||
1. pnpm Install
|
||||
2. Add an OPENAI_KEY to an .env file with your open ai key
|
||||
3. Enjoy
|
||||
|
||||
|
||||
## Stores
|
||||
- Chat Messages
|
||||
- Chat Messages (Derived)
|
||||
- Answer
|
||||
- Chat History
|
||||
|
||||
### Chat Messages
|
||||
The chat messages store stores the transcript for the current active conversation.
|
||||
When a question is submitted it posts to the api endpoint and if it gets a 200 starts to stream the answer.
|
||||
|
||||
**Answer Store**
|
||||
The answer store is what holds answer being streamed. While the AI is typing the answer store is being updated, and when the response is 'DONE' the answer is appended to the active transcript and reset to a blank string.
|
||||
|
||||
The use of two separate stores allows for a single update to the entire transcript, error checking prior to updating and for there to be no visible difference in the UI when streaming the answer.
|
||||
|
||||
### Chat Messages (Derived)
|
||||
The derived Chat Messages store gets the active conversation starting with the first query and checks to see if there is a 'chatHistory' key in local storage. This store acts as the bridge between the history store and the chat messages store. If there isn't any history in local storage, it creates a key and updates it if there is a query. Once the answer store finishes streaming the answer and updates the original Chat messages store, the derived store updates the key with updated transcript
|
||||
|
||||
### Chat history
|
||||
The Chat history store holds the references to all the various conversations held in local storage. On clicking one it'll update the chat view to display the active transcript.
|
||||
It also handles deleting any of the keys. The Chat history store is set by the derived store, since it is dependant on the existance of messages, the change in those messages, and the existance of a history in local storage.
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "chatbot",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"test:unit": "vitest",
|
||||
"lint": "prettier --plugin-search-dir . --check .",
|
||||
"format": "prettier --plugin-search-dir . --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^2.0.0",
|
||||
"@sveltejs/adapter-vercel": "^2.3.0",
|
||||
"@sveltejs/kit": "^1.5.0",
|
||||
"@types/common-tags": "^1.8.1",
|
||||
"@types/dompurify": "^2.4.0",
|
||||
"@types/marked": "^4.0.8",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"dompurify": "^3.0.1",
|
||||
"gpt3-tokenizer": "^1.1.5",
|
||||
"isomorphic-dompurify": "^1.1.0",
|
||||
"marked": "^4.2.12",
|
||||
"openai": "^3.2.1",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"sse.js": "^0.6.1",
|
||||
"svelte": "^3.54.0",
|
||||
"svelte-check": "^3.0.1",
|
||||
"svelte-exmarkdown": "^2.0.0",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"svelte-preprocess-markdown": "^2.7.3",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.9.3",
|
||||
"vite": "^4.0.0",
|
||||
"vitest": "^0.25.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
const tailwindcss = require("tailwindcss");
|
||||
const autoprefixer = require("autoprefixer");
|
||||
|
||||
const config = {
|
||||
plugins: [
|
||||
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||
tailwindcss(),
|
||||
//But others, like autoprefixer, need to run after,
|
||||
autoprefixer,
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
|
@ -0,0 +1,39 @@
|
|||
/* Write your global styles here, in PostCSS syntax */
|
||||
@import './styles/tailwind.css';
|
||||
@import './styles/vars.css';
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
font-family: Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: inline-flex;
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
border-radius: 0.25rem
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: rgba(44, 43, 43, 0.6);
|
||||
color: rgb(190 18 60 / var(--tw-text-opacity));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
|
||||
}
|
||||
|
||||
body {
|
||||
color: white;
|
||||
background-color: #131416;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: number;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
ol > li {
|
||||
margin: 1rem 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('sum test', () => {
|
||||
it('adds 1 + 2 to equal 3', () => {
|
||||
expect(1 + 2).toBe(3);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import Chat from './Icons/Chat.svelte';
|
||||
import Pencil from './Icons/Pencil.svelte';
|
||||
import Plus from './Icons/Plus.svelte';
|
||||
import Trash from './Icons/Trash.svelte';
|
||||
|
||||
import { chatMessages } from '$lib/stores/chat-messages';
|
||||
import {
|
||||
chatHistory,
|
||||
filterHistory,
|
||||
chatHistorySubscription,
|
||||
loadMessages
|
||||
} from '../stores/chat-history';
|
||||
|
||||
let chatHistoryKeys: any = [];
|
||||
|
||||
onMount(() => {
|
||||
chatHistorySubscription.set($chatHistory);
|
||||
chatHistorySubscription.subscribe((value: any) => {
|
||||
chatHistoryKeys = Object.keys(value);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="h-[700px] w-[350px] bg-black bg-opacity-20 rounded-md py-4 px-2 overflow-y-auto flex flex-col gap-2"
|
||||
>
|
||||
<button
|
||||
on:click={chatMessages.reset}
|
||||
class="flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white cursor-pointer text-sm mb-2 flex-shrink-0 border border-white/20"
|
||||
>
|
||||
<Plus /> New Game
|
||||
</button>
|
||||
|
||||
{#if chatHistoryKeys.length > 0}
|
||||
{#each chatHistoryKeys as message (message)}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
on:click={() => loadMessages(message)}
|
||||
class="flex py-3 px-3 items-center gap-3 relative rounded-md cursor-pointer break-all pr-14 bg-opacity-40 hover:bg-white/5 bg-black group animate-flash text-sm"
|
||||
>
|
||||
<Chat />
|
||||
<div class="flex-1 text-ellipsis max-h-5 overflow-hidden break-all relative">{message}</div>
|
||||
|
||||
<div class="absolute flex right-1 z-10 text-gray-300 visible">
|
||||
<button on:click={() => loadMessages(message)} class="p-1 hover:text-white">
|
||||
<Pencil />
|
||||
</button>
|
||||
<button
|
||||
on:click|preventDefault={() => filterHistory(message)}
|
||||
class="p-1 hover:text-white"
|
||||
>
|
||||
<Trash />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
|
@ -0,0 +1,46 @@
|
|||
<script lang="ts">
|
||||
import Markdown from 'svelte-exmarkdown';
|
||||
import { marked } from 'marked';
|
||||
import DOMPurify from 'isomorphic-dompurify';
|
||||
import type { ChatCompletionRequestMessageRoleEnum } from 'openai';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let type: ChatCompletionRequestMessageRoleEnum;
|
||||
export let message: string = '';
|
||||
export { classes as class };
|
||||
|
||||
let classes = '';
|
||||
let scrollToDiv: HTMLDivElement;
|
||||
|
||||
const classSet = {
|
||||
user: 'justify-end text-rose-700',
|
||||
assistant: 'justify-start text-teal-400',
|
||||
system: 'justify-center text-gray-400'
|
||||
};
|
||||
|
||||
const typeEffect = (node: HTMLDivElement, message: string) => {
|
||||
return {
|
||||
update(message: string) {
|
||||
scrollToDiv.scrollIntoView({ behavior: 'auto', block: 'end', inline: 'end' });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
scrollToDiv.scrollIntoView({ behavior: 'auto', block: 'end', inline: 'end' });
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex items-center {classSet[type]} ">
|
||||
<p class="text-xs px-2">{type === 'user' ? 'Me' : 'Bot'}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex {classSet[type]}">
|
||||
<div
|
||||
use:typeEffect={message}
|
||||
class="bg-black py-0.5 px-4 max-w-2xl rounded leading-loose {classes} {classSet[type]}"
|
||||
>
|
||||
{@html DOMPurify.sanitize(marked.parse(message))}
|
||||
</div>
|
||||
<div bind:this={scrollToDiv} />
|
||||
</div>
|
|
@ -0,0 +1,13 @@
|
|||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-4 w-4"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /></svg
|
||||
>
|
After Width: | Height: | Size: 293 B |
|
@ -0,0 +1,13 @@
|
|||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-4 w-4"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path d="M12 20h9" /><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" /></svg
|
||||
>
|
After Width: | Height: | Size: 308 B |
|
@ -0,0 +1,13 @@
|
|||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-4 w-4"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></svg
|
||||
>
|
After Width: | Height: | Size: 297 B |
|
@ -0,0 +1,20 @@
|
|||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="h-4 w-4"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><polyline points="3 6 5 6 21 6" /><path
|
||||
d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
|
||||
/><line x1="10" y1="11" x2="10" y2="17" /><line
|
||||
x1="14"
|
||||
y1="11"
|
||||
x2="14"
|
||||
y2="17"
|
||||
/></svg
|
||||
>
|
After Width: | Height: | Size: 422 B |
|
@ -0,0 +1,25 @@
|
|||
<script lang="ts">
|
||||
export let value: any;
|
||||
export let placeholder = '';
|
||||
export let name = '';
|
||||
export let type = 'text';
|
||||
export let label = '';
|
||||
let classes = '';
|
||||
export { classes as class };
|
||||
|
||||
const typeAction = (node: HTMLInputElement) => {
|
||||
node.type = type;
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col min-w-xl {classes}">
|
||||
<label class="text-xs" for={name}>{label}</label>
|
||||
<input
|
||||
{name}
|
||||
{placeholder}
|
||||
use:typeAction
|
||||
bind:value
|
||||
class="shadow bg-white/10 rounded-md px-4 py-1.5 min-w-xl text-teal-300 border border-transparent focus:outline-none focus:ring-1 focus:ring-teal-300 focus:border-transparent"
|
||||
{...$$restProps}
|
||||
/>
|
||||
</div>
|
|
@ -0,0 +1,53 @@
|
|||
import { derived, get, writable } from 'svelte/store';
|
||||
import { chatMessages, type ChatTranscript } from './chat-messages';
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
export const chatHistorySubscription = writable();
|
||||
|
||||
const setLocalHistory = <T>(history: T) =>
|
||||
localStorage.setItem('chatHistory', JSON.stringify(history));
|
||||
const getLocalHistory = () => JSON.parse(localStorage.getItem('chatHistory') || '{}');
|
||||
|
||||
export const chatHistory = derived(chatMessages, ($chatMessages) => {
|
||||
if (!browser) return null;
|
||||
|
||||
let history = localStorage.getItem('chatHistory');
|
||||
|
||||
if (!history && $chatMessages.messages.length === 1) return null;
|
||||
|
||||
if (history && $chatMessages.messages.length === 1) return JSON.parse(history);
|
||||
|
||||
const key = $chatMessages.messages[1].content; //The second message is the query
|
||||
const value = $chatMessages.messages;
|
||||
const obj = { [key]: value };
|
||||
|
||||
if (!history) setLocalHistory(obj);
|
||||
|
||||
const chatHistory = getLocalHistory();
|
||||
|
||||
if (chatHistory) {
|
||||
chatHistory[key] = value;
|
||||
setLocalHistory(chatHistory);
|
||||
chatHistorySubscription.set(chatHistory);
|
||||
return chatHistory;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
export const filterHistory = (key: string) => {
|
||||
const history = getLocalHistory();
|
||||
delete history[key];
|
||||
setLocalHistory(history);
|
||||
chatHistorySubscription.set(history);
|
||||
};
|
||||
|
||||
const getHistory = (key: string) => getLocalHistory()[key]; //Returns the history for a given key
|
||||
|
||||
export const loadMessages = (query: string) => {
|
||||
if (get(chatMessages).chatState !== 'idle') return; //Prevents switching between messages while loading
|
||||
if (!query) return;
|
||||
|
||||
const newMessages = getHistory(query);
|
||||
chatMessages.replace({ messages: newMessages, chatState: 'idle' });
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
import type { ChatCompletionRequestMessage } from 'openai';
|
||||
import { SSE } from 'sse.js';
|
||||
import { get, writable } from 'svelte/store';
|
||||
|
||||
export interface ChatTranscript {
|
||||
messages: ChatCompletionRequestMessage[];
|
||||
chatState: 'idle' | 'loading' | 'error' | 'message';
|
||||
}
|
||||
|
||||
const { subscribe, update, ...store } = writable<ChatTranscript>({
|
||||
messages: [
|
||||
{ role: 'assistant', content: 'Welcome! Please introduce yourself to your AI competitor.'}
|
||||
],
|
||||
chatState: 'idle'
|
||||
});
|
||||
|
||||
const set = async (query: string) => {
|
||||
updateMessages(query, 'user', 'loading');
|
||||
|
||||
request(query);
|
||||
};
|
||||
|
||||
const request = async (query: string) => {
|
||||
const eventSource = new SSE('/api/chat', {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
payload: JSON.stringify({ messages: get(chatMessages).messages })
|
||||
});
|
||||
|
||||
eventSource.addEventListener('error', handleError);
|
||||
eventSource.addEventListener('message', streamMessage);
|
||||
eventSource.stream();
|
||||
}
|
||||
|
||||
const replace = (messages: ChatTranscript) => {
|
||||
store.set(messages);
|
||||
};
|
||||
|
||||
const reset = () =>
|
||||
store.set({
|
||||
messages: [
|
||||
{ role: 'assistant', content: 'Welcome! Please introduce yourself to your AI competitor.' }
|
||||
],
|
||||
chatState: 'idle'
|
||||
});
|
||||
|
||||
const updateMessages = (content: any, role: any, state: any) => {
|
||||
chatMessages.update((messages: ChatTranscript) => {
|
||||
return { messages: [...messages.messages, { role: role, content: content }], chatState: state };
|
||||
});
|
||||
};
|
||||
|
||||
const handleError = <T>(err: T) => {
|
||||
updateMessages(err, 'system', 'error');
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
const streamMessage = (e: MessageEvent) => {
|
||||
try {
|
||||
if (e.data === '[DONE]') {
|
||||
updateMessages(get(answer), 'assistant', 'idle');
|
||||
return answer.set('');
|
||||
}
|
||||
|
||||
if (get(answer) === '...') answer.set('');
|
||||
|
||||
const completionResponse = JSON.parse(e.data);
|
||||
const [{ delta }] = completionResponse.choices;
|
||||
|
||||
if (delta.content) {
|
||||
answer.update((_a) => _a + delta.content);
|
||||
}
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const chatMessages = { subscribe, set, update, reset, replace };
|
||||
export const answer = writable<string>('');
|
|
@ -0,0 +1,13 @@
|
|||
import GPT3TokenizerImport from 'gpt3-tokenizer';
|
||||
|
||||
const GPT3Tokenizer: typeof GPT3TokenizerImport =
|
||||
typeof GPT3TokenizerImport === 'function'
|
||||
? GPT3TokenizerImport
|
||||
: (GPT3TokenizerImport as any).default;
|
||||
|
||||
const tokenizer = new GPT3Tokenizer({ type: 'gpt3' });
|
||||
|
||||
export function getTokens(input: string): number {
|
||||
const tokens = tokenizer.encode(input);
|
||||
return tokens.text.length;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
import '../app.css';
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col items-center py-14">
|
||||
<slot />
|
||||
</div>
|
|
@ -0,0 +1,69 @@
|
|||
<script lang="ts">
|
||||
import ChatHistory from '$lib/components/ChatHistory.svelte';
|
||||
import ChatMessage from '$lib/components/ChatMessage.svelte';
|
||||
import Input from '$lib/components/Input.svelte';
|
||||
import { chatMessages, answer } from '$lib/stores/chat-messages';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let query = '';
|
||||
const INITIAL_QUERY = `You will erroneously define a randomly chosen English word with the definition of an English word that sounds similar. You will then ask them to guess the correct word for the errornous definition.
|
||||
|
||||
Here is an example of what you would output:
|
||||
|
||||
Today we'll be playing a word game. Here's how it works: I will define a word. But the definition I give it will actually be for a different but similarly-sounding word. You'll have to guess the correct word that is being defined.
|
||||
|
||||
Ready to begin? Here's the first one:
|
||||
|
||||
"A photon is a legendary bird which according to one account lived 500 years, burned itself to ashes on a pyre, and rose alive from the ashes to live another period. What word am I actually describing?"
|
||||
|
||||
---
|
||||
|
||||
To further explain the output, I chose two words that sound similar, photon and phoenix. I am then using the definition of a phoenix to describe a photon, and the user will have to guess that the real word I'm describing is a phoenix.
|
||||
|
||||
Repeat this process until the user incorrectly guesses 3 times.`;
|
||||
|
||||
|
||||
// onMount(async () => {
|
||||
// await chatMessages.set(INITIAL_QUERY);
|
||||
// });
|
||||
|
||||
const handleSubmit = async () => {
|
||||
answer.set('...');
|
||||
await chatMessages.set(query);
|
||||
query = '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<section class="flex max-w-6xl w-full pt-4 justify-center">
|
||||
<div class="flex flex-col gap-2">
|
||||
<ChatHistory />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col w-full px-8 items-center gap-2">
|
||||
<div
|
||||
class="h-[700px] w-full bg-black bg-opacity-20 rounded-md p-4 overflow-y-auto flex flex-col gap-4"
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each $chatMessages.messages as message}
|
||||
<ChatMessage type={message.role} message={message.content} />
|
||||
{/each}
|
||||
|
||||
{#if $answer}
|
||||
<ChatMessage type="assistant" message={$answer} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<form
|
||||
class="flex w-full rounded-md gap-4 bg-black bg-opacity-20 p-2"
|
||||
on:submit|preventDefault={handleSubmit}
|
||||
>
|
||||
<Input type="text" bind:value={query} class="w-full" />
|
||||
<button
|
||||
type="submit"
|
||||
class="bg-black bg-opacity-40 hover:bg-white/5 px-8 py-1.5 border border-black/40 ml-[-0.5rem] rounded-md text-teal-300"
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
|
@ -0,0 +1,115 @@
|
|||
import { OPENAI_KEY } from '$env/static/private';
|
||||
import type { CreateChatCompletionRequest, ChatCompletionRequestMessage } from 'openai';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { getTokens } from '$lib/utils/tokenizer';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { Config } from '@sveltejs/adapter-vercel';
|
||||
|
||||
export const config: Config = {
|
||||
runtime: 'edge'
|
||||
};
|
||||
|
||||
const INITIAL_QUERY = `You are playing a game with the user. You will erroneously define a randomly chosen English word with the definition of an English word that sounds similar. You will then ask them to guess the correct word for the errornous definition.
|
||||
|
||||
Here is an example of what you would output.
|
||||
|
||||
---
|
||||
|
||||
Nice to meet you. Today we'll be playing a word game. Here's how it works: I will define a word. But the definition I give it will actually be for a different but similarly-sounding word. You'll have to guess the correct word that is being defined.
|
||||
|
||||
Ready to begin? Here's the first one:
|
||||
|
||||
"A photon is a legendary bird which according to one account lived 500 years, burned itself to ashes on a pyre, and rose alive from the ashes to live another period. What word am I actually describing?"
|
||||
|
||||
---
|
||||
|
||||
To further explain the output, I chose two words that sound similar, photon and phoenix. I am then using the definition of a phoenix to describe a photon, and the user will have to guess that the real word I'm describing is a phoenix.
|
||||
|
||||
Repeat this process until the user incorrectly guesses 3 times.`;
|
||||
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
if (!OPENAI_KEY) {
|
||||
throw new Error('OPENAI_KEY env variable not set');
|
||||
}
|
||||
|
||||
const requestData = await request.json();
|
||||
|
||||
if (!requestData) {
|
||||
throw new Error('No request data');
|
||||
}
|
||||
|
||||
const reqMessages: ChatCompletionRequestMessage[] = requestData.messages;
|
||||
|
||||
if (!reqMessages) {
|
||||
throw new Error('no messages provided');
|
||||
}
|
||||
|
||||
let tokenCount = 0;
|
||||
|
||||
reqMessages.forEach((msg) => {
|
||||
const tokens = getTokens(msg.content);
|
||||
tokenCount += tokens;
|
||||
});
|
||||
|
||||
const moderationRes = await fetch('https://api.openai.com/v1/moderations', {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${OPENAI_KEY}`
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
input: reqMessages[reqMessages.length - 1].content
|
||||
})
|
||||
});
|
||||
|
||||
const moderationData = await moderationRes.json();
|
||||
const [results] = moderationData.results;
|
||||
|
||||
if (results.flagged) {
|
||||
throw new Error('Query flagged by openai');
|
||||
}
|
||||
|
||||
const prompt = INITIAL_QUERY;
|
||||
tokenCount += getTokens(prompt);
|
||||
|
||||
if (tokenCount >= 4000) {
|
||||
throw new Error('Query too large');
|
||||
}
|
||||
|
||||
const messages: ChatCompletionRequestMessage[] = [
|
||||
{ role: 'system', content: prompt },
|
||||
...reqMessages
|
||||
];
|
||||
|
||||
const chatRequestOpts: CreateChatCompletionRequest = {
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages,
|
||||
temperature: 0.5,
|
||||
stream: true
|
||||
};
|
||||
|
||||
const chatResponse = await fetch('https://api.openai.com/v1/chat/completions', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${OPENAI_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify(chatRequestOpts)
|
||||
});
|
||||
|
||||
if (!chatResponse.ok) {
|
||||
const err = await chatResponse.json();
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
return new Response(chatResponse.body, {
|
||||
headers: {
|
||||
'Content-Type': 'text/event-stream'
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'There was an error processing your request' }, { status: 500 });
|
||||
}
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
|
@ -0,0 +1,11 @@
|
|||
:root {
|
||||
--cyan-100: 183 90% 90%;
|
||||
--cyan-200: 183 90% 80%;
|
||||
--cyan-300: 183 90% 70%;
|
||||
--cyan-400: 183 90% 60%;
|
||||
--cyan-500: 183 90% 50%;
|
||||
--cyan-600: 183 90% 40%;
|
||||
--cyan-700: 183 90% 30%;
|
||||
--cyan-800: 183 90% 20%;
|
||||
--cyan-900: 183 90% 10%;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
declare module 'sse.js' {
|
||||
export type SSEOptions = EventSourceInit & {
|
||||
headers?: Record<string, string>
|
||||
payload?: string
|
||||
method?: string
|
||||
}
|
||||
|
||||
export class SSE extends EventSource {
|
||||
constructor(url: string | URL, sseOptions?: SSEOptions)
|
||||
stream(): void
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,23 @@
|
|||
import preprocess from "svelte-preprocess";
|
||||
import adapter from '@sveltejs/adapter-vercel';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
import {markdown} from 'svelte-preprocess-markdown';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: [vitePreprocess(), preprocess({
|
||||
postcss: true
|
||||
}),
|
||||
markdown()
|
||||
],
|
||||
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
runtime: 'nodejs18.x'
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -0,0 +1,9 @@
|
|||
const defaultTheme = require('tailwindcss/defaultTheme')
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
theme: {},
|
||||
plugins: [],
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"ignoreDeprecations": "5.0"
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import adapter from '@sveltejs/adapter-vercel';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}']
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue