UNPKG

@govbr-ds/webcomponents

Version:

Biblioteca de Web Components baseado no GovBR-DS

1,980 lines (1,961 loc) 119 kB
/*! * Construído por SERPRO * © https://serpro.gov.br/ - MIT License. */ import { p as r, H as a, h as o, c as i } from "./p-UEoE4lEZ.js"; var n = {}; /** * (c) Iconify * * For the full copyright and license information, please view the license.txt * files at https://github.com/iconify/iconify * * Licensed under MIT. * * @license MIT * @version 3.0.1 */ var t; function requireIconifyIcon() { if (t) return n; t = 1; /** * Default values for dimensions */ const r = Object.freeze({ left: 0, top: 0, width: 16, height: 16 }); /** * Default values for transformations */ const a = Object.freeze({ rotate: 0, vFlip: false, hFlip: false }); /** * Default values for all optional IconifyIcon properties */ const o = Object.freeze({ ...r, ...a }); /** * Default values for all properties used in ExtendedIconifyIcon */ const i = Object.freeze({ ...o, body: "", hidden: false }); /** * Default icon customisations values */ const e = Object.freeze({ width: null, height: null }); const g = Object.freeze({ ...e, ...a }); /** * Get rotation value */ function rotateFromString(r, a = 0) { const o = r.replace(/^-?[0-9.]*/, ""); function cleanup(r) { while (r < 0) r += 4; return r % 4; } if (o === "") { const a = parseInt(r); return isNaN(a) ? 0 : cleanup(a); } else if (o !== r) { let a = 0; switch (o) { case "%": a = 25; break; case "deg": a = 90; } if (a) { let i = parseFloat(r.slice(0, r.length - o.length)); if (isNaN(i)) return 0; i = i / a; return i % 1 === 0 ? cleanup(i) : 0; } } return a; } const v = /[\s,]+/; /** * Apply "flip" string to icon customisations */ function flipFromString(r, a) { a.split(v).forEach((a => { const o = a.trim(); switch (o) { case "horizontal": r.hFlip = true; break; case "vertical": r.vFlip = true; break; } })); } const d = { ...g, preserveAspectRatio: "" }; /** * Get customisations */ function getCustomisations(r) { const a = { ...d }; const attr = (a, o) => r.getAttribute(a) || o // Dimensions ; a.width = attr("width", null); a.height = attr("height", null); // Rotation a.rotate = rotateFromString(attr("rotate", "")); // Flip flipFromString(a, attr("flip", "")); // SVG attributes a.preserveAspectRatio = attr("preserveAspectRatio", attr("preserveaspectratio", "")); return a; } /** * Check if customisations have been updated */ function haveCustomisationsChanged(r, a) { for (const o in d) { if (r[o] !== a[o]) { return true; } } return false; } /** * Expression to test part of icon name. * * Used when loading icons from Iconify API due to project naming convension. * Ignored when using custom icon sets - convension does not apply. */ const c = /^[a-z0-9]+(-[a-z0-9]+)*$/; /** * Convert string icon name to IconifyIconName object. */ const stringToIcon = (r, a, o, i = "") => { const n = r.split(":"); if (r.slice(0, 1) === "@") { if (n.length < 2 || n.length > 3) return null; i = n.shift().slice(1); } if (n.length > 3 || !n.length) return null; if (n.length > 1) { const r = n.pop(); const o = n.pop(); const t = { provider: n.length > 0 ? n[0] : i, prefix: o, name: r }; return a && !validateIconName(t) ? null : t; } const t = n[0]; const e = t.split("-"); if (e.length > 1) { const r = { provider: i, prefix: e.shift(), name: e.join("-") }; return a && !validateIconName(r) ? null : r; } if (o && i === "") { const r = { provider: i, prefix: "", name: t }; return a && !validateIconName(r, o) ? null : r; } return null; }; /** * Check if icon is valid. * * This function is not part of stringToIcon because validation is not needed for most code. */ const validateIconName = (r, a) => { if (!r) return false; return !!((a && r.prefix === "" || !!r.prefix) && !!r.name); }; /** * Resolve icon set icons * * Returns parent icon for each icon */ function getIconsTree(r, a) { const o = r.icons; const i = r.aliases || Object.create(null); const n = Object.create(null); function resolve(r) { if (o[r]) return n[r] = []; if (!(r in n)) { n[r] = null; const a = i[r] && i[r].parent; const o = a && resolve(a); if (o) n[r] = [ a ].concat(o); } return n[r]; } Object.keys(o).concat(Object.keys(i)).forEach(resolve); return n; } /** * Merge transformations */ function mergeIconTransformations(r, a) { const o = {}; if (!r.hFlip !== !a.hFlip) o.hFlip = true; if (!r.vFlip !== !a.vFlip) o.vFlip = true; const i = ((r.rotate || 0) + (a.rotate || 0)) % 4; if (i) o.rotate = i; return o; } /** * Merge icon and alias * * Can also be used to merge default values and icon */ function mergeIconData(r, o) { const n = mergeIconTransformations(r, o); for (const t in i) if (t in a) { if (t in r && !(t in n)) n[t] = a[t]; } else if (t in o) n[t] = o[t]; else if (t in r) n[t] = r[t]; return n; } /** * Get icon data, using prepared aliases tree */ function internalGetIconData(r, a, o) { const i = r.icons; const n = r.aliases || Object.create(null); let t = {}; function parse(r) { t = mergeIconData(i[r] || n[r], t); } parse(a); o.forEach(parse); return mergeIconData(r, t); } /** * Extract icons from an icon set * * Returns list of icons that were found in icon set */ function parseIconSet(r, a) { const o = []; if (typeof r !== "object" || typeof r.icons !== "object") return o; if (r.not_found instanceof Array) r.not_found.forEach((r => { a(r, null); o.push(r); })); const i = getIconsTree(r); for (const n in i) { const t = i[n]; if (t) { a(n, internalGetIconData(r, n, t)); o.push(n); } } return o; } /** * Optional properties */ const b = { provider: "", aliases: {}, not_found: {}, ...r }; /** * Check props */ function checkOptionalProps(r, a) { for (const o in a) if (o in r && typeof r[o] !== typeof a[o]) return false; return true; } /** * Validate icon set, return it as IconifyJSON on success, null on failure * * Unlike validateIconSet(), this function is very basic. * It does not throw exceptions, it does not check metadata, it does not fix stuff. */ function quicklyValidateIconSet(r) { if (typeof r !== "object" || r === null) return null; const a = r; if (typeof a.prefix !== "string" || !r.icons || typeof r.icons !== "object") return null; if (!checkOptionalProps(r, b)) return null; const o = a.icons; for (const r in o) { const a = o[r]; if (!r || typeof a.body !== "string" || !checkOptionalProps(a, i)) return null; } const n = a.aliases || Object.create(null); for (const r in n) { const a = n[r]; const t = a.parent; if (!r || typeof t !== "string" || !o[t] && !n[t] || !checkOptionalProps(a, i)) return null; } return a; } /** * Storage by provider and prefix */ const u = Object.create(null); /** * Create new storage */ function newStorage(r, a) { return { provider: r, prefix: a, icons: Object.create(null), missing: new Set }; } /** * Get storage for provider and prefix */ function getStorage(r, a) { const o = u[r] || (u[r] = Object.create(null)); return o[a] || (o[a] = newStorage(r, a)); } /** * Add icon set to storage * * Returns array of added icons */ function addIconSet(r, a) { if (!quicklyValidateIconSet(a)) return []; return parseIconSet(a, ((a, o) => { if (o) r.icons[a] = o; else r.missing.add(a); })); } /** * Add icon to storage */ function addIconToStorage(r, a, o) { try { if (typeof o.body === "string") { r.icons[a] = { ...o }; return true; } } catch (r) {} return false; } /** * List available icons */ function listIcons$1(r, a) { let o = []; const i = typeof r === "string" ? [ r ] : Object.keys(u); i.forEach((r => { const i = typeof r === "string" && typeof a === "string" ? [ a ] : Object.keys(u[r] || {}); i.forEach((a => { const i = getStorage(r, a); o = o.concat(Object.keys(i.icons).map((o => (r !== "" ? "@" + r + ":" : "") + a + ":" + o))); })); })); return o; } /** * Allow storing icons without provider or prefix, making it possible to store icons like "home" */ let l = false; function allowSimpleNames(r) { if (typeof r === "boolean") l = r; return l; } /** * Get icon data * * Returns: * - IconifyIcon on success, object directly from storage so don't modify it * - null if icon is marked as missing (returned in `not_found` property from API, so don't bother sending API requests) * - undefined if icon is missing in storage */ function getIconData(r) { const a = typeof r === "string" ? stringToIcon(r, true, l) : r; if (a) { const r = getStorage(a.provider, a.prefix); const o = a.name; return r.icons[o] || (r.missing.has(o) ? null : void 0); } } /** * Add one icon */ function addIcon$1(r, a) { const o = stringToIcon(r, true, l); if (!o) return false; const i = getStorage(o.provider, o.prefix); if (a) return addIconToStorage(i, o.name, a); else { i.missing.add(o.name); return true; } } /** * Add icon set */ function addCollection$1(r, a) { if (typeof r !== "object") return false; if (typeof a !== "string") a = r.provider || ""; if (l && !a && !r.prefix) { let a = false; if (quicklyValidateIconSet(r)) { r.prefix = ""; parseIconSet(r, ((r, o) => { if (addIcon$1(r, o)) a = true; })); } return a; } const o = r.prefix; if (!validateIconName({ prefix: o, name: "a" })) return false; const i = getStorage(a, o); return !!addIconSet(i, r); } /** * Check if icon data is available */ function iconLoaded$1(r) { return !!getIconData(r); } /** * Get full icon */ function getIcon$1(r) { const a = getIconData(r); return a ? { ...o, ...a } : a; } /** * Remove callback */ function removeCallback(r, a) { r.forEach((r => { const o = r.loaderCallbacks; if (o) r.loaderCallbacks = o.filter((r => r.id !== a)); })); } /** * Update all callbacks for provider and prefix */ function updateCallbacks(r) { if (!r.pendingCallbacksFlag) { r.pendingCallbacksFlag = true; setTimeout((() => { r.pendingCallbacksFlag = false; const a = r.loaderCallbacks ? r.loaderCallbacks.slice(0) : []; if (!a.length) return; let o = false; const i = r.provider; const n = r.prefix; a.forEach((a => { const t = a.icons; const e = t.pending.length; t.pending = t.pending.filter((a => { if (a.prefix !== n) return true; const e = a.name; if (r.icons[e]) t.loaded.push({ provider: i, prefix: n, name: e }); else if (r.missing.has(e)) t.missing.push({ provider: i, prefix: n, name: e }); else { o = true; return true; } return false; })); if (t.pending.length !== e) { if (!o) removeCallback([ r ], a.id); a.callback(t.loaded.slice(0), t.missing.slice(0), t.pending.slice(0), a.abort); } })); })); } } /** * Unique id counter for callbacks */ let m = 0; /** * Add callback */ function storeCallback(r, a, o) { const i = m++; const n = removeCallback.bind(null, o, i); if (!a.pending.length) return n; const t = { id: i, icons: a, callback: r, abort: n }; o.forEach((r => { (r.loaderCallbacks || (r.loaderCallbacks = [])).push(t); })); return n; } /** * Check if icons have been loaded */ function sortIcons(r) { const a = { loaded: [], missing: [], pending: [] }; const o = Object.create(null); r.sort(((r, a) => { if (r.provider !== a.provider) return r.provider.localeCompare(a.provider); if (r.prefix !== a.prefix) return r.prefix.localeCompare(a.prefix); return r.name.localeCompare(a.name); })); let i = { provider: "", prefix: "", name: "" }; r.forEach((r => { if (i.name === r.name && i.prefix === r.prefix && i.provider === r.provider) return; i = r; const n = r.provider; const t = r.prefix; const e = r.name; const g = o[n] || (o[n] = Object.create(null)); const v = g[t] || (g[t] = getStorage(n, t)); let d; if (e in v.icons) d = a.loaded; else if (t === "" || v.missing.has(e)) d = a.missing; else d = a.pending; const c = { provider: n, prefix: t, name: e }; d.push(c); })); return a; } /** * Local storate types and entries */ const s = Object.create(null); /** * Set API module */ function setAPIModule(r, a) { s[r] = a; } /** * Get API module */ function getAPIModule(r) { return s[r] || s[""]; } /** * Convert icons list from string/icon mix to icons and validate them */ function listToIcons(r, a = true, o = false) { const i = []; r.forEach((r => { const n = typeof r === "string" ? stringToIcon(r, a, o) : r; if (n) i.push(n); })); return i; } /** * Create full API configuration from partial data */ function createAPIConfig(r) { let a; if (typeof r.resources === "string") a = [ r.resources ]; else { a = r.resources; if (!(a instanceof Array) || !a.length) return null; } const o = { resources: a, path: r.path || "/", maxURL: r.maxURL || 500, rotate: r.rotate || 750, timeout: r.timeout || 5e3, random: r.random === true, index: r.index || 0, dataAfterTimeout: r.dataAfterTimeout !== false }; return o; } /** * Local storage */ const k = Object.create(null); /** * Redundancy for API servers. * * API should have very high uptime because of implemented redundancy at server level, but * sometimes bad things happen. On internet 100% uptime is not possible. * * There could be routing problems. Server might go down for whatever reason, but it takes * few minutes to detect that downtime, so during those few minutes API might not be accessible. * * This script has some redundancy to mitigate possible network issues. * * If one host cannot be reached in 'rotate' (750 by default) ms, script will try to retrieve * data from different host. Hosts have different configurations, pointing to different * API servers hosted at different providers. */ const p = [ "https://api.simplesvg.com", "https://api.unisvg.com" ]; const f = []; while (p.length > 0) if (p.length === 1) f.push(p.shift()); else if (Math.random() > .5) f.push(p.shift()); else f.push(p.pop()); k[""] = createAPIConfig({ resources: [ "https://api.iconify.design" ].concat(f) }); /** * Add custom config for provider */ function addAPIProvider$1(r, a) { const o = createAPIConfig(a); if (o === null) return false; k[r] = o; return true; } /** * Get API configuration */ function getAPIConfig(r) { return k[r]; } /** * List API providers */ function listAPIProviders() { return Object.keys(k); } /** * Default RedundancyConfig for API calls */ const w = { resources: [], index: 0, timeout: 2e3, rotate: 750, random: false, dataAfterTimeout: false }; /** * Send query */ function sendQuery(r, a, o, i) { const n = r.resources.length; const t = r.random ? Math.floor(Math.random() * n) : r.index; let e; if (r.random) { let a = r.resources.slice(0); e = []; while (a.length > 1) { const r = Math.floor(Math.random() * a.length); e.push(a[r]); a = a.slice(0, r).concat(a.slice(r + 1)); } e = e.concat(a); } else e = r.resources.slice(t).concat(r.resources.slice(0, t)); const g = Date.now(); let v = "pending"; let d = 0; let c; let b = null; let u = []; let l = []; if (typeof i === "function") l.push(i); /** * Reset timer */ function resetTimer() { if (b) { clearTimeout(b); b = null; } } /** * Abort everything */ function abort() { if (v === "pending") v = "aborted"; resetTimer(); u.forEach((r => { if (r.status === "pending") r.status = "aborted"; })); u = []; } /** * Add / replace callback to call when execution is complete. * This can be used to abort pending query implementations when query is complete or aborted. */ function subscribe(r, a) { if (a) l = []; if (typeof r === "function") l.push(r); } /** * Get query status */ function getQueryStatus() { return { startTime: g, payload: a, status: v, queriesSent: d, queriesPending: u.length, subscribe, abort }; } /** * Fail query */ function failQuery() { v = "failed"; l.forEach((r => { r(void 0, c); })); } /** * Clear queue */ function clearQueue() { u.forEach((r => { if (r.status === "pending") r.status = "aborted"; })); u = []; } /** * Got response from module */ function moduleResponse(a, o, i) { const n = o !== "success"; u = u.filter((r => r !== a)); switch (v) { case "pending": break; case "failed": if (n || !r.dataAfterTimeout) return; break; default: return; } if (o === "abort") { c = i; failQuery(); return; } if (n) { c = i; if (!u.length) if (!e.length) failQuery(); else execNext(); return; } resetTimer(); clearQueue(); if (!r.random) { const o = r.resources.indexOf(a.resource); if (o !== -1 && o !== r.index) r.index = o; } v = "completed"; l.forEach((r => { r(i); })); } /** * Execute next query */ function execNext() { if (v !== "pending") return; resetTimer(); const i = e.shift(); if (i === void 0) { if (u.length) { b = setTimeout((() => { resetTimer(); if (v === "pending") { clearQueue(); failQuery(); } }), r.timeout); return; } failQuery(); return; } const n = { status: "pending", resource: i, callback: (r, a) => { moduleResponse(n, r, a); } }; u.push(n); d++; b = setTimeout(execNext, r.rotate); o(i, a, n.callback); } setTimeout(execNext); return getQueryStatus; } /** * Redundancy instance */ function initRedundancy(r) { const a = { ...w, ...r }; let o = []; /** * Remove aborted and completed queries */ function cleanup() { o = o.filter((r => r().status === "pending")); } /** * Send query */ function query(r, i, n) { const t = sendQuery(a, r, i, ((r, a) => { cleanup(); if (n) n(r, a); })); o.push(t); return t; } /** * Find instance */ function find(r) { return o.find((a => r(a))) || null; } const i = { query, find, setIndex: r => { a.index = r; }, getIndex: () => a.index, cleanup }; return i; } function emptyCallback$1() {} const y = Object.create(null); /** * Get Redundancy instance for provider */ function getRedundancyCache(r) { if (!y[r]) { const a = getAPIConfig(r); if (!a) return; const o = initRedundancy(a); const i = { config: a, redundancy: o }; y[r] = i; } return y[r]; } /** * Send API query */ function sendAPIQuery(r, a, o) { let i; let n; if (typeof r === "string") { const a = getAPIModule(r); if (!a) { o(void 0, 424); return emptyCallback$1; } n = a.send; const t = getRedundancyCache(r); if (t) i = t.redundancy; } else { const a = createAPIConfig(r); if (a) { i = initRedundancy(a); const o = r.resources ? r.resources[0] : ""; const t = getAPIModule(o); if (t) n = t.send; } } if (!i || !n) { o(void 0, 424); return emptyCallback$1; } return i.query(a, n, o)().abort; } function emptyCallback() {} /** * Function called when new icons have been loaded */ function loadedNewIcons(r) { if (!r.iconsLoaderFlag) { r.iconsLoaderFlag = true; setTimeout((() => { r.iconsLoaderFlag = false; updateCallbacks(r); })); } } /** * Check icon names for API */ function checkIconNamesForAPI(r) { const a = []; const o = []; r.forEach((r => { (r.match(c) ? a : o).push(r); })); return { valid: a, invalid: o }; } /** * Parse loader response */ function parseLoaderResponse(r, a, o) { function checkMissing() { const o = r.pendingIcons; a.forEach((a => { if (o) o.delete(a); if (!r.icons[a]) r.missing.add(a); })); } if (o && typeof o === "object") try { const a = addIconSet(r, o); if (!a.length) { checkMissing(); return; } } catch (r) { console.error(r); } checkMissing(); loadedNewIcons(r); } /** * Handle response that can be async */ function parsePossiblyAsyncResponse(r, a) { if (r instanceof Promise) r.then((r => { a(r); })).catch((() => { a(null); })); else a(r); } /** * Load icons */ function loadNewIcons(r, a) { if (!r.iconsToLoad) r.iconsToLoad = a; else r.iconsToLoad = r.iconsToLoad.concat(a).sort(); if (!r.iconsQueueFlag) { r.iconsQueueFlag = true; setTimeout((() => { r.iconsQueueFlag = false; const {provider: a, prefix: o} = r; const i = r.iconsToLoad; delete r.iconsToLoad; if (!i || !i.length) return; const n = r.loadIcon; if (r.loadIcons && (i.length > 1 || !n)) { parsePossiblyAsyncResponse(r.loadIcons(i, o, a), (a => { parseLoaderResponse(r, i, a); })); return; } if (n) { i.forEach((i => { const t = n(i, o, a); parsePossiblyAsyncResponse(t, (a => { const n = a ? { prefix: o, icons: { [i]: a } } : null; parseLoaderResponse(r, [ i ], n); })); })); return; } const {valid: t, invalid: e} = checkIconNamesForAPI(i); if (e.length) parseLoaderResponse(r, e, null); if (!t.length) return; const g = o.match(c) ? getAPIModule(a) : null; if (!g) { parseLoaderResponse(r, t, null); return; } const v = g.prepare(a, o, t); v.forEach((o => { sendAPIQuery(a, o, (a => { parseLoaderResponse(r, o.icons, a); })); })); })); } } /** * Load icons */ const loadIcons$1 = (r, a) => { const o = listToIcons(r, true, allowSimpleNames()); const i = sortIcons(o); if (!i.pending.length) { let r = true; if (a) setTimeout((() => { if (r) a(i.loaded, i.missing, i.pending, emptyCallback); })); return () => { r = false; }; } const n = Object.create(null); const t = []; let e, g; i.pending.forEach((r => { const {provider: a, prefix: o} = r; if (o === g && a === e) return; e = a; g = o; t.push(getStorage(a, o)); const i = n[a] || (n[a] = Object.create(null)); if (!i[o]) i[o] = []; })); i.pending.forEach((r => { const {provider: a, prefix: o, name: i} = r; const t = getStorage(a, o); const e = t.pendingIcons || (t.pendingIcons = new Set); if (!e.has(i)) { e.add(i); n[a][o].push(i); } })); t.forEach((r => { const a = n[r.provider][r.prefix]; if (a.length) loadNewIcons(r, a); })); return a ? storeCallback(a, i, t) : emptyCallback; }; /** * Load one icon using Promise */ const loadIcon$1 = r => new Promise(((a, i) => { const n = typeof r === "string" ? stringToIcon(r, true) : r; if (!n) { i(r); return; } loadIcons$1([ n || r ], (t => { if (t.length && n) { const r = getIconData(n); if (r) { a({ ...o, ...r }); return; } } i(r); })); })); /** * Test icon string */ function testIconObject(r) { try { const a = typeof r === "string" ? JSON.parse(r) : r; if (typeof a.body === "string") { return { ...a }; } // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { } } /** * Parse icon value, load if needed */ function parseIconValue(r, a) { if (typeof r === "object") { const a = testIconObject(r); return { data: a, value: r }; } if (typeof r !== "string") { // Invalid value return { value: r }; } // Check for JSON if (r.includes("{")) { const a = testIconObject(r); if (a) { return { data: a, value: r }; } } // Parse icon name const o = stringToIcon(r, true, true); if (!o) { return { value: r }; } // Valid icon name: check if data is available const i = getIconData(o); // Icon data exists or icon has no prefix. Do not load icon from API if icon has no prefix if (i !== undefined || !o.prefix) { return { value: r, name: o, data: i }; } // Load icon const n = loadIcons$1([ o ], (() => a(r, o, getIconData(o)))); return { value: r, name: o, loading: n }; } // Check for Safari let h = false; try { h = navigator.vendor.indexOf("Apple") === 0; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { } /** * Get render mode */ function getRenderMode(r, a) { switch (a) { // Force mode case "svg": case "bg": case "mask": return a; } // Check for animation, use 'style' for animated icons, unless browser is Safari // (only <a>, which should be ignored or animations start with '<a') if (a !== "style" && (h || r.indexOf("<a") === -1)) { // Render <svg> return "svg"; } // Use background or mask return r.indexOf("currentColor") === -1 ? "bg" : "mask"; } /** * Regular expressions for calculating dimensions */ const x = /(-?[0-9.]*[0-9]+[0-9.]*)/g; const I = /^-?[0-9.]*[0-9]+[0-9.]*$/g; function calculateSize$1(r, a, o) { if (a === 1) return r; o = o || 100; if (typeof r === "number") return Math.ceil(r * a * o) / o; if (typeof r !== "string") return r; const i = r.split(x); if (i === null || !i.length) return r; const n = []; let t = i.shift(); let e = I.test(t); while (true) { if (e) { const r = parseFloat(t); if (isNaN(r)) n.push(t); else n.push(Math.ceil(r * a * o) / o); } else n.push(t); t = i.shift(); if (t === void 0) return n.join(""); e = !e; } } function splitSVGDefs(r, a = "defs") { let o = ""; const i = r.indexOf("<" + a); while (i >= 0) { const n = r.indexOf(">", i); const t = r.indexOf("</" + a); if (n === -1 || t === -1) break; const e = r.indexOf(">", t); if (e === -1) break; o += r.slice(n + 1, t).trim(); r = r.slice(0, i).trim() + r.slice(e + 1); } return { defs: o, content: r }; } /** * Merge defs and content */ function mergeDefsAndContent(r, a) { return r ? "<defs>" + r + "</defs>" + a : a; } /** * Wrap SVG content, without wrapping definitions */ function wrapSVGContent(r, a, o) { const i = splitSVGDefs(r); return mergeDefsAndContent(i.defs, a + i.content + o); } /** * Check if value should be unset. Allows multiple keywords */ const isUnsetKeyword = r => r === "unset" || r === "undefined" || r === "none" /** * Get SVG attributes and content from icon + customisations * * Does not generate style to make it compatible with frameworks that use objects for style, such as React. * Instead, it generates 'inline' value. If true, rendering engine should add verticalAlign: -0.125em to icon. * * Customisations should be normalised by platform specific parser. * Result should be converted to <svg> by platform specific parser. * Use replaceIDs to generate unique IDs for body. */; function iconToSVG(r, a) { const i = { ...o, ...r }; const n = { ...g, ...a }; const t = { left: i.left, top: i.top, width: i.width, height: i.height }; let e = i.body; [ i, n ].forEach((r => { const a = []; const o = r.hFlip; const i = r.vFlip; let n = r.rotate; if (o) if (i) n += 2; else { a.push("translate(" + (t.width + t.left).toString() + " " + (0 - t.top).toString() + ")"); a.push("scale(-1 1)"); t.top = t.left = 0; } else if (i) { a.push("translate(" + (0 - t.left).toString() + " " + (t.height + t.top).toString() + ")"); a.push("scale(1 -1)"); t.top = t.left = 0; } let g; if (n < 0) n -= Math.floor(n / 4) * 4; n = n % 4; switch (n) { case 1: g = t.height / 2 + t.top; a.unshift("rotate(90 " + g.toString() + " " + g.toString() + ")"); break; case 2: a.unshift("rotate(180 " + (t.width / 2 + t.left).toString() + " " + (t.height / 2 + t.top).toString() + ")"); break; case 3: g = t.width / 2 + t.left; a.unshift("rotate(-90 " + g.toString() + " " + g.toString() + ")"); break; } if (n % 2 === 1) { if (t.left !== t.top) { g = t.left; t.left = t.top; t.top = g; } if (t.width !== t.height) { g = t.width; t.width = t.height; t.height = g; } } if (a.length) e = wrapSVGContent(e, '<g transform="' + a.join(" ") + '">', "</g>"); })); const v = n.width; const d = n.height; const c = t.width; const b = t.height; let u; let l; if (v === null) { l = d === null ? "1em" : d === "auto" ? b : d; u = calculateSize$1(l, c / b); } else { u = v === "auto" ? c : v; l = d === null ? calculateSize$1(u, b / c) : d === "auto" ? b : d; } const m = {}; const setAttr = (r, a) => { if (!isUnsetKeyword(a)) m[r] = a.toString(); }; setAttr("width", u); setAttr("height", l); const s = [ t.left, t.top, c, b ]; m.viewBox = s.join(" "); return { attributes: m, viewBox: s, body: e }; } /** * Generate <svg> */ function iconToHTML$1(r, a) { let o = r.indexOf("xlink:") === -1 ? "" : ' xmlns:xlink="http://www.w3.org/1999/xlink"'; for (const r in a) o += " " + r + '="' + a[r] + '"'; return '<svg xmlns="http://www.w3.org/2000/svg"' + o + ">" + r + "</svg>"; } /** * Encode SVG for use in url() * * Short alternative to encodeURIComponent() that encodes only stuff used in SVG, generating * smaller code. */ function encodeSVGforURL(r) { return r.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " "); } /** * Generate data: URL from SVG */ function svgToData(r) { return "data:image/svg+xml," + encodeSVGforURL(r); } /** * Generate url() from SVG */ function svgToURL$1(r) { return 'url("' + svgToData(r) + '")'; } const detectFetch = () => { let r; try { r = fetch; if (typeof r === "function") return r; } catch (r) {} }; /** * Fetch function */ let S = detectFetch(); /** * Set custom fetch() function */ function setFetch(r) { S = r; } /** * Get fetch() function. Used by Icon Finder Core */ function getFetch() { return S; } /** * Calculate maximum icons list length for prefix */ function calculateMaxLength(r, a) { const o = getAPIConfig(r); if (!o) return 0; let i; if (!o.maxURL) i = 0; else { let r = 0; o.resources.forEach((a => { const o = a; r = Math.max(r, o.length); })); const n = a + ".json?icons="; i = o.maxURL - r - o.path.length - n.length; } return i; } /** * Should query be aborted, based on last HTTP status */ function shouldAbort(r) { return r === 404; } /** * Prepare params */ const prepare = (r, a, o) => { const i = []; const n = calculateMaxLength(r, a); const t = "icons"; let e = { type: t, provider: r, prefix: a, icons: [] }; let g = 0; o.forEach(((o, v) => { g += o.length + 1; if (g >= n && v > 0) { i.push(e); e = { type: t, provider: r, prefix: a, icons: [] }; g = o.length; } e.icons.push(o); })); i.push(e); return i; }; /** * Get path */ function getPath(r) { if (typeof r === "string") { const a = getAPIConfig(r); if (a) return a.path; } return "/"; } /** * Load icons */ const send = (r, a, o) => { if (!S) { o("abort", 424); return; } let i = getPath(a.provider); switch (a.type) { case "icons": { const r = a.prefix; const o = a.icons; const n = o.join(","); const t = new URLSearchParams({ icons: n }); i += r + ".json?" + t.toString(); break; } case "custom": { const r = a.uri; i += r.slice(0, 1) === "/" ? r.slice(1) : r; break; } default: o("abort", 400); return; } let n = 503; S(r + i).then((r => { const a = r.status; if (a !== 200) { setTimeout((() => { o(shouldAbort(a) ? "abort" : "next", a); })); return; } n = 501; return r.json(); })).then((r => { if (typeof r !== "object" || r === null) { setTimeout((() => { if (r === 404) o("abort", r); else o("next", n); })); return; } setTimeout((() => { o("success", r); })); })).catch((() => { o("next", n); })); }; /** * Export module */ const z = { prepare, send }; /** * Set custom loader for multiple icons */ function setCustomIconsLoader$1(r, a, o) { getStorage(o || "", a).loadIcons = r; } /** * Set custom loader for one icon */ function setCustomIconLoader$1(r, a, o) { getStorage(o || "", a).loadIcon = r; } /** * Attribute to add */ const C = "data-style"; /** * Custom style to add to each node */ let P = ""; /** * Set custom style to add to all components * * Affects only components rendered after function call */ function appendCustomStyle(r) { P = r; } /** * Add/update style node */ function updateStyle(r, a) { // Get node, create if needed let o = Array.from(r.childNodes).find((r => r.hasAttribute && r.hasAttribute(C))); if (!o) { o = document.createElement("style"); o.setAttribute(C, C); r.appendChild(o); } // Update content o.textContent = ":host{display:inline-block;vertical-align:" + (a ? "-0.125em" : "0") + "}span,svg{display:block;margin:auto}" + P; } // Core /** * Get functions and initialise stuff */ function exportFunctions() { /** * Initialise stuff */ // Set API module setAPIModule("", z); // Allow simple icon names allowSimpleNames(true); let r; try { r = window; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { } if (r) { // Load icons from global "IconifyPreload" if (r.IconifyPreload !== void 0) { const a = r.IconifyPreload; const o = "Invalid IconifyPreload syntax."; if (typeof a === "object" && a !== null) { (a instanceof Array ? a : [ a ]).forEach((r => { try { if ( // Check if item is an object and not null/array typeof r !== "object" || r === null || r instanceof Array || // Check for 'icons' and 'prefix' typeof r.icons !== "object" || typeof r.prefix !== "string" || // Add icon set !addCollection$1(r)) { console.error(o); } // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { console.error(o); } })); } } // Set API from global "IconifyProviders" if (r.IconifyProviders !== void 0) { const a = r.IconifyProviders; if (typeof a === "object" && a !== null) { for (const r in a) { const o = "IconifyProviders[" + r + "] is invalid."; try { const i = a[r]; if (typeof i !== "object" || !i || i.resources === void 0) { continue; } if (!addAPIProvider$1(r, i)) { console.error(o); } // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { console.error(o); } } } } } const a = { getAPIConfig, setAPIModule, sendAPIQuery, setFetch, getFetch, listAPIProviders }; return { iconLoaded: iconLoaded$1, getIcon: getIcon$1, listIcons: listIcons$1, addIcon: addIcon$1, addCollection: addCollection$1, calculateSize: calculateSize$1, buildIcon: iconToSVG, iconToHTML: iconToHTML$1, svgToURL: svgToURL$1, loadIcons: loadIcons$1, loadIcon: loadIcon$1, addAPIProvider: addAPIProvider$1, setCustomIconLoader: setCustomIconLoader$1, setCustomIconsLoader: setCustomIconsLoader$1, appendCustomStyle, _api: a }; } // List of properties to apply const j = { "background-color": "currentColor" }; const A = { "background-color": "transparent" }; // Dynamically add common props to variables above const T = { image: "var(--svg)", repeat: "no-repeat", size: "100% 100%" }; const O = { "-webkit-mask": j, mask: j, background: A }; for (const r in O) { const a = O[r]; for (const o in T) { a[r + "-" + o] = T[o]; } } /** * Fix size: add 'px' to numbers */ function fixSize(r) { return r ? r + (r.match(/^[-0-9.]+$/) ? "px" : "") : "inherit"; } /** * Render node as <span> */ function renderSPAN(r, a, o) { const i = document.createElement("span"); // Body let n = r.body; if (n.indexOf("<a") !== -1) { // Animated SVG: add something to fix timing bug n += "\x3c!-- " + Date.now() + " --\x3e"; } // Generate SVG as URL const t = r.attributes; const e = iconToHTML$1(n, { ...t, width: a.width + "", height: a.height + "" }); const g = svgToURL$1(e); // Generate style const v = i.style; const d = { "--svg": g, width: fixSize(t.width), height: fixSize(t.height), ...o ? j : A }; // Apply style for (const r in d) { v.setProperty(r, d[r]); } return i; } let L; /** * Attempt to create policy */ function createPolicy() { try { L = window.trustedTypes.createPolicy("iconify", { createHTML: r => r }); } catch (r) { L = null; } } /** * Clean up value for innerHTML assignment * * This code doesn't actually clean up anything. * It is intended be used with Iconify icon data, which has already been validated */ function cleanUpInnerHTML(r) { if (L === void 0) createPolicy(); return L ? L.createHTML(r) : r; } /** * Render node as <svg> */ function renderSVG(r) { const a = document.createElement("span"); // Add style if needed const o = r.attributes; let i = ""; if (!o.width) { i = "width: inherit;"; } if (!o.height) { i += "height: inherit;"; } if (i) { o.style = i; } // Generate SVG const n = iconToHTML$1(r.body, o); a.innerHTML = cleanUpInnerHTML(n); return a.firstChild; } /** * Find icon node */ function findIconElement(r) { return Array.from(r.childNodes).find((r => { const a = r.tagName && r.tagName.toUpperCase(); return a === "SPAN" || a === "SVG"; })); } /** * Render icon */ function renderIcon(r, a) { const i = a.icon.data; const n = a.customisations; // Render icon const t = iconToSVG(i, n); if (n.preserveAspectRatio) { t.attributes["preserveAspectRatio"] = n.preserveAspectRatio; } const e = a.renderedMode; let g; switch (e) { case "svg": g = renderSVG(t); break; default: g = renderSPAN(t, { ...o, ...i }, e === "mask"); } // Set element const v = findIconElement(r); if (v) { // Replace old element if (g.tagName === "SPAN" && v.tagName === g.tagName) { // Swap style instead of whole node v.setAttribute("style", g.getAttribute("style")); } else { r.replaceChild(g, v); } } else { // Add new element r.appendChild(g); } } /** * Set state to PendingState */ function setPendingState(r, a, o) { const i = o && (o.rendered ? o : o.lastRender); return { rendered: false, inline: a, icon: r, lastRender: i }; } /** * Register 'iconify-icon' component, if it does not exist */ function defineIconifyIcon(r = "iconify-icon") { // Check for custom elements registry and HTMLElement let a; let o; try { a = window.customElements; o = window.HTMLElement; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { return; } // Make sure registry and HTMLElement exist if (!a || !o) { return; } // Check for duplicate const i = a.get(r); if (i) { return i; } // All attributes const n = [ // Icon "icon", // Mode "mode", "inline", "noobserver", // Customisations "width", "height", "rotate", "flip" ]; /** * Component class */ const t = class extends o { // Root _shadowRoot; // Initialised _initialised=false; // Icon state _state; // Attributes check queued _checkQueued=false; // Connected _connected=false; // Observer _observer=null; _visible=true; /** * Constructor */ constructor() { super(); // Attach shadow DOM const r = this._shadowRoot = this.attachShadow({ mode: "open" }); // Add style const a = this.hasAttribute("inline"); updateStyle(r, a); // Create empty state this._state = setPendingState({ value: "" }, a); // Queue icon render this._queueCheck(); } /** * Connected to DOM */ connectedCallback() { this._connected = true; this.startObserver(); } /** * Disconnected from DOM */ disconnectedCallback() { this._connected = false; this.stopObserver(); } /** * Observed attributes */ static get observedAttributes() { return n.slice(0); } /** * Observed properties that are different from attributes * * Experimental! Need to test with various frameworks that support it */ /* static get properties() { return { inline: { type: Boolean, reflect: true, }, // Not listing other attributes because they are strings or combination // of string and another type. Cannot have multiple types }; } */ /** * Attribute has changed */ attributeChangedCallback(r) { switch (r) { case "inline": { // Update immediately: not affected by other attributes const r = this.hasAttribute("inline"); const a = this._state; if (r !== a.inline) { // Update style if inline mode changed a.inline = r; updateStyle(this._shadowRoot, r); } break; } case "noobserver": { const r = this.hasAttribute("noobserver"); if (r) { this.startObserver(); } else { this.stopObserver(); } break; } default: // Queue check for other attributes this._queueCheck(); } } /** * Get/set icon */ get icon() { const r = this.getAttribute("icon"); if (r && r.slice(0, 1) === "{") { try { return JSON.parse(r); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { } } return r; } set icon(r) { if (typeof r === "object") { r = JSON.stringify(r); } this.setAttribute("icon", r); } /** * Get/set inline */ get inline() { return this.hasAttribute("inline"); } set inline(r) { if (r) { this.setAttribute("inline", "true"); } else { this.removeAttribute("inline"); } } /** * Get/set observer */ get observer() { return this.hasAttribute("observer"); } set observer(r) { if (r) { this.setAttribute("observer", "true"); } else { this.removeAttribute("observer"); } } /** * Restart animation */ restartAnimation() { const r = this._state; if (r.rendered) { const a = this._shadowRoot; if (r.renderedMode === "svg") { // Update root node try { a.lastChild.setCurrentTime(0); return; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (r) { // Failed: setCurrentTime() is not supported } } renderIcon(a, r); } } /** * Get status */ get status() { const r = this._state; return r.rendered ? "rendered" : r.icon.data === null ? "failed" : "loading"; } /** * Queue attributes re-check */ _queueCheck() { if (!this._checkQueued) { this._checkQueued = true; setTimeout((() => { this._check(); })); } } /** * Check for changes */ _check() { if (!this._checkQueued) { return; } this._checkQueued = false; const r = this._state; // Get icon const a = this.getAttribute("icon"); if (a !== r.icon.value) { this._iconChanged(a); return; } // Ignore other attributes if icon is not rendered if (!r.rendered || !this._visible) { return; } // Check for mode and attribute changes const o = this.getAttribute("mode"); const i = getCustomisations(this); if (r.attrMode !== o || haveCustomisationsChanged(r.customisations, i) || !findIconElement(this._shadowRoot)) { this._renderIcon(r.icon, i, o); } } /** * Icon value has changed