quasar
Version:
Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
2,147 lines (1,801 loc) • 1.05 MB
JavaScript
/*!
* Quasar Framework v2.11.9
* (c) 2015-present Razvan Stoenescu
* Released under the MIT License.
*/
import { ref, reactive, createApp, markRaw, defineComponent, getCurrentInstance, computed, onMounted, onBeforeUnmount, h, withDirectives, unref, Transition, nextTick, watch, onUnmounted, Teleport, onDeactivated, KeepAlive, onBeforeMount, toRaw, provide, onActivated, inject, onBeforeUpdate, shallowReactive, vShow, onUpdated, isRef, TransitionGroup } from 'vue';
function injectProp (target, propName, get, set) {
Object.defineProperty(target, propName, {
get,
set,
enumerable: true
});
return target
}
function injectMultipleProps (target, props) {
for (const key in props) {
injectProp(target, key, props[ key ]);
}
return target
}
/* eslint-disable no-useless-escape */
/**
* __ QUASAR_SSR __ -> runs on SSR on client or server
* __ QUASAR_SSR_SERVER __ -> runs on SSR on server
* __ QUASAR_SSR_CLIENT __ -> runs on SSR on client
* __ QUASAR_SSR_PWA __ -> built with SSR+PWA; may run on SSR on client or on PWA client
* (needs runtime detection)
*/
const isRuntimeSsrPreHydration = ref(
__QUASAR_SSR_CLIENT__ && (
__QUASAR_SSR_PWA__ ? document.body.getAttribute('data-server-rendered') !== null : true
)
);
let iosCorrection;
function getMatch (userAgent, platformMatch) {
const match = /(edg|edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
|| /(opr)[\/]([\w.]+)/.exec(userAgent)
|| /(vivaldi)[\/]([\w.]+)/.exec(userAgent)
|| /(chrome|crios)[\/]([\w.]+)/.exec(userAgent)
|| /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
|| /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
|| /(firefox|fxios)[\/]([\w.]+)/.exec(userAgent)
|| /(webkit)[\/]([\w.]+)/.exec(userAgent)
|| /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent)
|| [];
return {
browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || '',
version: match[ 2 ] || match[ 4 ] || '0',
versionNumber: match[ 4 ] || match[ 2 ] || '0',
platform: platformMatch[ 0 ] || ''
}
}
function getPlatformMatch (userAgent) {
return /(ipad)/.exec(userAgent)
|| /(ipod)/.exec(userAgent)
|| /(windows phone)/.exec(userAgent)
|| /(iphone)/.exec(userAgent)
|| /(kindle)/.exec(userAgent)
|| /(silk)/.exec(userAgent)
|| /(android)/.exec(userAgent)
|| /(win)/.exec(userAgent)
|| /(mac)/.exec(userAgent)
|| /(linux)/.exec(userAgent)
|| /(cros)/.exec(userAgent)
// TODO: Remove BlackBerry detection. BlackBerry OS, BlackBerry 10, and BlackBerry PlayBook OS
// is officially dead as of January 4, 2022 (https://www.blackberry.com/us/en/support/devices/end-of-life)
|| /(playbook)/.exec(userAgent)
|| /(bb)/.exec(userAgent)
|| /(blackberry)/.exec(userAgent)
|| []
}
const hasTouch = 'ontouchstart' in window || window.navigator.maxTouchPoints > 0;
function applyIosCorrection (is) {
iosCorrection = { is: { ...is } };
delete is.mac;
delete is.desktop;
const platform = Math.min(window.innerHeight, window.innerWidth) > 414
? 'ipad'
: 'iphone';
Object.assign(is, {
mobile: true,
ios: true,
platform,
[ platform ]: true
});
}
function getPlatform (UA) {
const
userAgent = UA.toLowerCase(),
platformMatch = getPlatformMatch(userAgent),
matched = getMatch(userAgent, platformMatch),
browser = {};
if (matched.browser) {
browser[ matched.browser ] = true;
browser.version = matched.version;
browser.versionNumber = parseInt(matched.versionNumber, 10);
}
if (matched.platform) {
browser[ matched.platform ] = true;
}
const knownMobiles = browser.android
|| browser.ios
|| browser.bb
|| browser.blackberry
|| browser.ipad
|| browser.iphone
|| browser.ipod
|| browser.kindle
|| browser.playbook
|| browser.silk
|| browser[ 'windows phone' ];
// These are all considered mobile platforms, meaning they run a mobile browser
if (knownMobiles === true || userAgent.indexOf('mobile') > -1) {
browser.mobile = true;
if (browser.edga || browser.edgios) {
browser.edge = true;
matched.browser = 'edge';
}
else if (browser.crios) {
browser.chrome = true;
matched.browser = 'chrome';
}
else if (browser.fxios) {
browser.firefox = true;
matched.browser = 'firefox';
}
}
// If it's not mobile we should consider it's desktop platform, meaning it runs a desktop browser
// It's a workaround for anonymized user agents
// (browser.cros || browser.mac || browser.linux || browser.win)
else {
browser.desktop = true;
}
// Set iOS if on iPod, iPad or iPhone
if (browser.ipod || browser.ipad || browser.iphone) {
browser.ios = true;
}
if (browser[ 'windows phone' ]) {
browser.winphone = true;
delete browser[ 'windows phone' ];
}
// TODO: The assumption about WebKit based browsers below is not completely accurate.
// Google released Blink(a fork of WebKit) engine on April 3, 2013, which is really different than WebKit today.
// Today, one might want to check for WebKit to deal with its bugs, which is used on all browsers on iOS, and Safari browser on all platforms.
// Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
if (
browser.chrome
|| browser.opr
|| browser.safari
|| browser.vivaldi
// we expect unknown, non iOS mobile browsers to be webkit based
|| (
browser.mobile === true
&& browser.ios !== true
&& knownMobiles !== true
)
) {
browser.webkit = true;
}
// TODO: (Qv3) rename the terms 'edge' to 'edge legacy'(or remove it) then 'edge chromium' to 'edge' to match with the known up-to-date terms
// Microsoft Edge is the new Chromium-based browser. Microsoft Edge Legacy is the old EdgeHTML-based browser (EOL: March 9, 2021).
if (browser.edg) {
matched.browser = 'edgechromium';
browser.edgeChromium = true;
}
// Blackberry browsers are marked as Safari on BlackBerry
if ((browser.safari && browser.blackberry) || browser.bb) {
matched.browser = 'blackberry';
browser.blackberry = true;
}
// Playbook browsers are marked as Safari on Playbook
if (browser.safari && browser.playbook) {
matched.browser = 'playbook';
browser.playbook = true;
}
// Opera 15+ are identified as opr
if (browser.opr) {
matched.browser = 'opera';
browser.opera = true;
}
// Stock Android browsers are marked as Safari on Android.
if (browser.safari && browser.android) {
matched.browser = 'android';
browser.android = true;
}
// Kindle browsers are marked as Safari on Kindle
if (browser.safari && browser.kindle) {
matched.browser = 'kindle';
browser.kindle = true;
}
// Kindle Silk browsers are marked as Safari on Kindle
if (browser.safari && browser.silk) {
matched.browser = 'silk';
browser.silk = true;
}
if (browser.vivaldi) {
matched.browser = 'vivaldi';
browser.vivaldi = true;
}
// Assign the name and platform variable
browser.name = matched.browser;
browser.platform = matched.platform;
{
if (userAgent.indexOf('electron') > -1) {
browser.electron = true;
}
else if (document.location.href.indexOf('-extension://') > -1) {
browser.bex = true;
}
else {
if (window.Capacitor !== void 0) {
browser.capacitor = true;
browser.nativeMobile = true;
browser.nativeMobileWrapper = 'capacitor';
}
else if (window._cordovaNative !== void 0 || window.cordova !== void 0) {
browser.cordova = true;
browser.nativeMobile = true;
browser.nativeMobileWrapper = 'cordova';
}
if (
hasTouch === true
&& browser.mac === true
&& (
(browser.desktop === true && browser.safari === true)
|| (
browser.nativeMobile === true
&& browser.android !== true
&& browser.ios !== true
&& browser.ipad !== true
)
)
) {
/*
* Correction needed for iOS since the default
* setting on iPad is to request desktop view; if we have
* touch support and the user agent says it's a
* desktop, we infer that it's an iPhone/iPad with desktop view
* so we must fix the false positives
*/
applyIosCorrection(browser);
}
}
}
return browser
}
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
const ssrClient = {
has: {
touch: false,
webStorage: false
},
within: { iframe: false }
};
// We export "client" for hydration error-free parts,
// like touch directives who do not (and must NOT) wait
// for the client takeover;
// Do NOT import this directly in your app, unless you really know
// what you are doing.
const client = {
userAgent,
is: getPlatform(userAgent),
has: {
touch: hasTouch
},
within: {
iframe: window.self !== window.top
}
};
const Platform = {
install (opts) {
const { $q } = opts;
if (isRuntimeSsrPreHydration.value === true) {
// takeover should increase accuracy for
// the rest of the props; we also avoid
// hydration errors
opts.onSSRHydrated.push(() => {
Object.assign($q.platform, client);
isRuntimeSsrPreHydration.value = false;
iosCorrection = void 0;
});
// we need to make platform reactive
// for the takeover phase
$q.platform = reactive(this);
}
else {
$q.platform = this;
}
}
};
{
// do not access window.localStorage without
// devland actually using it as this will get
// reported under "Cookies" in Google Chrome
let hasWebStorage;
injectProp(client.has, 'webStorage', () => {
if (hasWebStorage !== void 0) {
return hasWebStorage
}
try {
if (window.localStorage) {
hasWebStorage = true;
return true
}
}
catch (e) {}
hasWebStorage = false;
return false
});
client.is.ios === true
&& window.navigator.vendor.toLowerCase().indexOf('apple') === -1;
if (isRuntimeSsrPreHydration.value === true) {
// must match with server-side before
// client taking over in order to prevent
// hydration errors
Object.assign(Platform, client, iosCorrection, ssrClient);
}
else {
Object.assign(Platform, client);
}
}
var defineReactivePlugin = (state, plugin) => {
const reactiveState = reactive(state);
for (const name in state) {
injectProp(
plugin,
name,
() => reactiveState[ name ],
val => { reactiveState[ name ] = val; }
);
}
return plugin
};
const listenOpts = {
hasPassive: false,
passiveCapture: true,
notPassiveCapture: true
};
try {
const opts = Object.defineProperty({}, 'passive', {
get () {
Object.assign(listenOpts, {
hasPassive: true,
passive: { passive: true },
notPassive: { passive: false },
passiveCapture: { passive: true, capture: true },
notPassiveCapture: { passive: false, capture: true }
});
}
});
window.addEventListener('qtest', null, opts);
window.removeEventListener('qtest', null, opts);
}
catch (e) {}
function noop () {}
function leftClick (e) {
return e.button === 0
}
function middleClick (e) {
return e.button === 1
}
function rightClick (e) {
return e.button === 2
}
function position (e) {
if (e.touches && e.touches[ 0 ]) {
e = e.touches[ 0 ];
}
else if (e.changedTouches && e.changedTouches[ 0 ]) {
e = e.changedTouches[ 0 ];
}
else if (e.targetTouches && e.targetTouches[ 0 ]) {
e = e.targetTouches[ 0 ];
}
return {
top: e.clientY,
left: e.clientX
}
}
function getEventPath (e) {
if (e.path) {
return e.path
}
if (e.composedPath) {
return e.composedPath()
}
const path = [];
let el = e.target;
while (el) {
path.push(el);
if (el.tagName === 'HTML') {
path.push(document);
path.push(window);
return path
}
el = el.parentElement;
}
}
// Reasonable defaults
const
LINE_HEIGHT = 40,
PAGE_HEIGHT = 800;
function getMouseWheelDistance (e) {
let x = e.deltaX, y = e.deltaY;
if ((x || y) && e.deltaMode) {
const multiplier = e.deltaMode === 1 ? LINE_HEIGHT : PAGE_HEIGHT;
x *= multiplier;
y *= multiplier;
}
if (e.shiftKey && !x) {
[ y, x ] = [ x, y ];
}
return { x, y }
}
function stop (e) {
e.stopPropagation();
}
function prevent (e) {
e.cancelable !== false && e.preventDefault();
}
function stopAndPrevent (e) {
e.cancelable !== false && e.preventDefault();
e.stopPropagation();
}
function preventDraggable (el, status) {
if (el === void 0 || (status === true && el.__dragPrevented === true)) {
return
}
const fn = status === true
? el => {
el.__dragPrevented = true;
el.addEventListener('dragstart', prevent, listenOpts.notPassiveCapture);
}
: el => {
delete el.__dragPrevented;
el.removeEventListener('dragstart', prevent, listenOpts.notPassiveCapture);
};
el.querySelectorAll('a, img').forEach(fn);
}
function addEvt (ctx, targetName, events) {
const name = `__q_${ targetName }_evt`;
ctx[ name ] = ctx[ name ] !== void 0
? ctx[ name ].concat(events)
: events;
events.forEach(evt => {
evt[ 0 ].addEventListener(evt[ 1 ], ctx[ evt[ 2 ] ], listenOpts[ evt[ 3 ] ]);
});
}
function cleanEvt (ctx, targetName) {
const name = `__q_${ targetName }_evt`;
if (ctx[ name ] !== void 0) {
ctx[ name ].forEach(evt => {
evt[ 0 ].removeEventListener(evt[ 1 ], ctx[ evt[ 2 ] ], listenOpts[ evt[ 3 ] ]);
});
ctx[ name ] = void 0;
}
}
/*
* also update /types/utils/event.d.ts
*/
var event = {
listenOpts,
leftClick,
middleClick,
rightClick,
position,
getEventPath,
getMouseWheelDistance,
stop,
prevent,
stopAndPrevent,
preventDraggable
};
function debounce (fn, wait = 250, immediate) {
let timer = null;
function debounced (/* ...args */) {
const args = arguments;
const later = () => {
timer = null;
if (immediate !== true) {
fn.apply(this, args);
}
};
if (timer !== null) {
clearTimeout(timer);
}
else if (immediate === true) {
fn.apply(this, args);
}
timer = setTimeout(later, wait);
}
debounced.cancel = () => {
timer !== null && clearTimeout(timer);
};
return debounced
}
const SIZE_LIST = [ 'sm', 'md', 'lg', 'xl' ];
const { passive: passive$4 } = listenOpts;
var Screen = defineReactivePlugin({
width: 0,
height: 0,
name: 'xs',
sizes: {
sm: 600,
md: 1024,
lg: 1440,
xl: 1920
},
lt: {
sm: true,
md: true,
lg: true,
xl: true
},
gt: {
xs: false,
sm: false,
md: false,
lg: false
},
xs: true,
sm: false,
md: false,
lg: false,
xl: false
}, {
setSizes: noop,
setDebounce: noop,
install ({ $q, onSSRHydrated }) {
$q.screen = this;
if (this.__installed === true) {
if ($q.config.screen !== void 0) {
if ($q.config.screen.bodyClasses === false) {
document.body.classList.remove(`screen--${ this.name }`);
}
else {
this.__update(true);
}
}
return
}
const { visualViewport } = window;
const target = visualViewport || window;
const scrollingElement = document.scrollingElement || document.documentElement;
const getSize = visualViewport === void 0 || client.is.mobile === true
? () => [
Math.max(window.innerWidth, scrollingElement.clientWidth),
Math.max(window.innerHeight, scrollingElement.clientHeight)
]
: () => [
visualViewport.width * visualViewport.scale + window.innerWidth - scrollingElement.clientWidth,
visualViewport.height * visualViewport.scale + window.innerHeight - scrollingElement.clientHeight
];
const classes = $q.config.screen !== void 0 && $q.config.screen.bodyClasses === true;
this.__update = force => {
const [ w, h ] = getSize();
if (h !== this.height) {
this.height = h;
}
if (w !== this.width) {
this.width = w;
}
else if (force !== true) {
return
}
let s = this.sizes;
this.gt.xs = w >= s.sm;
this.gt.sm = w >= s.md;
this.gt.md = w >= s.lg;
this.gt.lg = w >= s.xl;
this.lt.sm = w < s.sm;
this.lt.md = w < s.md;
this.lt.lg = w < s.lg;
this.lt.xl = w < s.xl;
this.xs = this.lt.sm;
this.sm = this.gt.xs === true && this.lt.md === true;
this.md = this.gt.sm === true && this.lt.lg === true;
this.lg = this.gt.md === true && this.lt.xl === true;
this.xl = this.gt.lg;
s = (this.xs === true && 'xs')
|| (this.sm === true && 'sm')
|| (this.md === true && 'md')
|| (this.lg === true && 'lg')
|| 'xl';
if (s !== this.name) {
if (classes === true) {
document.body.classList.remove(`screen--${ this.name }`);
document.body.classList.add(`screen--${ s }`);
}
this.name = s;
}
};
let updateEvt, updateSizes = {}, updateDebounce = 16;
this.setSizes = sizes => {
SIZE_LIST.forEach(name => {
if (sizes[ name ] !== void 0) {
updateSizes[ name ] = sizes[ name ];
}
});
};
this.setDebounce = deb => {
updateDebounce = deb;
};
const start = () => {
const style = getComputedStyle(document.body);
// if css props available
if (style.getPropertyValue('--q-size-sm')) {
SIZE_LIST.forEach(name => {
this.sizes[ name ] = parseInt(style.getPropertyValue(`--q-size-${ name }`), 10);
});
}
this.setSizes = sizes => {
SIZE_LIST.forEach(name => {
if (sizes[ name ]) {
this.sizes[ name ] = sizes[ name ];
}
});
this.__update(true);
};
this.setDebounce = delay => {
updateEvt !== void 0 && target.removeEventListener('resize', updateEvt, passive$4);
updateEvt = delay > 0
? debounce(this.__update, delay)
: this.__update;
target.addEventListener('resize', updateEvt, passive$4);
};
this.setDebounce(updateDebounce);
if (Object.keys(updateSizes).length > 0) {
this.setSizes(updateSizes);
updateSizes = void 0; // free up memory
}
else {
this.__update();
}
// due to optimizations, this would be left out otherwise
classes === true && this.name === 'xs'
&& document.body.classList.add('screen--xs');
};
if (isRuntimeSsrPreHydration.value === true) {
onSSRHydrated.push(start);
}
else {
start();
}
}
});
const Plugin$9 = defineReactivePlugin({
isActive: false,
mode: false
}, {
__media: void 0,
set (val) {
Plugin$9.mode = val;
if (val === 'auto') {
if (Plugin$9.__media === void 0) {
Plugin$9.__media = window.matchMedia('(prefers-color-scheme: dark)');
Plugin$9.__updateMedia = () => { Plugin$9.set('auto'); };
Plugin$9.__media.addListener(Plugin$9.__updateMedia);
}
val = Plugin$9.__media.matches;
}
else if (Plugin$9.__media !== void 0) {
Plugin$9.__media.removeListener(Plugin$9.__updateMedia);
Plugin$9.__media = void 0;
}
Plugin$9.isActive = val === true;
document.body.classList.remove(`body--${ val === true ? 'light' : 'dark' }`);
document.body.classList.add(`body--${ val === true ? 'dark' : 'light' }`);
},
toggle () {
{
Plugin$9.set(Plugin$9.isActive === false);
}
},
install ({ $q, onSSRHydrated, ssrContext }) {
const { dark } = $q.config;
$q.dark = this;
if (this.__installed === true && dark === void 0) {
return
}
this.isActive = dark === true;
const initialVal = dark !== void 0 ? dark : false;
if (isRuntimeSsrPreHydration.value === true) {
const ssrSet = val => {
this.__fromSSR = val;
};
const originalSet = this.set;
this.set = ssrSet;
ssrSet(initialVal);
onSSRHydrated.push(() => {
this.set = originalSet;
this.set(this.__fromSSR);
});
}
else {
this.set(initialVal);
}
}
});
const getTrue = () => true;
function filterInvalidPath (path) {
return typeof path === 'string'
&& path !== ''
&& path !== '/'
&& path !== '#/'
}
function normalizeExitPath (path) {
path.startsWith('#') === true && (path = path.substring(1));
path.startsWith('/') === false && (path = '/' + path);
path.endsWith('/') === true && (path = path.substring(0, path.length - 1));
return '#' + path
}
function getShouldExitFn (cfg) {
if (cfg.backButtonExit === false) {
return () => false
}
if (cfg.backButtonExit === '*') {
return getTrue
}
// Add default root path
const exitPaths = [ '#/' ];
// Add custom exit paths
Array.isArray(cfg.backButtonExit) === true && exitPaths.push(
...cfg.backButtonExit.filter(filterInvalidPath).map(normalizeExitPath)
);
return () => exitPaths.includes(window.location.hash)
}
var History = {
__history: [],
add: noop,
remove: noop,
install ({ $q }) {
if (this.__installed === true) { return }
const { cordova, capacitor } = client.is;
if (cordova !== true && capacitor !== true) {
return
}
const qConf = $q.config[ cordova === true ? 'cordova' : 'capacitor' ];
if (qConf !== void 0 && qConf.backButton === false) {
return
}
// if the '@capacitor/app' plugin is not installed
// then we got nothing to do
if (
// if we're on Capacitor mode
capacitor === true
// and it's also not in Capacitor's main instance
&& (window.Capacitor === void 0 || window.Capacitor.Plugins.App === void 0)
) {
return
}
this.add = entry => {
if (entry.condition === void 0) {
entry.condition = getTrue;
}
this.__history.push(entry);
};
this.remove = entry => {
const index = this.__history.indexOf(entry);
if (index >= 0) {
this.__history.splice(index, 1);
}
};
const shouldExit = getShouldExitFn(
Object.assign(
{ backButtonExit: true },
qConf
)
);
const backHandler = () => {
if (this.__history.length) {
const entry = this.__history[ this.__history.length - 1 ];
if (entry.condition() === true) {
this.__history.pop();
entry.handler();
}
}
else if (shouldExit() === true) {
navigator.app.exitApp();
}
else {
window.history.back();
}
};
if (cordova === true) {
document.addEventListener('deviceready', () => {
document.addEventListener('backbutton', backHandler, false);
});
}
else {
window.Capacitor.Plugins.App.addListener('backButton', backHandler);
}
}
};
var defaultLang = {
isoName: 'en-US',
nativeName: 'English (US)',
label: {
clear: 'Clear',
ok: 'OK',
cancel: 'Cancel',
close: 'Close',
set: 'Set',
select: 'Select',
reset: 'Reset',
remove: 'Remove',
update: 'Update',
create: 'Create',
search: 'Search',
filter: 'Filter',
refresh: 'Refresh',
expand: label => (label ? `Expand "${ label }"` : 'Expand'),
collapse: label => (label ? `Collapse "${ label }"` : 'Collapse')
},
date: {
days: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
daysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
firstDayOfWeek: 0, // 0-6, 0 - Sunday, 1 Monday, ...
format24h: false,
pluralDay: 'days'
},
table: {
noData: 'No data available',
noResults: 'No matching records found',
loading: 'Loading...',
selectedRecords: rows => (
rows === 1
? '1 record selected.'
: (rows === 0 ? 'No' : rows) + ' records selected.'
),
recordsPerPage: 'Records per page:',
allRows: 'All',
pagination: (start, end, total) => start + '-' + end + ' of ' + total,
columns: 'Columns'
},
editor: {
url: 'URL',
bold: 'Bold',
italic: 'Italic',
strikethrough: 'Strikethrough',
underline: 'Underline',
unorderedList: 'Unordered List',
orderedList: 'Ordered List',
subscript: 'Subscript',
superscript: 'Superscript',
hyperlink: 'Hyperlink',
toggleFullscreen: 'Toggle Fullscreen',
quote: 'Quote',
left: 'Left align',
center: 'Center align',
right: 'Right align',
justify: 'Justify align',
print: 'Print',
outdent: 'Decrease indentation',
indent: 'Increase indentation',
removeFormat: 'Remove formatting',
formatting: 'Formatting',
fontSize: 'Font Size',
align: 'Align',
hr: 'Insert Horizontal Rule',
undo: 'Undo',
redo: 'Redo',
heading1: 'Heading 1',
heading2: 'Heading 2',
heading3: 'Heading 3',
heading4: 'Heading 4',
heading5: 'Heading 5',
heading6: 'Heading 6',
paragraph: 'Paragraph',
code: 'Code',
size1: 'Very small',
size2: 'A bit small',
size3: 'Normal',
size4: 'Medium-large',
size5: 'Big',
size6: 'Very big',
size7: 'Maximum',
defaultFont: 'Default Font',
viewSource: 'View Source'
},
tree: {
noNodes: 'No nodes available',
noResults: 'No matching nodes found'
}
};
function getLocale () {
const val = Array.isArray(navigator.languages) === true && navigator.languages.length > 0
? navigator.languages[ 0 ]
: navigator.language;
if (typeof val === 'string') {
return val.split(/[-_]/).map((v, i) => (
i === 0
? v.toLowerCase()
: (
i > 1 || v.length < 4
? v.toUpperCase()
: (v[ 0 ].toUpperCase() + v.slice(1).toLowerCase())
)
)).join('-')
}
}
const Plugin$8 = defineReactivePlugin({
__langPack: {}
}, {
getLocale,
set (langObject = defaultLang, ssrContext) {
const lang = {
...langObject,
rtl: langObject.rtl === true,
getLocale
};
{
lang.set = Plugin$8.set;
if (Plugin$8.__langConfig === void 0 || Plugin$8.__langConfig.noHtmlAttrs !== true) {
const el = document.documentElement;
el.setAttribute('dir', lang.rtl === true ? 'rtl' : 'ltr');
el.setAttribute('lang', lang.isoName);
}
Object.assign(Plugin$8.__langPack, lang);
Plugin$8.props = lang;
Plugin$8.isoName = lang.isoName;
Plugin$8.nativeName = lang.nativeName;
}
},
install ({ $q, lang, ssrContext }) {
{
$q.lang = Plugin$8.__langPack;
Plugin$8.__langConfig = $q.config.lang;
if (this.__installed === true) {
lang !== void 0 && this.set(lang);
}
else {
this.set(lang || defaultLang);
}
}
}
});
function setCssVar (propName, value, element = document.body) {
if (typeof propName !== 'string') {
throw new TypeError('Expected a string as propName')
}
if (typeof value !== 'string') {
throw new TypeError('Expected a string as value')
}
if (!(element instanceof Element)) {
throw new TypeError('Expected a DOM element')
}
element.style.setProperty(`--q-${ propName }`, value);
}
let lastKeyCompositionStatus = false;
function onKeyDownComposition (evt) {
lastKeyCompositionStatus = evt.isComposing === true;
}
function shouldIgnoreKey (evt) {
return lastKeyCompositionStatus === true
|| evt !== Object(evt)
|| evt.isComposing === true
|| evt.qKeyEvent === true
}
function isKeyCode (evt, keyCodes) {
return shouldIgnoreKey(evt) === true
? false
: [].concat(keyCodes).includes(evt.keyCode)
}
function getMobilePlatform (is) {
if (is.ios === true) return 'ios'
if (is.android === true) return 'android'
}
function getBodyClasses ({ is, has, within }, cfg) {
const cls = [
is.desktop === true ? 'desktop' : 'mobile',
`${ has.touch === false ? 'no-' : '' }touch`
];
if (is.mobile === true) {
const mobile = getMobilePlatform(is);
mobile !== void 0 && cls.push('platform-' + mobile);
}
if (is.nativeMobile === true) {
const type = is.nativeMobileWrapper;
cls.push(type);
cls.push('native-mobile');
if (
is.ios === true
&& (cfg[ type ] === void 0 || cfg[ type ].iosStatusBarPadding !== false)
) {
cls.push('q-ios-padding');
}
}
else if (is.electron === true) {
cls.push('electron');
}
else if (is.bex === true) {
cls.push('bex');
}
within.iframe === true && cls.push('within-iframe');
return cls
}
function applyClientSsrCorrections () {
const { is } = client;
const classes = document.body.className;
const classList = new Set(classes.replace(/ {2}/g, ' ').split(' '));
if (iosCorrection !== void 0) {
classList.delete('desktop');
classList.add('platform-ios');
classList.add('mobile');
}
// else: is it SSG?
else if (is.nativeMobile !== true && is.electron !== true && is.bex !== true) {
if (is.desktop === true) {
classList.delete('mobile');
classList.delete('platform-ios');
classList.delete('platform-android');
classList.add('desktop');
}
else if (is.mobile === true) {
classList.delete('desktop');
classList.add('mobile');
const mobile = getMobilePlatform(is);
if (mobile !== void 0) {
classList.add(`platform-${ mobile }`);
classList.delete(`platform-${ mobile === 'ios' ? 'android' : 'ios' }`);
}
else {
classList.delete('platform-ios');
classList.delete('platform-android');
}
}
}
if (client.has.touch === true) {
classList.delete('no-touch');
classList.add('touch');
}
if (client.within.iframe === true) {
classList.add('within-iframe');
}
const newCls = Array.from(classList).join(' ');
if (classes !== newCls) {
document.body.className = newCls;
}
}
function setColors (brand) {
for (const color in brand) {
setCssVar(color, brand[ color ]);
}
}
var Body = {
install (opts) {
if (this.__installed === true) { return }
if (isRuntimeSsrPreHydration.value === true) {
applyClientSsrCorrections();
}
else {
const { $q } = opts;
$q.config.brand !== void 0 && setColors($q.config.brand);
const cls = getBodyClasses(client, $q.config);
document.body.classList.add.apply(document.body.classList, cls);
}
if (client.is.ios === true) {
// needed for iOS button active state
document.body.addEventListener('touchstart', noop);
}
window.addEventListener('keydown', onKeyDownComposition, true);
}
};
var materialIcons = {
name: 'material-icons',
type: {
positive: 'check_circle',
negative: 'warning',
info: 'info',
warning: 'priority_high'
},
arrow: {
up: 'arrow_upward',
right: 'arrow_forward',
down: 'arrow_downward',
left: 'arrow_back',
dropdown: 'arrow_drop_down'
},
chevron: {
left: 'chevron_left',
right: 'chevron_right'
},
colorPicker: {
spectrum: 'gradient',
tune: 'tune',
palette: 'style'
},
pullToRefresh: {
icon: 'refresh'
},
carousel: {
left: 'chevron_left',
right: 'chevron_right',
up: 'keyboard_arrow_up',
down: 'keyboard_arrow_down',
navigationIcon: 'lens'
},
chip: {
remove: 'cancel',
selected: 'check'
},
datetime: {
arrowLeft: 'chevron_left',
arrowRight: 'chevron_right',
now: 'access_time',
today: 'today'
},
editor: {
bold: 'format_bold',
italic: 'format_italic',
strikethrough: 'strikethrough_s',
underline: 'format_underlined',
unorderedList: 'format_list_bulleted',
orderedList: 'format_list_numbered',
subscript: 'vertical_align_bottom',
superscript: 'vertical_align_top',
hyperlink: 'link',
toggleFullscreen: 'fullscreen',
quote: 'format_quote',
left: 'format_align_left',
center: 'format_align_center',
right: 'format_align_right',
justify: 'format_align_justify',
print: 'print',
outdent: 'format_indent_decrease',
indent: 'format_indent_increase',
removeFormat: 'format_clear',
formatting: 'text_format',
fontSize: 'format_size',
align: 'format_align_left',
hr: 'remove',
undo: 'undo',
redo: 'redo',
heading: 'format_size',
code: 'code',
size: 'format_size',
font: 'font_download',
viewSource: 'code'
},
expansionItem: {
icon: 'keyboard_arrow_down',
denseIcon: 'arrow_drop_down'
},
fab: {
icon: 'add',
activeIcon: 'close'
},
field: {
clear: 'cancel',
error: 'error'
},
pagination: {
first: 'first_page',
prev: 'keyboard_arrow_left',
next: 'keyboard_arrow_right',
last: 'last_page'
},
rating: {
icon: 'grade'
},
stepper: {
done: 'check',
active: 'edit',
error: 'warning'
},
tabs: {
left: 'chevron_left',
right: 'chevron_right',
up: 'keyboard_arrow_up',
down: 'keyboard_arrow_down'
},
table: {
arrowUp: 'arrow_upward',
warning: 'warning',
firstPage: 'first_page',
prevPage: 'chevron_left',
nextPage: 'chevron_right',
lastPage: 'last_page'
},
tree: {
icon: 'play_arrow'
},
uploader: {
done: 'done',
clear: 'clear',
add: 'add_box',
upload: 'cloud_upload',
removeQueue: 'clear_all',
removeUploaded: 'done_all'
}
};
const Plugin$7 = defineReactivePlugin({
iconMapFn: null,
__icons: {}
}, {
set (setObject, ssrContext) {
const def = { ...setObject, rtl: setObject.rtl === true };
{
def.set = Plugin$7.set;
Object.assign(Plugin$7.__icons, def);
}
},
install ({ $q, iconSet, ssrContext }) {
{
if ($q.config.iconMapFn !== void 0) {
this.iconMapFn = $q.config.iconMapFn;
}
$q.iconSet = this.__icons;
injectProp($q, 'iconMapFn', () => this.iconMapFn, val => { this.iconMapFn = val; });
if (this.__installed === true) {
iconSet !== void 0 && this.set(iconSet);
}
else {
this.set(iconSet || materialIcons);
}
}
}
});
const quasarKey = '_q_';
const timelineKey = '_q_t_';
const stepperKey = '_q_s_';
const layoutKey = '_q_l_';
const pageContainerKey = '_q_pc_';
const fabKey = '_q_f_';
const formKey = '_q_fo_';
const tabsKey = '_q_tabs_';
const uploaderKey = '_q_u_';
const emptyRenderFn = () => {};
const globalConfig = {};
let globalConfigIsFrozen = false;
function freezeGlobalConfig () {
globalConfigIsFrozen = true;
}
function isDeepEqual (a, b) {
if (a === b) {
return true
}
if (a !== null && b !== null && typeof a === 'object' && typeof b === 'object') {
if (a.constructor !== b.constructor) {
return false
}
let length, i;
if (a.constructor === Array) {
length = a.length;
if (length !== b.length) {
return false
}
for (i = length; i-- !== 0;) {
if (isDeepEqual(a[ i ], b[ i ]) !== true) {
return false
}
}
return true
}
if (a.constructor === Map) {
if (a.size !== b.size) {
return false
}
let iter = a.entries();
i = iter.next();
while (i.done !== true) {
if (b.has(i.value[ 0 ]) !== true) {
return false
}
i = iter.next();
}
iter = a.entries();
i = iter.next();
while (i.done !== true) {
if (isDeepEqual(i.value[ 1 ], b.get(i.value[ 0 ])) !== true) {
return false
}
i = iter.next();
}
return true
}
if (a.constructor === Set) {
if (a.size !== b.size) {
return false
}
const iter = a.entries();
i = iter.next();
while (i.done !== true) {
if (b.has(i.value[ 0 ]) !== true) {
return false
}
i = iter.next();
}
return true
}
if (a.buffer != null && a.buffer.constructor === ArrayBuffer) {
length = a.length;
if (length !== b.length) {
return false
}
for (i = length; i-- !== 0;) {
if (a[ i ] !== b[ i ]) {
return false
}
}
return true
}
if (a.constructor === RegExp) {
return a.source === b.source && a.flags === b.flags
}
if (a.valueOf !== Object.prototype.valueOf) {
return a.valueOf() === b.valueOf()
}
if (a.toString !== Object.prototype.toString) {
return a.toString() === b.toString()
}
const keys = Object.keys(a).filter(key => a[ key ] !== void 0);
length = keys.length;
if (length !== Object.keys(b).filter(key => b[ key ] !== void 0).length) {
return false
}
for (i = length; i-- !== 0;) {
const key = keys[ i ];
if (isDeepEqual(a[ key ], b[ key ]) !== true) {
return false
}
}
return true
}
// true if both NaN, false otherwise
return a !== a && b !== b // eslint-disable-line no-self-compare
}
// not perfect, but what we ARE interested is for Arrays not to slip in
// as spread operator will mess things up in various areas
function isObject (v) {
return v !== null && typeof v === 'object' && Array.isArray(v) !== true
}
function isDate (v) {
return Object.prototype.toString.call(v) === '[object Date]'
}
function isRegexp (v) {
return Object.prototype.toString.call(v) === '[object RegExp]'
}
function isNumber (v) {
return typeof v === 'number' && isFinite(v)
}
var is = {
deepEqual: isDeepEqual,
object: isObject,
date: isDate,
regexp: isRegexp,
number: isNumber
};
const autoInstalledPlugins = [
Platform,
Body,
Plugin$9,
Screen,
History,
Plugin$8,
Plugin$7
];
function createChildApp (appCfg, parentApp) {
const app = createApp(appCfg);
app.config.globalProperties = parentApp.config.globalProperties;
const { reload, ...appContext } = parentApp._context;
Object.assign(app._context, appContext);
return app
}
function installPlugins (pluginOpts, pluginList) {
pluginList.forEach(Plugin => {
Plugin.install(pluginOpts);
Plugin.__installed = true;
});
}
function prepareApp (app, uiOpts, pluginOpts) {
app.config.globalProperties.$q = pluginOpts.$q;
app.provide(quasarKey, pluginOpts.$q);
installPlugins(pluginOpts, autoInstalledPlugins);
uiOpts.components !== void 0 && Object.values(uiOpts.components).forEach(c => {
if (isObject(c) === true && c.name !== void 0) {
app.component(c.name, c);
}
});
uiOpts.directives !== void 0 && Object.values(uiOpts.directives).forEach(d => {
if (isObject(d) === true && d.name !== void 0) {
app.directive(d.name, d);
}
});
uiOpts.plugins !== void 0 && installPlugins(
pluginOpts,
Object.values(uiOpts.plugins).filter(
p => typeof p.install === 'function' && autoInstalledPlugins.includes(p) === false
)
);
if (isRuntimeSsrPreHydration.value === true) {
pluginOpts.$q.onSSRHydrated = () => {
pluginOpts.onSSRHydrated.forEach(fn => { fn(); });
pluginOpts.$q.onSSRHydrated = () => {};
};
}
}
var installQuasar = function (parentApp, opts = {}) {
const $q = { version: '2.11.9' };
if (globalConfigIsFrozen === false) {
if (opts.config !== void 0) {
Object.assign(globalConfig, opts.config);
}
$q.config = { ...globalConfig };
freezeGlobalConfig();
}
else {
$q.config = opts.config || {};
}
prepareApp(parentApp, opts, {
parentApp,
$q,
lang: opts.lang,
iconSet: opts.iconSet,
onSSRHydrated: []
});
};
const createComponent = raw => markRaw(defineComponent(raw));
const createDirective = raw => markRaw(raw);
const units = [ 'B', 'KB', 'MB', 'GB', 'TB', 'PB' ];
function humanStorageSize (bytes) {
let u = 0;
while (parseInt(bytes, 10) >= 1024 && u < units.length - 1) {
bytes /= 1024;
++u;
}
return `${ bytes.toFixed(1) }${ units[ u ] }`
}
function capitalize (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
function between (v, min, max) {
return max <= min
? min
: Math.min(max, Math.max(min, v))
}
function normalizeToInterval (v, min, max) {
if (max <= min) {
return min
}
const size = (max - min + 1);
let index = min + (v - min) % size;
if (index < min) {
index = size + index;
}
return index === 0 ? 0 : index // fix for (-a % a) => -0
}
function pad (v, length = 2, char = '0') {
if (v === void 0 || v === null) {
return v
}
const val = '' + v;
return val.length >= length
? val
: new Array(length - val.length + 1).join(char) + val
}
var format = {
humanStorageSize,
capitalize,
between,
normalizeToInterval,
pad
};
const
xhr = XMLHttpRequest,
open = xhr.prototype.open,
positionValues = [ 'top', 'right', 'bottom', 'left' ];
let stack = [];
let highjackCount = 0;
function translate ({ p, pos, active, horiz, reverse, dir }) {
let x = 1, y = 1;
if (horiz === true) {
if (reverse === true) { x = -1; }
if (pos === 'bottom') { y = -1; }
return { transform: `translate3d(${ x * (p - 100) }%,${ active ? 0 : y * -200 }%,0)` }
}
if (reverse === true) { y = -1; }
if (pos === 'right') { x = -1; }
return { transform: `translate3d(${ active ? 0 : dir * x * -200 }%,${ y * (p - 100) }%,0)` }
}
function inc (p, amount) {
if (typeof amount !== 'number') {
if (p < 25) {
amount = Math.random() * 3 + 3;
}
else if (p < 65) {
amount = Math.random() * 3;
}
else if (p < 85) {
amount = Math.random() * 2;
}
else if (p < 99) {
amount = 0.6;
}
else {
amount = 0;
}
}
return between(p + amount, 0, 100)
}
function highjackAjax (stackEntry) {
highjackCount++;
stack.push(stackEntry);
if (highjackCount > 1) { return }
xhr.prototype.open = function (_, url) {
const stopStack = [];
const loadStart = () => {
stack.forEach(entry => {
if (
entry.hijackFilter.value === null
|| (entry.hijackFilter.value(url) === true)
) {
entry.start();
stopStack.push(entry.stop);
}
});
};
const loadEnd = () => {
stopStack.forEach(stop => { stop(); });
};
this.addEventListener('loadstart', loadStart, { once: true });
this.addEventListener('loadend', loadEnd, { once: true });
open.apply(this, arguments);
};
}
function restoreAjax (start) {
stack = stack.filter(entry => entry.start !== start);
highjackCount = Math.max(0, highjackCount - 1);
if (highjackCount === 0) {
xhr.prototype.open = open;
}
}
var QAjaxBar = createComponent({
name: 'QAjaxBar',
props: {
position: {
type: String,
default: 'top',
validator: val => positionValues.includes(val)
},
size: {
type: String,
default: '2px'
},
color: String,
skipHijack: Boolean,
reverse: Boolean,
hijackFilter: Function
},
emits: [ 'start', 'stop' ],
setup (props, { emit }) {
const { proxy } = getCurrentInstance();
const progress = ref(0);
const onScreen = ref(false);
const animate = ref(true);
let sessions = 0, timer = null, speed;
const classes = computed(() =>
`q-loading-bar q-loading-bar--${ props.position }`
+ (props.color !== void 0 ? ` bg-${ props.color }` : '')
+ (animate.value === true ? '' : ' no-transition')
);
const horizontal = computed(() => props.position === 'top' || props.position === 'bottom');
const sizeProp = computed(() => (horizontal.value === true ? 'height' : 'width'));
const style = computed(() => {
const active = onScreen.value;
const obj = translate({
p: progress.value,
pos: props.position,
active,
horiz: horizontal.value,
reverse: proxy.$q.lang.rtl === true && [ 'top', 'bottom' ].includes(props.position)
? props.reverse === false
: props.reverse,
dir: proxy.$q.lang.rtl === true ? -1 : 1
});
obj[ sizeProp.value ] = props.size;
obj.opacity = active ? 1 : 0;
return obj
});
const attributes = computed(() => (
onScreen.value === true
? {
role: 'progressbar',
'aria-valuemin': 0,
'aria-valuemax': 100,
'aria-valuenow': progress.value
}
: { 'aria-hidden': 'true' }
));
function start (newSpeed = 300) {
const oldSpeed = speed;
speed = Math.max(0, newSpeed) || 0;
sessions++;
if (sessions > 1) {
if (oldSpeed === 0 && newSpeed > 0) {
planNextStep();
}
else if (timer !== null && oldSpeed > 0 && newSpeed <= 0) {
clearTimeout(timer);
timer = null;
}
return sessions
}
timer !== null && clearTimeout(timer);
emit('start');
progress.value = 0;
timer = setTimeout(() => {
timer = null;
animate.value = true;
newSpeed > 0 && planNextStep();
}, onScreen.value === true ? 500 : 1);
if (onScreen.value !== true) {
onScreen.value = true;
animate.value = false;
}
return sessions
}
function increment (amount) {
if (sessions > 0) {
progress.value = inc(progress.value, amount);
}
return sessions
}
function stop () {
sessions = Math.max(0, sessions - 1);
if (sessions > 0) {
return sessions
}
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
emit('stop');
const end = () => {
animate.value = true;
progress.value = 100;
timer = setTimeout(() => {
timer = null;
onScreen.value = false;
}, 1000);
};
if (progress.value === 0) {
timer = setTimeout(end, 1);
}
else {
end();
}
return sessions
}
function planNextStep () {
if (progress.value < 100) {
timer = setTimeout(() => {
timer = null;
increment();
planNextStep();
}, speed);
}
}
let hijacked;
onMounted(() => {
if (props.skipHijack !== true) {
hijacked = true;
highjackAjax({
start,
stop,
hijackFilter: computed(() => props.hijackFilter || null)
});
}
});
onBeforeUnmount(() => {
timer !== null && clearTimeout(timer);
hijacked === true && restoreAjax(start);
});
// expose public methods
Object.assign(proxy, { start, stop, increment });
return () => h('div', {
class: classes.value,
style: style.value,
...attributes.value
})
}
});
const useSizeDefaults = {
xs: 18,
sm: 24,
md: 32,
lg: 38,
xl: 46
};
const useSizeProps = {
size: String
};
function useSize (props, sizes = useSizeDefaults) {
// return sizeStyle
return computed(() => (
props.size !== void 0
? { fontSize: props.size in sizes ? `${ sizes[ props.size ] }px` : props.size }
: null
))
}
function hSlot (slot, otherwise) {
return slot !== void 0
? slot() || otherwise
: otherwise
}
function hUniqueSlot (slot, otherwise) {
if (slot !== void 0) {
const vnode = slot();
if (vnode !== void 0 && vnode !== null) {
return vnode.slice()
}
}
return otherwise
}
/**
* Source definitely exists,
* so it's merged with the possible slot
*/
function hMergeSlot (slot, source) {
return slot !== void 0
? source.concat(slot())
: source
}
/**
* Merge with possible slot,
* even if source might not exist
*/
function hMergeSlotSafely (slot, source) {
if (slot === void 0) {
return source
}
return source !== void 0
? source.concat(slot())
: slot()
}
/*
* (String) key - unique vnode key
* (Boolean) condition - should change ONLY when adding/removing directive
*/
function hDir (
tag,
data,
children,
key,
condition,
getDirsFn
) {
data.key = key + condition;
const vnode = h(tag, data, children);
return condition === true
? withDirectives(vnode, getDirsFn())
: vnode
}
const defaultViewBox = '0 0 24 24';
const sameFn = i => i;
const ionFn = i => `ionicons ${ i }`;
const libMap = {
'mdi-': i => `mdi ${ i }`,
'icon-': sameFn, // fontawesome equiv
'bt-': i => `bt ${ i }`,
'eva-': i => `eva ${ i }`,
'ion-md': ionFn,
'ion-ios': ionFn,
'ion-logo': ionFn,
'iconfont ': sameFn,
'ti-': i => `themify-icon ${ i }`,
'bi-': i => `bootstrap-icons ${ i }`
};
const matMap = {
o_: '-outlined',
r_: '-round',
s_: '-sharp'
};
const symMap = {
sym_o_: '-outlined',
sym_r_: '-rounded',
sym_s_: '-sharp'
};
const libRE = new RegExp('^(' + Object.keys(libMap).join('|') + ')');
const matRE = new RegExp('^(' + Object.keys(matMap).join('|') + ')');
const symRE = new RegExp('^(' + Object.keys(symMap).join('|') + ')');
const mRE = /^[Mm]\s?[-+]?\.?\d/;
const imgRE = /^img:/;
const svgUseRE = /^svguse:/;
const ionRE = /^ion-/;
const faRE = /^(fa-(solid|regular|light|brands|duotone|thin)|[lf]a[srlbdk]?) /;
var QIcon = createComponent({
name: 'QIcon',
props: {
...useSizeProps,
tag: {
type: String,
default: 'i'
},
name: String,
color: String,
left: Boolean,
right: Bo