UNPKG

@embedthis/devcore

Version:

Devcore UI Framework

1,561 lines (1,560 loc) 1.28 MB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value; var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value); import { reactive, watch, onMounted, onUnmounted, openBlock, createElementBlock, createBlock, withCtx, createVNode, createTextVNode, toDisplayString, createElementVNode, normalizeClass, withDirectives, normalizeStyle, withModifiers, createCommentVNode, vShow, getCurrentInstance, nextTick, computed, defineComponent, ref, toRefs, inject, watchEffect, provide, unref, resolveDynamicComponent, normalizeProps, mergeProps, renderSlot, Fragment, renderList, withKeys, toRef, guardReactiveProps, isRef, Transition, resolveComponent, resolveDirective, toHandlers, onBeforeMount, TransitionGroup, onBeforeUnmount, createSlots } from "vue"; import { VAlert } from "vuetify/lib/components/VAlert/index.mjs"; import { VDialog } from "vuetify/lib/components/VDialog/index.mjs"; import { VBtn } from "vuetify/lib/components/VBtn/index.mjs"; import { VCard, VCardTitle, VCardText, VCardActions } from "vuetify/lib/components/VCard/index.mjs"; import { VProgressCircular } from "vuetify/lib/components/VProgressCircular/index.mjs"; import { VProgressLinear } from "vuetify/lib/components/VProgressLinear/index.mjs"; import { aliases, mdi } from "vuetify/lib/iconsets/mdi-svg"; import "vuetify/dist/vuetify.min.css"; import { VIcon } from "vuetify/lib/components/VIcon/index.mjs"; import { VDivider } from "vuetify/lib/components/VDivider/index.mjs"; import { VRow, VCol, VSpacer, VContainer } from "vuetify/lib/components/VGrid/index.mjs"; import { VTextField } from "vuetify/lib/components/VTextField/index.mjs"; import { VForm } from "vuetify/lib/components/VForm/index.mjs"; import { VCheckbox } from "vuetify/lib/components/VCheckbox/index.mjs"; import { VCombobox } from "vuetify/lib/components/VCombobox/index.mjs"; import { VFileInput } from "vuetify/lib/components/VFileInput/index.mjs"; import { VLabel } from "vuetify/lib/components/VLabel/index.mjs"; import { VRadio } from "vuetify/lib/components/VRadio/index.mjs"; import { VRadioGroup } from "vuetify/lib/components/VRadioGroup/index.mjs"; import { VSelect } from "vuetify/lib/components/VSelect/index.mjs"; import { VSlider } from "vuetify/lib/components/VSlider/index.mjs"; import { VSwitch } from "vuetify/lib/components/VSwitch/index.mjs"; import { VTextarea } from "vuetify/lib/components/VTextarea/index.mjs"; import { VList, VListItem, VListItemTitle, VListItemSubtitle, VListSubheader } from "vuetify/lib/components/VList/index.mjs"; import { VMenu } from "vuetify/lib/components/VMenu/index.mjs"; import { VTabs, VTab } from "vuetify/lib/components/VTabs/index.mjs"; import { VToolbar, VToolbarTitle, VToolbarItems } from "vuetify/lib/components/VToolbar/index.mjs"; import { VImg } from "vuetify/lib/components/VImg/index.mjs"; import { VWindow, VWindowItem } from "vuetify/lib/components/VWindow/index.mjs"; import { VColorPicker } from "vuetify/lib/components/VColorPicker/index.mjs"; import { VSheet } from "vuetify/lib/components/VSheet/index.mjs"; import { VAppBarNavIcon, VAppBar } from "vuetify/lib/components/VAppBar/index.mjs"; import { VNavigationDrawer } from "vuetify/lib/components/VNavigationDrawer/index.mjs"; import { VTooltip } from "vuetify/lib/components/VTooltip/index.mjs"; import { VApp } from "vuetify/lib/components/VApp/index.mjs"; import { VMain } from "vuetify/lib/components/VMain/index.mjs"; import { useTheme } from "vuetify"; try { if (typeof global !== "undefined") { } else if (typeof self !== "undefined") { self.global = self; } else if (typeof window !== "undefined") { window.global = window; } else { let self2 = Function("return this")(); self2.global = self2; } } catch (e) { } function debug(profile2) { global.dump = (...args) => { let s = []; for (let item of args) { s.push( JSON.stringify( item, function(key2, value) { if (this[key2] instanceof Date) { return this[key2].toLocaleString(); } return value; }, 4 ) ); } print(s.join(" ")); }; global.print = (...args) => { console.log(...args); }; global.assert = (a) => { if (!a) { console.log(`Assertion failed`, new Error("Assertion"), { bug: true }); debugger; } }; } function allow(obj, ...mask) { let result = {}; if (!obj) { obj = {}; } if (mask.length == 1 && Array.isArray(mask[0])) { mask = mask[0]; } if (Array.isArray(mask)) { for (let field of mask) { if (obj[field] !== void 0) { result[field] = obj[field]; } } } else if (typeof mask == "string") { result[mask] = obj[mask]; } else { for (let field of Object.keys(mask)) { if (obj[field] !== void 0) { result[field] = obj[field]; } } } return result; } function deny(obj, ...mask) { let result; if (!obj) { obj = {}; } if (mask.length == 1 && Array.isArray(mask[0])) { mask = mask[0]; } if (Array.isArray(mask)) { result = Object.assign({}, obj); for (let key2 of mask) { delete result[key2]; } } else if (typeof mask == "string") { result = {}; for (let [key2, value] of Object.entries(obj)) { if (key2 != mask) { result[key2] = value; } } result[mask] = obj[mask]; } else { result = {}; for (let field of Object.keys(mask)) { if (obj[field] !== void 0) { result[field] = obj[field]; } } } return result; } function money(n, places = 2) { let factor = Math.pow(10, places); let number = +(Math.round(n * factor) / factor).toFixed(places); let fraction = number % 1; let fixed = Math.floor(number); fixed = fixed.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ","); if (fraction) { fraction = (Math.round(fraction * factor) / factor).toFixed(places).replace(/^0\./, "."); } else { fraction = ""; } return fixed + fraction; } function toTitle(word2) { return word2 ? word2[0].toUpperCase() + word2.slice(1) : ""; } function titlecase(str) { if (!str) { return str; } var words = str.toString().split(/[ \.]/g); for (let i = 0; i < words.length; i++) { words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1); } return words.join(" "); } function toMap(a, property2, indexed = false) { let result = {}; if (property2) { for (let i = 0; i < a.length; i++) { let item = a[i]; if (indexed) { result[item[property2]] = i; } else { result[item[property2]] = item; } } } else { for (let i = 0; i < a.length; i++) { let item = a[i]; result[item] = i; } } return result; } function unique(a) { return Array.from(new Set(a)); } class ChatClass { provide(provider) { this.provider = provider; } async init(config) { if (this.provider) { await this.provider.init(config); } } async open() { if (this.provider) { await this.provider.open(); } } async close() { if (this.provider) { await this.provider.close(); } } async identify() { if (this.provider) { await this.provider.identify(); } } async toggle() { if (this.provider) { await this.provider.toggle(); } } } const Chat = new ChatClass(); const RECURSE_LIMIT$2 = 50; function clone(src, recurse = 0) { let result; if (recurse > RECURSE_LIMIT$2) { throw new Error("Recursive clone"); } if (Array.isArray(src)) { result = []; for (let item of src) { result.push(clone(item, recurse + 1)); } } else if (typeof src == "object" && !(src instanceof Date || src instanceof RegExp || src == null)) { result = Object.create(Object.getPrototypeOf(src)); var i, descriptor, keys2 = Object.getOwnPropertyNames(src); for (i = 0; i < keys2.length; i++) { try { descriptor = Object.getOwnPropertyDescriptor(src, keys2[i]); if (descriptor.get) { let value = descriptor.get(); if (value === void 0) continue; if (value && typeof value === "object") { value = clone(value, recurse + 1); } descriptor = { value, configurable: descriptor.configurable, enumerable: descriptor.enumerable, writable: true }; } else if (descriptor.value && typeof descriptor.value === "object") { if (keys2[i] == "__observers__" || keys2[i] == "__ob__") { continue; } descriptor.value = clone(descriptor.value, recurse + 1); } Object.defineProperty(result, keys2[i], descriptor); } catch (e) { continue; } } } else { result = src; } return result; } const RECURSE_LIMIT$1 = 75; function combine(dest, src, options = "", recurse = 0) { if (recurse > RECURSE_LIMIT$1) { return; } if (!src) { return dest; } if (!dest || typeof dest != "object" || Array.isArray(dest)) { return dest; } for (let key2 of Object.getOwnPropertyNames(src)) { if (key2 == "__observers__" || key2 == "__ob__") { continue; } let property2 = key2; let op = key2[0]; if (op == "+") { property2 = key2.slice(1); } else if (op == "-") { property2 = key2.slice(1); } else if (op == "?") { property2 = key2.slice(1); } else if (op == "=") { property2 = key2.slice(1); } else if (options) { op = options; } else { op = ""; } let s = src[key2]; let d = dest[property2]; if (!dest.hasOwnProperty(property2)) { if (op == "-") { continue; } dest[property2] = clone(s); continue; } else if (op == "?" && d != null) { continue; } if (Array.isArray(d)) { if (op == "=") { dest[property2] = clone(s); } else if (op == "-") { if (Array.isArray(s)) { for (let item of s) { let index2 = d.indexOf(item); if (index2 >= 0) d.slice(index2, 1); } } else { let index2 = d.indexOf(s); if (index2 >= 0) d.slice(index2, 1); } } else if (op == "+") { if (Array.isArray(s)) { for (let item of s) { if (d.indexOf(s) < 0) d.push(item); } } else { d.push(s); } } else { dest[property2] = clone(s); } } else if (d instanceof Date) { if (op == "+") { dest[property2] += s; } else if (op == "-") { dest[property2] -= s; } else { dest[property2] = s; } } else if (typeof d == "object" && d !== null && d !== void 0) { if (op == "=") { dest[property2] = clone(s); } else if (op == "-") { delete dest[property2]; } else if (s === null) { dest[property2] = s; } else if (typeof s == "object") { combine(d, s, op, recurse + 1); } else { dest[property2] = s; } } else if (typeof d == "string") { if (op == "+") { dest[property2] += " " + s; } else if (op == "-") { if (d == s) { delete dest[property2]; } else { dest[property2] = d.replace(s, ""); } } else { dest[property2] = s; } } else if (typeof d == "number") { if (op == "+") { dest[property2] += s; } else if (op == "-") { dest[property2] -= s; } else { dest[property2] = s; } } else { if (op == "=") { dest[property2] = s; } else if (op == "-") { delete dest[property2]; } else { dest[property2] = s; } } } return dest; } function blend(dest, ...src) { if (!dest) { dest = {}; } for (let obj of src) { if (obj) { dest = combine(dest, obj); } } return dest; } function uuid() { return "xxxxxxxxxxxxxxxxyxxxxxxxxxyxxxxx".replace(/[xy]/g, function(c2) { var r = Math.random() * 16 | 0, v = c2 == "x" ? r : r & 3 | 8; return v.toString(16); }); } class Json { /* Reviver for JSON.parse(, reviver) */ static decode(key2, value) { if (typeof value == "string") { if (value.indexOf("{type:date}") == 0) { return new Date(value.slice(11)); } else if (value.indexOf("{type:regexp}") == 0) { return new Regexp(value.slice(13)); } } return value; } /* Prepare an object for encoding by JSON.stringify() */ static encode(obj, nest = 0) { let result; if (obj) { result = Array.isArray(obj) ? [] : {}; for (let [key2, value] of Object.entries(obj)) { if (value instanceof Date) { result[key2] = "{type:date}" + value.toUTCString(); } else if (value instanceof RegExp) { result[key2] = "{type:regexp}" + value.source; } else if (typeof value == "object") { if (nest < 20) { result[key2] = Json.encode(value, nest + 1); } else { result[key2] = value; } } else { result[key2] = value; } } } else { result = obj; } return result; } } function init(self2, code, message, context) { self2.code = `${code}Error`; self2.name = self2.constructor.name; self2.message = message; self2.context = context; if (context) { self2.context = context; if (context.status != null) { self2.status = context.status; } } self2.date = /* @__PURE__ */ new Date(); if (typeof Error.captureStackTrace === "function") { Error.captureStackTrace(self2, self2.constructor); } else { self2.stack = new Error(message).stack; } } class NetError extends Error { constructor(message, context) { super(message); init(this, "Validation", message, context); } } class LogClass { constructor() { this.logger = this.defaultLogger; } error(message, context) { this.process("error", message, context); } info(message, context) { this.process("info", message, context); } trace(message, context) { this.process("trace", message, context); } process(level, message, context) { if (level == "trace" || level == "data") { return; } if (context) { try { console.log(level, ":", message, JSON.stringify(context, null, 4)); } catch (err) { let buf = ["{"]; for (let [key2, value] of Object.entries(context)) { try { buf.push(` ${key2}: ${JSON.stringify(value, null, 4)}`); } catch (err2) { } } buf.push("}"); console.log(level, ":", message, buf.join("\n")); } } else { console.log(level, ":", message); } } } const Log = new LogClass(); const LazyDelay = 3e3; const State$1 = {}; class StoreClass { constructor() { __publicField(this, "modules", {}); } init(options = {}) { var _a; this.options = options; this.persist = `${options.config.name}-state`; this.lazy = options.lazy !== false; this.initialState = {}; if (((_a = options.config) == null ? void 0 : _a.profile) != "prod" || window.location.hostname == "localhost") { global.State = State$1; } } /* async reload(accountId) { let options = this.options options.persist = `${options.config.name}-${accountId}-state` for (let key of Object.keys(State)) { delete State[key] } this.initialState = this.loadState() } */ /* Load all persisted state from browser local storage or options loader */ loadState(persist) { this.persist = persist; let options = this.options; let data2; if (options.reset) { this.reset(); } else { if (options.loader) { data2 = options.loader(options); } else { data2 = localStorage[this.persist]; if (data2) { data2 = JSON.parse(data2); } } } data2 = data2 || {}; if (options.verbose) { dump("Initial state", data2); } for (let name2 of Object.keys(this.modules)) { this.blendModuleState(name2, data2[name2]); } } /* Blend and filter initial state for a module. Blends with module inline state. */ blendModuleState(name2, data2) { let module = this.modules[name2]; if (module.saveState === false || module.loadState === false) { data2 = {}; } else if (typeof module.loadState == "function") { data2 = module.loadState.call(module, data2); } blend(module, data2); } addMethods(methods) { blend(State$1, methods); } add(name2, module, options = {}) { if (this.modules[name2]) { return; } this.modules[name2] = module; if (options.reactive === false) { module.saveState = false; State$1[name2] = module; } else { State$1[name2] = reactive(module); watch( State$1[name2], () => { this.saveState(name2); }, { deep: true } ); } } /* Log mutations and other activities */ log(verb, module, name2, v) { if (this.options.log) { if (verb == "Invoke") { Log.info(`Invoke: ${module}.${name2}`); } else { Log.info(`${verb}: ${module}.${name2} = ${v}`); if (this.options.verbose) { let at = new Error(); let stack2 = at.stack.replace(/^Error/, ""); Log.info("From: " + stack2); } } } } // Save all state. Do a lazy save by default. async saveState(module) { if (this.persist) { if (this.lazy) { if (!this.saveTimeout) { this.saveTimeout = setTimeout(async () => { await this.save(); this.saveTimeout = null; }, LazyDelay); } } else { this.save(); } } } async save() { let state2 = {}; for (let [name2, module] of Object.entries(this.modules)) { if (module.saveState === false) { state2[name2] = {}; continue; } state2[name2] = Object.assign({}, State$1[name2]); if (typeof module.saveState == "function") { state2[name2] = await module.saveState.call(module, state2[name2]); } } if (this.options.verbose) { dump("Saving state", state2); } try { localStorage[this.persist] = JSON.stringify(state2); } catch (err) { Log.error(`Cannot save to local storage`, { err }); } } async reset() { try { for (let key2 of Object.keys(State$1)) { delete State$1[key2]; } await this.save(); } catch (err) { Log.error(`Cannot reset local storage`, { err }); } } } const Store = new StoreClass(); const _export_sfc$1 = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key2, val] of props) { target[key2] = val; } return target; }; class FeedbackClass { constructor() { __publicField(this, "page", reactive({ active: null, dialog: null, message: null, severity: null, severityStyle: null })); this.page.dialog = true; } away() { this.clear(); return true; } clear() { let page = this.page; page.message = ""; page.severity = "info"; page.severityStyle = ""; page.active = false; } error(msg, context) { this.init("error", msg); } init(sev, msg) { setTimeout(() => { let page = this.page; page.severity = sev; page.severityStyle = `feedback-common feedback-${sev}`; page.message = msg; { page.active = true; } }, 1); } info(msg) { this.init("info", msg); } response(response, message) { if (response) { if (typeof message == "object" && message.message) { message = message.message; } this.init(response.status == 200 ? "info" : "error", message); } } warn(msg) { this.init("warn", msg); } } const Feedback = new FeedbackClass(); const _sfc_main$1i = { __name: "VuFeedback", setup(__props, { expose: __expose }) { __expose(); const page = Feedback.page; onMounted(() => { document.body.addEventListener("click", Feedback.away.bind(Feedback)); }); onUnmounted(() => { document.body.removeEventListener("click", Feedback.away.bind(Feedback)); }); const __returned__ = { FeedbackClass, Feedback, page, get State() { return State$1; }, onMounted, onUnmounted, reactive }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }; const _hoisted_1$Z = { class: "feedback" }; const _hoisted_2$v = { key: 1, class: "feedback-nav" }; function _sfc_render$1i(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("div", _hoisted_1$Z, [ $setup.page.dialog ? (openBlock(), createBlock(VDialog, { key: 0, modelValue: $setup.page.active, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.page.active = $event), location: "bottom", "content-class": "feedback-dialog", __opacity: 0, scrim: false }, { default: withCtx(() => [ createVNode(VAlert, { class: "vrow", type: $setup.page.severity }, { default: withCtx(() => [ createTextVNode(toDisplayString($setup.page.message), 1) ]), _: 1 }, 8, ["type"]) ]), _: 1 }, 8, ["modelValue"])) : (openBlock(), createElementBlock("div", _hoisted_2$v, [ createElementVNode("span", { class: normalizeClass($setup.page.severityStyle) }, toDisplayString($setup.page.message), 3) ])) ]); } const VuFeedback = /* @__PURE__ */ _export_sfc$1(_sfc_main$1i, [["render", _sfc_render$1i], ["__file", "VuFeedback.vue"]]); const Durations = { short: 3e3, medium: 5e3, long: 1e4, vlong: 3e4 }; const NapTime = 250; class ProgressClass { constructor() { __publicField(this, "page", reactive({ active: false, bar: false, cancel: false, classes: "", dialog: null, duration: Durations.short, hint: "Please wait...", inc: 0, percent: 1, progress: 0, ready: true, repeat: false, seq: 0, started: /* @__PURE__ */ new Date(), styling: { width: null, transition: null }, title: null, value: 0 })); } clear() { let page = this.page; page.value = 0; page.active = false; page.styling = {}; page.classes = ""; page.seq++; } start(duration, message, options = {}) { let page = this.page; page.started = /* @__PURE__ */ new Date(); page.title = message; page.hint = options.hint || "Please wait..."; page.bar = options.bar; page.cancel = options.cancel; if (duration === false) { return; } else if (typeof duration == "number") { duration *= 1e3; } else if (duration == "repeat") { duration = options.duration || Durations.short; page.repeat = true; } else if (duration == "dialog") { duration = options.duration || Durations.short; page.repeat = true; page.dialog = true; } else if (typeof duration != "number") { duration = Durations[duration || "short"]; if (!duration) { duration = Durations.short; } } if (duration < NapTime || duration > 9999999999) { duration = Durations.short; } page.active = true; page.value = 0; page.duration = duration; page.inc = duration / NapTime; page.classes = page.classes.replace(/fade/g, ""); page.seq++; } stop(msg) { let page = this.page; page.dialog = null; page.repeat = false; page.classes += " fade"; page.value = 100; page.active = false; page.started = null; page.message = null; page.seq++; if (msg) { if (typeof msg == "string") { Feedback.info(msg); } else if (msg.info) { Feedback.info(msg); } else if (msg.error) { Feedback.error(msg); } } } message(message, hint = "") { let page = this.page; page.title = message; page.hint = hint || page.hint; page.seq++; } async cancel() { let page = this.page; if (typeof page.cancel == "function") { await page.cancel(); } this.stop(); } } const Progress = new ProgressClass(); const _sfc_main$1h = { __name: "VuProgress", setup(__props, { expose: __expose }) { __expose(); const page = Progress.page; watch(() => page.seq, update, { deep: true }); async function update() { do { while (page.active && page.value <= 100) { setWidth(page.value); if (page.bar) { page.percent = ((Date.now() - page.started.getTime()) / page.duration * 100).toFixed(0); if (page.percent == 0) { page.percent = 1; } else if (page.percent > 100) { page.percent = 100; } } await delay2(NapTime); page.value = page.value + 100 / page.inc; } await delay2(NapTime); page.value = 0; setWidth(0); } while (page.repeat); page.classes += " fade"; page.active = false; } function setWidth(width) { page.classes = page.classes.replace(" fade", ""); if (width > 100) { width = 100; } if (width > 0) { page.styling.transition = "width 1s linear 0s"; page.styling.width = `${width}%`; } else { page.styling.transition = "none"; page.styling.width = "0%"; } } function outside(v) { return false; } async function delay2(time) { return new Promise(function(resolve, reject) { setTimeout(() => resolve(true), time); }); } const __returned__ = { Durations, NapTime, ProgressClass, Progress, page, update, setWidth, outside, delay: delay2, get Feedback() { return Feedback; }, reactive, watch }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }; const _hoisted_1$Y = { class: "progress" }; const _hoisted_2$u = { class: "hint" }; function _sfc_render$1h(_ctx, _cache, $props, $setup, $data, $options) { return withDirectives((openBlock(), createElementBlock("div", _hoisted_1$Y, [ createElementVNode("div", { class: normalizeClass(["progress-bar", $setup.page.classes]), style: normalizeStyle($setup.page.styling) }, null, 6), createVNode(VDialog, { modelValue: $setup.page.dialog, "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.page.dialog = $event), persistent: "", width: "500", "content-class": "progress-dialog", "onClick:outside": withModifiers($setup.outside, ["stop", "prevent"]) }, { default: withCtx(() => [ createVNode(VCard, null, { default: withCtx(() => [ createVNode(VCardTitle, { class: "headline", "_primary-title": "" }, { default: withCtx(() => [ createTextVNode(toDisplayString($setup.page.title), 1) ]), _: 1 }), createVNode(VCardText, null, { default: withCtx(() => [ $setup.page.bar ? (openBlock(), createBlock(VProgressLinear, { key: 0, modelValue: $setup.page.percent, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.page.percent = $event), height: "20", color: "accent" }, null, 8, ["modelValue"])) : (openBlock(), createBlock(VProgressCircular, { key: 1, size: 100, width: 6, indeterminate: "", color: "teal" })), createElementVNode("p", _hoisted_2$u, toDisplayString($setup.page.hint), 1), $setup.page.cancel ? (openBlock(), createBlock(VBtn, { key: 2, onClick: _cache[1] || (_cache[1] = ($event) => $setup.Progress.cancel()), class: "mt-4 pa-4 cancel" }, { default: withCtx(() => _cache[3] || (_cache[3] = [ createTextVNode("Cancel") ])), _: 1 })) : createCommentVNode("", true) ]), _: 1 }) ]), _: 1 }) ]), _: 1 }, 8, ["modelValue"]) ], 512)), [ [vShow, $setup.page.ready] ]); } const VuProgress = /* @__PURE__ */ _export_sfc$1(_sfc_main$1h, [["render", _sfc_render$1h], ["__file", "VuProgress.vue"]]); class Net { static setConfig(config, notify) { Net.config = config || {}; this.notify = notify || netCallback; } async fetch(url, options = {}) { var _a; this.config = Object.assign({ timeouts: { http: 30 }, api: "" }, Net.config); this.notify = this.notify || Net.notify; if (options.clear) { await this.callback("clear"); } if (!url.startsWith("http")) { let api = options.api || options.base || this.config.api || ""; if (api.indexOf("http") == 0) { url = api + url; } else { url = location.origin + api + url; } } if (options.progress) { await this.callback("start"); } if (options.log) { Log.trace("Fetch Request", { level: 0, options }); } let state2 = { url, timeout: null }; let response = await Promise.race([ this.fetchRetry(state2, options), this.timeout(state2, ((_a = this.config.timeouts) == null ? void 0 : _a.http) * 1e3) ]); clearTimeout(state2.timeoutHandle); return this.parseResponse(url, options, response); } /* Issue a request with retries */ async fetchRetry(state2, options = {}) { let url = state2.url; let args = Object.assign({}, options); if (!args.method) { args.method = "POST"; } let retries = options.retries || 0; args.mode = args.mode || "cors"; args.credentials = args.credentials === false ? void 0 : args.credentials || "include"; let response; let retry = 0; do { try { response = await fetch(url, args); if (!response) { throw new Error("No response"); } break; } catch (err) { if (state2.timeout) { return; } if (retries <= 0) { break; } Log.info(`Request ${url} failed, retry ${retry} ${err.message}`, { err }); } retry++; } while (--retries > 0); return response; } async parseResponse(url, options, response) { let body, status; if (response) { status = response.status; if (options.stream) { body = response.body.getReader(); } else if (options.blob) { body = await response.blob(); } else if (response.text) { body = await response.text(); let contentType; if (response.headers && response.headers.get) { contentType = response.headers.get("Content-Type"); } if (!body) { body = null; } else if (body && contentType && !options.noparse && (contentType.indexOf("application/json") == 0 || contentType.indexOf("application/x-amz-json-1.0") == 0)) { try { body = JSON.parse(body, Json.decode); } catch (err) { Log.error(`Cannot parse json response`, { body }); } } } } else { status = 445; } if (status != 200 && status != 204) { if (status == 401 && options.nologout !== true) { await this.callback("logout"); return null; } if (options.feedback !== false) { response = response || { status }; body = body || "Network Connection Error"; await this.callback("feedback", response, body); } } if (options.progress) { await this.callback("stop"); } if (options.log) { Log.trace("Fetch Response", { status, body }); } await this.callback("response", response, body); if (status != 200 && status != 204 && options.throw !== false) { if (typeof body == "object" && body.message) { body = body.message; } throw new NetError(body || "Cannot complete operation"); } return status == 200 ? body : null; } async get(url, options = {}) { options = Object.assign({}, options); options.method = "GET"; return await this.fetch(url, options); } async post(url, options = {}) { options.method = "POST"; return await this.fetch(url, options); } async callback(reason, args, data2) { if (this.notify) { try { await this.notify(reason, args, data2); } catch (e) { print(e); } } } /* Fetch timeouts. The fetch API does not implement timeouts or cancel (Ugh!) */ timeout(state2, delay2) { return new Promise(function(resolve, reject) { state2.timeoutHandle = setTimeout(function() { state2.timeout = true; resolve({ body: "Request timed out, please retry", status: 444 }); }, delay2); }); } } async function netCallback(reason, response, data2) { if (reason == "response" && response && response.headers) { let version2 = response.headers.get("X-Upgrade"); if (version2) { let sem = new SemVer(); if (sem.getVer(version2) > sem.getVer(State$1.config.version)) { if (!State$1.app.upgrading && State$1.app.upgradeAttempt <= 3) { State$1.app.upgradeAttempt = State$1.app.upgradeAttempt + 1; Store.save(); window.location.replace(`${window.location.href}?upgrading`); } } } else if (State$1.app.upgradeAttempt > 0) { State$1.app.upgradeAttempt = 0; } } else if (reason == "clear") { Feedback.clear(); } else if (reason == "feedback") { Feedback.response(response, data2); } else if (reason == "login" || reason == "logout") { State$1.ref.router.push({ path: "/login" }).catch(() => { }); } else if (reason == "start") { Progress.start(); } else if (reason == "stop") { Progress.stop(); } } const RECURSE_LIMIT = 50; class Task { constructor(roles2) { this.roles = roles2; } /* Can this role do the given task. Tasks may be a task string or may be other tasks/roles that contain other roles[] */ can(role, task) { if (task == null || role == task) { return true; } if (role == null) { role = "public"; } return this.canDo(this.roles[role], task); } canDo(tasks, task, depth = 0) { if (!tasks) { return false; } if (depth > RECURSE_LIMIT) { console.error(`Recursion depth exceeded`, { roles: this.roles, task }); return false; } for (let t of tasks) { if (t == task) { return true; } if (this.roles[t] && this.canDo(this.roles[t], task, depth + 1)) { return true; } } return false; } } const SessionDuration = 60 * 60 * 1e3; let User$1; class AuthClass { constructor() { __publicField(this, "app", null); __publicField(this, "cognito", null); __publicField(this, "cognitoConfig", null); __publicField(this, "monitoring", null); __publicField(this, "task", null); } init(app, config, { cognito, account, user }) { this.app = app; this.config = config; User$1 = user; if (config && cognito) { this.cognito = new cognito(config); } this.cognitoConfig = config; this.monitoring = false; this.task = new Task(State$1.config.roles); } async checkSession() { let cognito = this.cognito; let auth = null; if (!State$1.app.isSocial) { try { if (cognito) { auth = await cognito.checkLoggedIn(); if (auth) { State$1.auth.setAuthState(auth, cognito.tokens); } } else { auth = await User$1.checkSession(null, { nologout: true }); if (auth) { State$1.auth.setAuthState(auth, null); } } } catch (err) { } } return auth; } /* Authenticate the user's credentials. If already logged in, this will use the existing login session. If the authentication is successful, the AuthState is updated with the auth and tokens. Also returns the auth. */ async authenticate(params, options = { throw: false }) { let auth = State$1.auth.auth; let cognito = this.cognito; params = clone(params); try { if (State$1.app.isSocial) { params = { social: State$1.app.location.search }; } else if (params) { params.username = params.username || params.email; } if (auth && (params && auth.email != params.email || State$1.auth.getInvite() || State$1.app.isSocial)) { if (cognito) { await cognito.logout(); } else { await User$1.logout(); } State$1.auth.clearAuth(); auth = null; } if (!auth && params) { if (cognito) { auth = await cognito.login(params); } else { delete params.email; auth = await User$1.authenticate(params); } } } catch (err) { if (err.message == "Please Define Password") { throw err; } if (err.message == "Network error") { throw err; } if (options.throw !== false) { throw err; } } if (auth) { State$1.auth.setAuthState(auth, cognito ? cognito.tokens : null); State$1.app.setActivity(); } return auth; } /* Login the user. Call only after being authenticated. Will throw an exception if the login fails for any reason. */ async login(params = {}) { var _a; if (this.cognito && !State$1.auth.authenticated) { throw new Error("User is not authenticated"); } params = Object.assign({}, { invite: State$1.auth.getInvite() }, params); let data2 = await User$1.login(params, { log: false, feedback: false, nologout: true }); if (data2) { let id = ((_a = data2.account) == null ? void 0 : _a.id) || this.id; await Store.loadState(`${State$1.config.name}-${id}-state`); this.monitorSession(); await this.setLoginState(data2); State$1.auth.setInvite(null); } } /* After login, cache data and define the user role */ async setLoginState({ account, cache, keys: keys2, manager: manager2, schema, user, versions }) { if (account) { State$1.auth.setAccount(account); } if (manager2) { State$1.app.setManager(manager2); } if (user) { State$1.auth.setUser(user); } if (versions) { State$1.app.setVersions(versions); } if (schema) { State$1.app.setSchema(schema); } State$1.auth.setAuthorized(true); await State$1.cache.update({ cache, authorized: true, keys: keys2 }); State$1.auth.setReady(true); State$1.app.setNeed("board", "reload"); if (State$1.ref.chat) { State$1.ref.chat.identify(); } } /* Logout the user and navigate the app to the login form */ async logout(options = {}) { if (this.cognito) { await this.cognito.logout(); if (options.redirect && State$1.app.isSocial) { if (State$1.auth.auth.username.indexOf("Google") >= 0) { let net = new Net(); await net.fetch("https://accounts.google.com/logout", { feedback: false, throw: false, log: false }); } let url = this.cognito.socialLogoutUrl(); if (url) { State$1.auth.clearAuth(); Store.save(); window.open(url, "_self"); return; } } } else { await User$1.logout(); } State$1.auth.clearAuth(); this.monitoring = false; } async forgot(username) { if (this.cognito) { if (username) { username = username.toLowerCase(); } await this.cognito.forgot(username); } } async forgotConfirmation(username, password, code) { if (username) { username = username.toLowerCase(); } await this.cognito.forgotConfirmation(username, password, code); } /* Register a user with cognito */ async registerUser(params) { if (this.cognito) { await this.cognito.register(params); } } /* Check the user registration confirmation code. Throws on failure. */ async registerUserConfirmation(params, code) { if (this.cognito) { await this.cognito.registerConfirmation(params.username, code); await this.authenticate(params, { throw: true }); } } async sendCode(username) { if (this.cognito) { await this.cognito.resend(username); } } async setUser(username, details) { if (this.cognito) { await this.cognito.update(username, details); } } async changePassword(oldPassword, newPassword) { if (this.cognito) { return await this.cognito.changePassword(oldPassword, newPassword); } } async removeUser() { if (this.id && this.cognito) { Log.info(`Delete user ${this.email}`); await this.cognito.deleteUser(this.user.id); } } async monitorSession() { State$1.app.setActivity(); if (this.monitoring) return; this.monitoring = true; while (this.monitoring) { if (State$1.auth.authenticated) { let timeout = State$1.config.timeouts.session * 1e3; let elapsed = Date.now() - State$1.app.lastAccess; let remaining = timeout - elapsed; if (remaining < 0) { await this.logout({ redirect: true }); State$1.ref.router.push({ path: "/login" }).catch(() => { }); } else if (this.cognito) { Log.trace(`Session remaining: ${((timeout - elapsed) / 1e3 / 60).toFixed(0)} mins`); let cognitoElapsed = Date.now() - State$1.auth.tokensRefreshed; Log.trace(`Session elapsed: ${(cognitoElapsed / 1e3 / 60).toFixed(2)} mins`); if (cognitoElapsed > SessionDuration / 3) { State$1.auth.tokens = await this.cognito.refresh(); if (State$1.auth.tokens) { State$1.auth.tokensRefreshed = /* @__PURE__ */ new Date(); State$1.auth.setAuthState(State$1.auth, State$1.auth.tokens); } } } } await new Promise((resolve) => setTimeout(resolve, 60 * 1e3)); } this.monitoring = false; } parseUri() { let loc = window.location; let path = loc.pathname; if (path != "/") { loc.href = `${loc.origin}/#${path}${loc.search}`; return; } let [hash2, search] = loc.hash.split("?"); let location2 = State$1.app.location; location2.hash = hash2; location2.url = hash2 ? hash2.slice(1) : path; location2.search = search ? `?${search}` : null; let vars = []; if (loc.search) { vars.push(...loc.search.substring(1).split("&")); } if (search) { vars.push(...search.split("&")); } let query2 = {}; if (vars.length) { for (let i = 0; i < vars.length; i++) { let [key2, value] = vars[i].split("="); key2 = decodeURIComponent(key2); value = decodeURIComponent(value || true); query2[key2] = value; if (key2 == "url") { location2.url = value; } } } location2.query = query2; if (query2.upgrading) { State$1.app.upgrading = true; } let features2 = query2["features"]; if (features2) { for (let feature of features2.split(",")) { let [name2, value] = feature.split(":"); let obj = State$1.config.features; let parts = name2.split("."); for (let [index2, thisKey] of Object.entries(parts)) { if (index2 == parts.length - 1) { obj[thisKey] = value === void 0 ? true : value; } else { obj = obj[thisKey]; } } } } } /* Redirect after authentication This will redirect to an original url fragment and will restore original query paramemters */ redirect() { let { query: query2, url } = State$1.app.location; let target = url || "/"; if (target.indexOf("/auth") == 0 || target.indexOf("/login") == 0) { target = "/"; } let path = window.location.pathname + window.location.hash.replace(/^#\//, ""); if (target != path) { if (query2) { delete query2.code; if (query2.invite === null) { delete query2.invite; } delete query2.url; } if (target == "/login" || target == "/login/social") { target = "/"; } this.app.router.push({ path: target, query: query2 }, () => { }); } } can(role) { return this.task.can(State$1.auth.role, role); } canUser(user, role) { return this.task.can(user.role, role); } } const Auth = new AuthClass(); var mdiAccount = "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"; var mdiAlert = "M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z"; var mdiAlertCircleOutline = "M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z"; var mdiApps = "M16,20H20V16H16M16,14H20V10H16M10,8H14V4H10M16,8H20V4H16M10,14H14V10H10M4,14H8V10H4M4,20H8V16H4M10,20H14V16H10M4,8H8V4H4V8Z"; var mdiArrowCollapse = "M19.5,3.09L15,7.59V4H13V11H20V9H16.41L20.91,4.5L19.5,3.09M4,13V15H7.59L3.09,19.5L4.5,20.91L9,16.41V20H11V13H4Z"; var mdiArrowExpandHorizontal = "M9,11H15V8L19,12L15,16V13H9V16L5,12L9,8V11M2,20V4H4V20H2M20,20V4H22V20H20Z"; var mdiArrowLeftBold = "M20,9V15H12V19.84L4.16,12L12,4.16V9H20Z"; var mdiArrowRightBold = "M4,15V9H12V4.16L19.84,12L12,19.84V15H4Z"; var mdiAutoFix = "M7.5,5.6L5,7L6.4,4.5L5,2L7.5,3.4L10,2L8.6,4.5L10,7L7.5,5.6M19.5,15.4L22,14L20.6,16.5L22,19L19.5,17.6L17,19L18.4,16.5L17,14L19.5,15.4M22,2L20.6,4.5L22,7L19.5,5.6L17,7L18.4,4.5L17,2L19.5,3.4L22,2M13.34,12.78L15.78,10.34L13.66,8.22L11.22,10.66L13.34,12.78M14.37,7.29L16.71,9.63C17.1,10 17.1,10.65 16.71,11.04L5.04,22.71C4.65,23.1 4,23.1 3.63,22.71L1.29,20.37C0.9,20 0.9,19.35 1.29,18.96L12.96,7.29C13.35,6.9 14,6.9 14.37,7.29Z"; var mdiAws = "M7.64,10.38C7.64,10.63 7.66,10.83 7.71,11C7.76,11.12 7.83,11.28 7.92,11.46C7.96,11.5 7.97,11.56 7.97,11.61C7.97,11.68 7.93,11.74 7.84,11.81L7.42,12.09C7.36,12.13 7.3,12.15 7.25,12.15C7.18,12.15 7.12,12.11 7.05,12.05C6.96,11.95 6.88,11.85 6.81,11.74C6.75,11.63 6.68,11.5 6.61,11.35C6.09,11.96 5.44,12.27 4.65,12.27C4.09,12.27 3.65,12.11 3.32,11.79C3,11.47 2.83,11.04 2.83,10.5C2.83,9.95 3.03,9.5 3.43,9.14C3.84,8.8 4.38,8.62 5.06,8.62C5.29,8.62 5.5,8.64 5.77,8.68C6,8.71 6.27,8.76 6.53,8.82V8.34C6.53,7.83 6.43,7.5 6.22,7.27C6,7.06 5.65,6.97 5.14,6.97C4.9,6.97 4.66,7 4.42,7.05C4.17,7.11 3.93,7.18 3.7,7.28C3.59,7.32 3.5,7.35 3.47,7.36C3.42,7.38 3.39,7.38 3.36,7.38C3.27,7.38 3.22,7.32 3.22,7.18V6.85C3.22,6.75 3.23,6.67 3.27,6.62C3.3,6.57 3.36,6.53 3.45,6.5C3.69,6.36 3.96,6.26 4.29,6.18C4.62,6.09 4.96,6.05 5.33,6.05C6.12,6.05 6.7,6.23 7.07,6.59C7.44,6.95 7.62,7.5 7.62,8.23V10.38H7.64M4.94,11.4C5.16,11.4 5.38,11.36 5.62,11.28C5.86,11.2 6.07,11.05 6.25,10.85C6.36,10.72 6.44,10.58 6.5,10.42C6.5,10.26 6.55,10.07 6.55,9.84V9.57C6.35,9.5 6.15,9.5 5.93,9.45C5.72,9.43 5.5,9.41 5.31,9.41C4.86,9.41 4.54,9.5 4.32,9.68C4.1,9.86 4,10.11 4,10.44C4,10.76 4.07,11 4.24,11.15C4.4,11.32 4.63,11.4 4.94,11.4M10.28,12.11C10.16,12.11 10.08,12.09 10,12.05C9.97,12 9.92,11.91 9.88,11.79L8.32,6.65C8.28,6.5 8.26,6.43 8.26,6.38C8.26,6.27 8.31,6.21 8.42,6.21H9.07C9.2,6.21 9.29,6.23 9.33,6.28C9.39,6.32 9.43,6.41 9.47,6.54L10.58,10.94L11.62,6.54C11.65,6.41 11.69,6.32 11.75,6.28C11.8,6.24 11.89,6.21 12,6.21H12.55C12.67,6.21 12.76,6.23 12.81,6.28C12.86,6.32 12.91,6.41 12.94,6.54L14,11L15.14,6.54C15.18,6.41 15.23,6.32 15.27,6.28C15.33,6.24 15.41,6.21 15.53,6.21H16.15C16.26,6.21 16.32,6.27 16.32,6.38C16.32,6.41 16.31,6.45 16.3,6.5C16.3,6.5 16.28,6.58 16.26,6.65L14.65,11.79C14.61,11.93 14.57,12 14.5,12.05C14.46,12.09 14.37,12.12 14.26,12.12H13.69C13.56,12.12 13.5,12.1 13.42,12.05C13.37,12 13.32,11.92 13.3,11.79L12.27,7.5L11.24,11.78C11.21,11.91 11.17,12 11.12,12.05C11.06,12.09 10.97,12.11 10.85,12.11H10.28M18.83,12.29C18.5,12.29 18.13,12.25 17.8,12.17C17.47,12.09 17.21,12 17.04,11.91C16.93,11.85 16.86,11.78 16.83,11.72C16.8,11.66 16.79,11.6 16.79,11.54V11.2C16.79,11.06 16.84,11 16.94,11C17,11 17,11 17.06,11C17.1,11 17.16,11.05 17.23,11.08C17.45,11.18 17.7,11.26 17.96,11.31C18.23,11.36 18.5,11.39 18.75,11.39C19.17,11.39 19.5,11.32 19.72,11.17C19.95,11 20.07,10.81 20.07,10.54C20.07,10.35 20,10.2 19.89,10.07C19.77,9.95 19.54,9.83 19.22,9.73L18.25,9.43C17.77,9.27 17.41,9.05 17.19,8.75C16.97,8.46 16.86,8.13 16.86,7.78C16.86,7.5 16.92,7.26 17.04,7.05C17.16,6.83 17.32,6.65 17.5,6.5C17.72,6.35 17.94,6.24 18.21,6.16C18.47,6.08 18.75,6.04 19.05,6.04C19.19,6.04 19.34,6.05 19.5,6.07C19.64,6.09 19.78,6.12 19.92,6.14C20.06,6.18 20.18,6.21 20.3,6.25C20.42,6.29 20.5,6.33 20.58,6.37C20.67,6.42 20.74,6.47 20.78,6.53C20.82,6.59 20.84,6.66 20.84,6.75V7.07C20.84,7.21 20.79,7.28 20.69,7.28C20.64,7.28 20.55,7.25 20.43,7.2C20.06,7.03 19.63,6.94 19.16,6.94C18.78,6.94 18.5,7 18.27,7.13C18.07,7.25 17.96,7.45