⛄ Sync 2026-04-23 20:32:35
No files matched your search
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
LuCI - Lua Configuration Interface
|
||||
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2018 Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* CBI (Configuration Bindings Interface) helper utilities and DOM helpers.
|
||||
*
|
||||
* Provides initialization for CBI UI elements, dependency handling,
|
||||
* validation wiring and miscellaneous helpers used by LuCI forms. Functions
|
||||
* defined here are registered as global `window.*` symbols.
|
||||
* @module LuCI.cbi
|
||||
*/
|
||||
const cbi_d = [];
|
||||
if (typeof window !== 'undefined')
|
||||
window.cbi_d = cbi_d;
|
||||
const cbi_strings = { path: {}, label: {} };
|
||||
if (typeof window !== 'undefined')
|
||||
window.cbi_strings = cbi_strings;
|
||||
|
||||
/**
|
||||
* Read signed 8-bit integer from a byte array at the given offset.
|
||||
* @param {Array<number>} bytes - Byte array.
|
||||
* @param {number} off - Offset into the array.
|
||||
* @returns {number} Signed 8-bit value (returned as unsigned number).
|
||||
*/
|
||||
function s8(bytes, off) {
|
||||
const n = bytes[off];
|
||||
return (n > 0x7F) ? (n - 256) >>> 0 : n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read unsigned 16-bit little-endian integer from a byte array at offset.
|
||||
* @param {Array<number>} bytes - Byte array.
|
||||
* @param {number} off - Offset into the array.
|
||||
* @returns {number} Unsigned 16-bit integer.
|
||||
*/
|
||||
function u16(bytes, off) {
|
||||
return ((bytes[off + 1] << 8) + bytes[off]) >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a stable 32-bit-ish string hash used for translation keys.
|
||||
* Encodes UTF-8 surrogate pairs and mixes bytes into a hex hash string.
|
||||
* @param {string|null} s - Input string.
|
||||
* @returns {string|null} Hex hash string or null for empty input.
|
||||
*/
|
||||
function sfh(s) {
|
||||
if (s === null || s.length === 0)
|
||||
return null;
|
||||
|
||||
const bytes = [];
|
||||
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
let ch = s.charCodeAt(i);
|
||||
|
||||
// Handle surrogate pairs
|
||||
if (ch >= 0xD800 && ch <= 0xDBFF && i + 1 < s.length) {
|
||||
const next = s.charCodeAt(i + 1);
|
||||
if (next >= 0xDC00 && next <= 0xDFFF) {
|
||||
ch = 0x10000 + ((ch - 0xD800) << 10) + (next - 0xDC00);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch <= 0x7F)
|
||||
bytes.push(ch);
|
||||
else if (ch <= 0x7FF)
|
||||
bytes.push(((ch >>> 6) & 0x1F) | 0xC0,
|
||||
( ch & 0x3F) | 0x80);
|
||||
else if (ch <= 0xFFFF)
|
||||
bytes.push(((ch >>> 12) & 0x0F) | 0xE0,
|
||||
((ch >>> 6) & 0x3F) | 0x80,
|
||||
( ch & 0x3F) | 0x80);
|
||||
else if (ch <= 0x10FFFF)
|
||||
bytes.push(((ch >>> 18) & 0x07) | 0xF0,
|
||||
((ch >>> 12) & 0x3F) | 0x80,
|
||||
((ch >> 6) & 0x3F) | 0x80,
|
||||
( ch & 0x3F) | 0x80);
|
||||
}
|
||||
|
||||
if (!bytes.length)
|
||||
return null;
|
||||
|
||||
let hash = (bytes.length >>> 0);
|
||||
let len = (bytes.length >>> 2);
|
||||
let off = 0, tmp;
|
||||
|
||||
while (len--) {
|
||||
hash += u16(bytes, off);
|
||||
tmp = ((u16(bytes, off + 2) << 11) ^ hash) >>> 0;
|
||||
hash = ((hash << 16) ^ tmp) >>> 0;
|
||||
hash += hash >>> 11;
|
||||
off += 4;
|
||||
}
|
||||
|
||||
switch ((bytes.length & 3) >>> 0) {
|
||||
case 3:
|
||||
hash += u16(bytes, off);
|
||||
hash = (hash ^ (hash << 16)) >>> 0;
|
||||
hash = (hash ^ (s8(bytes, off + 2) << 18)) >>> 0;
|
||||
hash += hash >>> 11;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
hash += u16(bytes, off);
|
||||
hash = (hash ^ (hash << 11)) >>> 0;
|
||||
hash += hash >>> 17;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
hash += s8(bytes, off);
|
||||
hash = (hash ^ (hash << 10)) >>> 0;
|
||||
hash += hash >>> 1;
|
||||
break;
|
||||
}
|
||||
|
||||
hash = (hash ^ (hash << 3)) >>> 0;
|
||||
hash += hash >>> 5;
|
||||
hash = (hash ^ (hash << 4)) >>> 0;
|
||||
hash += hash >>> 17;
|
||||
hash = (hash ^ (hash << 25)) >>> 0;
|
||||
hash += hash >>> 6;
|
||||
|
||||
return (0x100000000 + hash).toString(16).slice(1);
|
||||
}
|
||||
|
||||
var plural_function = null;
|
||||
|
||||
/**
|
||||
* Trim whitespace and normalise internal whitespace sequences to single spaces.
|
||||
* @param {*} s - Value to convert to string and trim.
|
||||
* @returns {string} Trimmed and normalised string.
|
||||
*/
|
||||
function trimws(s) {
|
||||
return String(s).trim().replace(/[ \t\n]+/g, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a translated string for the given message and optional context.
|
||||
* Falls back to the source string when no translation found.
|
||||
* @param {string} s - Source string.
|
||||
* @param {string} [c] - Optional translation context.
|
||||
* @returns {string} Translated string or original.
|
||||
*/
|
||||
function _(s, c) {
|
||||
var k = (c != null ? trimws(c) + '\u0001' : '') + trimws(s);
|
||||
return (window.TR && TR[sfh(k)]) || s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plural-aware translation lookup.
|
||||
* @param {number} n - Quantity to evaluate plural form.
|
||||
* @param {string} s - Singular string.
|
||||
* @param {string} p - Plural string.
|
||||
* @param {string} [c] - Optional context.
|
||||
* @returns {string} Translated plural form or source string.
|
||||
*/
|
||||
function N_(n, s, p, c) {
|
||||
if (plural_function == null && window.TR)
|
||||
plural_function = new Function('n', (TR['00000000'] || 'plural=(n != 1);') + 'return +plural');
|
||||
|
||||
var i = plural_function ? plural_function(n) : (n != 1),
|
||||
k = (c != null ? trimws(c) + '\u0001' : '') + trimws(s) + '\u0002' + i.toString();
|
||||
|
||||
return (window.TR && TR[sfh(k)]) || (i ? p : s);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a dependency entry for a field.
|
||||
* @param {HTMLElement|string} field - Field element or its id.
|
||||
* @param {Object} dep - Dependency specification object.
|
||||
* @param {number} index - Order index of the dependent node.
|
||||
*/
|
||||
function cbi_d_add(field, dep, index) {
|
||||
var obj = (typeof(field) === 'string') ? document.getElementById(field) : field;
|
||||
if (obj) {
|
||||
var entry
|
||||
for (var i=0; i<cbi_d.length; i++) {
|
||||
if (cbi_d[i].id == obj.id) {
|
||||
entry = cbi_d[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!entry) {
|
||||
entry = {
|
||||
"node": obj,
|
||||
"id": obj.id,
|
||||
"parent": obj.parentNode.id,
|
||||
"deps": [],
|
||||
"index": index
|
||||
};
|
||||
cbi_d.unshift(entry);
|
||||
}
|
||||
entry.deps.push(dep)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an input/select identified by target matches the given reference value.
|
||||
* @param {string} target - Element id or name to query.
|
||||
* @param {string} ref - Reference value to compare with.
|
||||
* @returns {boolean} True if the current value matches ref.
|
||||
*/
|
||||
function cbi_d_checkvalue(target, ref) {
|
||||
var value = null,
|
||||
query = 'input[id="'+target+'"], input[name="'+target+'"], ' +
|
||||
'select[id="'+target+'"], select[name="'+target+'"]';
|
||||
|
||||
document.querySelectorAll(query).forEach(function(i) {
|
||||
if (value === null && ((i.type !== 'radio' && i.type !== 'checkbox') || i.checked === true))
|
||||
value = i.value;
|
||||
});
|
||||
|
||||
return (((value !== null) ? value : "") == ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a list of dependency descriptors and return whether any match.
|
||||
* @param {Array<Object>} deps - Array of dependency objects to evaluate.
|
||||
* @returns {boolean} True when dependencies indicate the element should be shown.
|
||||
*/
|
||||
function cbi_d_check(deps) {
|
||||
var reverse;
|
||||
var def = false;
|
||||
for (var i=0; i<deps.length; i++) {
|
||||
var istat = true;
|
||||
reverse = false;
|
||||
for (var j in deps[i]) {
|
||||
if (j == "!reverse") {
|
||||
reverse = true;
|
||||
} else if (j == "!default") {
|
||||
def = true;
|
||||
istat = false;
|
||||
} else {
|
||||
istat = (istat && cbi_d_checkvalue(j, deps[i][j]))
|
||||
}
|
||||
}
|
||||
|
||||
if (istat ^ reverse) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update DOM nodes based on registered dependencies, showing or hiding
|
||||
* nodes and restoring their order when dependency state changes.
|
||||
*/
|
||||
function cbi_d_update() {
|
||||
var state = false;
|
||||
for (var i=0; i<cbi_d.length; i++) {
|
||||
var entry = cbi_d[i];
|
||||
var node = document.getElementById(entry.id);
|
||||
var parent = document.getElementById(entry.parent);
|
||||
|
||||
if (node && node.parentNode && !cbi_d_check(entry.deps)) {
|
||||
node.parentNode.removeChild(node);
|
||||
state = true;
|
||||
}
|
||||
else if (parent && (!node || !node.parentNode) && cbi_d_check(entry.deps)) {
|
||||
var next = undefined;
|
||||
|
||||
for (next = parent.firstChild; next; next = next.nextSibling) {
|
||||
if (next.getAttribute && parseInt(next.getAttribute('data-index'), 10) > entry.index)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!next)
|
||||
parent.appendChild(entry.node);
|
||||
else
|
||||
parent.insertBefore(entry.node, next);
|
||||
|
||||
state = true;
|
||||
}
|
||||
|
||||
// hide optionals widget if no choices remaining
|
||||
if (parent && parent.parentNode && parent.getAttribute('data-optionals'))
|
||||
parent.parentNode.style.display = (parent.options.length <= 1) ? 'none' : '';
|
||||
}
|
||||
|
||||
if (entry && entry.parent)
|
||||
cbi_tag_last(parent);
|
||||
|
||||
if (state)
|
||||
cbi_d_update();
|
||||
else if (parent)
|
||||
parent.dispatchEvent(new CustomEvent('dependency-update', { bubbles: true }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize CBI widgets and wire up dependency and validation handlers.
|
||||
* Walks the DOM looking for CBI-specific data attributes and replaces
|
||||
* placeholders with interactive widgets.
|
||||
*/
|
||||
function cbi_init() {
|
||||
let nodes;
|
||||
|
||||
document.querySelectorAll('.cbi-dropdown').forEach(function(node) {
|
||||
cbi_dropdown_init(node);
|
||||
node.addEventListener('cbi-dropdown-change', cbi_d_update);
|
||||
});
|
||||
|
||||
nodes = document.querySelectorAll('[data-strings]');
|
||||
|
||||
for (let n of nodes) {
|
||||
const str = JSON.parse(n.getAttribute('data-strings'));
|
||||
for (let key in str) {
|
||||
for (let key2 in str[key]) {
|
||||
const dst = cbi_strings[key] || (cbi_strings[key] = { });
|
||||
dst[key2] = str[key][key2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodes = document.querySelectorAll('[data-depends]');
|
||||
|
||||
for (let n of nodes) {
|
||||
const index = parseInt(n.getAttribute('data-index'), 10);
|
||||
const depends = JSON.parse(n.getAttribute('data-depends'));
|
||||
if (!isNaN(index) && depends.length > 0) {
|
||||
for (let a of depends)
|
||||
cbi_d_add(n, a, index);
|
||||
}
|
||||
}
|
||||
|
||||
nodes = document.querySelectorAll('[data-update]');
|
||||
|
||||
for (let n of nodes) {
|
||||
const events = n.getAttribute('data-update').split(' ');
|
||||
for (let ev of events)
|
||||
n.addEventListener(ev, cbi_d_update);
|
||||
}
|
||||
|
||||
nodes = document.querySelectorAll('[data-choices]');
|
||||
|
||||
for (let node of nodes) {
|
||||
const choices = JSON.parse(node.getAttribute('data-choices'));
|
||||
const options = {};
|
||||
|
||||
for (let j = 0; j < choices[0].length; j++)
|
||||
options[choices[0][j]] = choices[1][j];
|
||||
|
||||
const def = (node.getAttribute('data-optional') === 'true')
|
||||
? node.placeholder || '' : null;
|
||||
|
||||
const cb = new L.ui.Combobox(node.value, options, {
|
||||
name: node.getAttribute('name'),
|
||||
sort: choices[0],
|
||||
select_placeholder: def || _('-- Please choose --'),
|
||||
custom_placeholder: node.getAttribute('data-manual') || _('-- custom --')
|
||||
});
|
||||
|
||||
const n = cb.render();
|
||||
n.addEventListener('cbi-dropdown-change', cbi_d_update);
|
||||
node.parentNode.replaceChild(n, node);
|
||||
}
|
||||
|
||||
nodes = document.querySelectorAll('[data-dynlist]');
|
||||
|
||||
for (let node of nodes) {
|
||||
const choices = JSON.parse(node.getAttribute('data-dynlist'));
|
||||
const values = JSON.parse(node.getAttribute('data-values') || '[]');
|
||||
let options = null;
|
||||
|
||||
if (choices[0] && choices[0].length) {
|
||||
options = {};
|
||||
|
||||
for (let j = 0; j < choices[0].length; j++)
|
||||
options[choices[0][j]] = choices[1][j];
|
||||
}
|
||||
|
||||
let dl = new L.ui.DynamicList(values, options, {
|
||||
name: node.getAttribute('data-prefix'),
|
||||
sort: choices[0],
|
||||
datatype: choices[2],
|
||||
optional: choices[3],
|
||||
placeholder: node.getAttribute('data-placeholder')
|
||||
});
|
||||
|
||||
let n = dl.render();
|
||||
n.addEventListener('cbi-dynlist-change', cbi_d_update);
|
||||
node.parentNode.replaceChild(n, node);
|
||||
}
|
||||
|
||||
nodes = document.querySelectorAll('[data-type]');
|
||||
|
||||
for (let node of nodes) {
|
||||
cbi_validate_field(node, node.getAttribute('data-optional') === 'true',
|
||||
node.getAttribute('data-type'));
|
||||
}
|
||||
|
||||
document.querySelectorAll('.cbi-tooltip:not(:empty)').forEach(function(s) {
|
||||
s.parentNode.classList.add('cbi-tooltip-container');
|
||||
});
|
||||
|
||||
document.querySelectorAll('.cbi-section-remove > input[name^="cbi.rts"]').forEach(function(i) {
|
||||
let handler = function(ev) {
|
||||
var bits = this.name.split(/\./),
|
||||
section = document.getElementById('cbi-' + bits[2] + '-' + bits[3]);
|
||||
|
||||
section.style.opacity = (ev.type === 'mouseover') ? 0.5 : '';
|
||||
};
|
||||
|
||||
i.addEventListener('mouseover', handler);
|
||||
i.addEventListener('mouseout', handler);
|
||||
});
|
||||
|
||||
var tasks = [];
|
||||
|
||||
document.querySelectorAll('[data-ui-widget]').forEach(function(node) {
|
||||
const args = JSON.parse(node.getAttribute('data-ui-widget') || '[]');
|
||||
const widget = new (Function.prototype.bind.apply(L.ui[args[0]], args));
|
||||
const markup = widget.render();
|
||||
|
||||
tasks.push(Promise.resolve(markup).then(function(markup) {
|
||||
markup.addEventListener('widget-change', cbi_d_update);
|
||||
node.parentNode.replaceChild(markup, node);
|
||||
}));
|
||||
});
|
||||
|
||||
Promise.all(tasks).then(cbi_d_update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all validators associated with a form and optionally show an error.
|
||||
* @param {HTMLFormElement} form - Form element containing validators.
|
||||
* @param {string} [errmsg] - Message to show when validation fails.
|
||||
* @returns {boolean} True when form is valid.
|
||||
*/
|
||||
function cbi_validate_form(form, errmsg)
|
||||
{
|
||||
/* if triggered by a section removal or addition, don't validate */
|
||||
if (form.cbi_state == 'add-section' || form.cbi_state == 'del-section')
|
||||
return true;
|
||||
|
||||
if (form.cbi_validators) {
|
||||
for (let fv of form.cbi_validators) {
|
||||
const validator = fv;
|
||||
|
||||
if (!validator() && errmsg) {
|
||||
if (typeof window !== 'undefined' && typeof window.alert === 'function')
|
||||
window.alert(errmsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable a named-section add button depending on input value.
|
||||
* @param {HTMLInputElement} input - Input that contains the new section name.
|
||||
*/
|
||||
function cbi_validate_named_section_add(input)
|
||||
{
|
||||
var button = input.parentNode.parentNode.querySelector('.cbi-button-add');
|
||||
button.disabled = input.value === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a delayed form validation (used to allow UI state to settle).
|
||||
* @param {HTMLFormElement} form - Form to validate after a short delay.
|
||||
* @returns {boolean} Always returns true.
|
||||
*/
|
||||
function cbi_validate_reset(form)
|
||||
{
|
||||
window.setTimeout(
|
||||
function() { cbi_validate_form(form, null) }, 100
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a validator to a field and wire validation events.
|
||||
* @param {HTMLElement|string} cbid - Element or element id to validate.
|
||||
* @param {boolean} optional - Whether an empty value is allowed.
|
||||
* @param {string} type - Validator type expression (passed to L.validation).
|
||||
*/
|
||||
function cbi_validate_field(cbid, optional, type)
|
||||
{
|
||||
var field = isElem(cbid) ? cbid : document.getElementById(cbid);
|
||||
var validatorFn;
|
||||
|
||||
try {
|
||||
var cbiValidator = L.validation.create(field, type, optional);
|
||||
validatorFn = cbiValidator.validate.bind(cbiValidator);
|
||||
}
|
||||
catch(e) {
|
||||
validatorFn = null;
|
||||
};
|
||||
|
||||
if (validatorFn !== null) {
|
||||
var form = findParent(field, 'form');
|
||||
|
||||
if (!form.cbi_validators)
|
||||
form.cbi_validators = [ ];
|
||||
|
||||
form.cbi_validators.push(validatorFn);
|
||||
|
||||
field.addEventListener("blur", validatorFn);
|
||||
field.addEventListener("keyup", validatorFn);
|
||||
field.addEventListener("cbi-dropdown-change", validatorFn);
|
||||
|
||||
if (matchesElem(field, 'select')) {
|
||||
field.addEventListener("change", validatorFn);
|
||||
field.addEventListener("click", validatorFn);
|
||||
}
|
||||
|
||||
validatorFn();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a table row up or down within a section and update the storage field.
|
||||
* @param {HTMLElement} elem - Element inside the row that triggers the swap.
|
||||
* @param {boolean} up - If true, move the row up; otherwise move down.
|
||||
* @param {string} store - ID of the hidden input used to store the order.
|
||||
* @returns {boolean} Always returns false to cancel default action.
|
||||
*/
|
||||
function cbi_row_swap(elem, up, store)
|
||||
{
|
||||
var tr = findParent(elem.parentNode, '.cbi-section-table-row');
|
||||
|
||||
if (!tr)
|
||||
return false;
|
||||
|
||||
tr.classList.remove('flash');
|
||||
|
||||
if (up) {
|
||||
var prev = tr.previousElementSibling;
|
||||
|
||||
if (prev && prev.classList.contains('cbi-section-table-row'))
|
||||
tr.parentNode.insertBefore(tr, prev);
|
||||
else
|
||||
return;
|
||||
}
|
||||
else {
|
||||
var next = tr.nextElementSibling ? tr.nextElementSibling.nextElementSibling : null;
|
||||
|
||||
if (next && next.classList.contains('cbi-section-table-row'))
|
||||
tr.parentNode.insertBefore(tr, next);
|
||||
else if (!next)
|
||||
tr.parentNode.appendChild(tr);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
var ids = [ ];
|
||||
|
||||
for (var i = 0, n = 0; i < tr.parentNode.childNodes.length; i++) {
|
||||
var node = tr.parentNode.childNodes[i];
|
||||
if (node.classList && node.classList.contains('cbi-section-table-row')) {
|
||||
node.classList.remove('cbi-rowstyle-1');
|
||||
node.classList.remove('cbi-rowstyle-2');
|
||||
node.classList.add((n++ % 2) ? 'cbi-rowstyle-2' : 'cbi-rowstyle-1');
|
||||
|
||||
if (/-([^-]+)$/.test(node.id))
|
||||
ids.push(RegExp.$1);
|
||||
}
|
||||
}
|
||||
|
||||
var input = document.getElementById(store);
|
||||
if (input)
|
||||
input.value = ids.join(' ');
|
||||
|
||||
window.scrollTo(0, tr.offsetTop);
|
||||
void tr.offsetWidth;
|
||||
tr.classList.add('flash');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the last visible value container child with class `cbi-value-last`.
|
||||
* @param {HTMLElement} container - Parent container element.
|
||||
*/
|
||||
function cbi_tag_last(container)
|
||||
{
|
||||
let last;
|
||||
|
||||
for (let cn of container.childNodes) {
|
||||
var c = cn;
|
||||
if (matchesElem(c, 'div')) {
|
||||
c.classList.remove('cbi-value-last');
|
||||
last = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (last)
|
||||
last.classList.add('cbi-value-last');
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a form, optionally adding a hidden input to pass a name/value pair.
|
||||
* @param {HTMLElement} elem - Element inside the form or an element with a form.
|
||||
* @param {string} [name] - Name of hidden input to include, if any.
|
||||
* @param {string} [value] - Value for the hidden input (defaults to '1').
|
||||
* @param {string} [action] - Optional form action URL override.
|
||||
* @returns {boolean} True on successful submit, false when no form found.
|
||||
*/
|
||||
function cbi_submit(elem, name, value, action)
|
||||
{
|
||||
const form = elem.form || findParent(elem, 'form');
|
||||
|
||||
if (!form)
|
||||
return false;
|
||||
|
||||
if (action)
|
||||
form.action = action;
|
||||
|
||||
if (name) {
|
||||
var hidden = form.querySelector('input[type="hidden"][name="%s"]'.format(name)) ||
|
||||
E('input', { type: 'hidden', name: name });
|
||||
|
||||
hidden.value = value || '1';
|
||||
form.appendChild(hidden);
|
||||
}
|
||||
|
||||
form.submit();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @external String
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format a string using positional arguments.
|
||||
* @function format
|
||||
* @memberof external:String.prototype
|
||||
* @param {...string} args
|
||||
* @returns {string}
|
||||
*/
|
||||
String.prototype.format = function()
|
||||
{
|
||||
if (!RegExp)
|
||||
return;
|
||||
|
||||
const html_esc = [/&/g, '&', /"/g, '"', /'/g, ''', /</g, '<', />/g, '>'];
|
||||
const quot_esc = [/"/g, '"', /'/g, '''];
|
||||
|
||||
/**
|
||||
* Escape a string.
|
||||
* @private
|
||||
* @function esc
|
||||
* @param {string} s
|
||||
* @param {string} r
|
||||
* @returns {string}
|
||||
*/
|
||||
function esc(s, r) {
|
||||
const t = typeof(s);
|
||||
|
||||
if (s == null || t === 'object' || t === 'function')
|
||||
return '';
|
||||
|
||||
if (t !== 'string')
|
||||
s = String(s);
|
||||
|
||||
for (let i = 0; i < r.length; i += 2)
|
||||
s = s.replace(r[i], r[i+1]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
let str = this;
|
||||
let subst, n, pad;
|
||||
let out = '';
|
||||
const re = /^(([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X|q|h|j|t|m))/;
|
||||
let a = [], numSubstitutions = 0;
|
||||
|
||||
while ((a = re.exec(str)) !== null) {
|
||||
const m = a[1];
|
||||
let leftpart = a[2], pPad = a[3], pJustify = a[4], pMinLength = a[5];
|
||||
let pPrecision = a[6], pType = a[7];
|
||||
let precision;
|
||||
|
||||
if (pType == '%') {
|
||||
subst = '%';
|
||||
}
|
||||
else {
|
||||
if (numSubstitutions < arguments.length) {
|
||||
let param = arguments[numSubstitutions++];
|
||||
|
||||
pad = '';
|
||||
if (pPad && pPad.substr(0,1) == "'")
|
||||
pad = pPad.substr(1,1);
|
||||
else if (pPad)
|
||||
pad = pPad;
|
||||
else
|
||||
pad = ' ';
|
||||
|
||||
precision = -1;
|
||||
if (pPrecision && pType == 'f')
|
||||
precision = +pPrecision.substring(1);
|
||||
|
||||
subst = param;
|
||||
|
||||
switch(pType) {
|
||||
case 'b':
|
||||
subst = Math.floor(+param || 0).toString(2);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
subst = String.fromCharCode(+param || 0);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
subst = Math.floor(+param || 0).toFixed(0);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
n = +param || 0;
|
||||
subst = Math.floor((n < 0) ? 0x100000000 + n : n).toFixed(0);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
subst = (precision > -1)
|
||||
? ((+param || 0.0)).toFixed(precision)
|
||||
: (+param || 0.0);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
subst = Math.floor(+param || 0).toString(8);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
subst = param;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
subst = Math.floor(+param || 0).toString(16).toLowerCase();
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
subst = Math.floor(+param || 0).toString(16).toUpperCase();
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
subst = esc(param, html_esc);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
subst = esc(param, quot_esc);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
var td = 0;
|
||||
var th = 0;
|
||||
var tm = 0;
|
||||
var ts = (param || 0);
|
||||
|
||||
if (ts > 59) {
|
||||
tm = Math.floor(ts / 60);
|
||||
ts = (ts % 60);
|
||||
}
|
||||
|
||||
if (tm > 59) {
|
||||
th = Math.floor(tm / 60);
|
||||
tm = (tm % 60);
|
||||
}
|
||||
|
||||
if (th > 23) {
|
||||
td = Math.floor(th / 24);
|
||||
th = (th % 24);
|
||||
}
|
||||
|
||||
subst = (td > 0)
|
||||
? String.format('%dd %dh %dm %ds', td, th, tm, ts)
|
||||
: String.format('%dh %dm %ds', th, tm, ts);
|
||||
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
var mf = pMinLength ? +pMinLength : 1000;
|
||||
var pr = pPrecision ? ~~(10 * +('0' + pPrecision)) : 2;
|
||||
|
||||
var i = 0;
|
||||
var val = (+param || 0);
|
||||
var units = [ ' ', ' K', ' M', ' G', ' T', ' P', ' E' ];
|
||||
|
||||
for (i = 0; (i < units.length) && (val > mf); i++)
|
||||
val /= mf;
|
||||
|
||||
if (i)
|
||||
subst = val.toFixed(pr) + units[i] + (mf == 1024 ? 'i' : '');
|
||||
else
|
||||
subst = val + ' ';
|
||||
|
||||
pMinLength = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pMinLength) {
|
||||
subst = subst.toString();
|
||||
for (let i = subst.length; i < pMinLength; i++)
|
||||
if (pJustify == '-')
|
||||
subst = subst + ' ';
|
||||
else
|
||||
subst = pad + subst;
|
||||
}
|
||||
|
||||
out += leftpart + subst;
|
||||
str = str.substr(m.length);
|
||||
}
|
||||
|
||||
return out + str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string using positional arguments.
|
||||
* @function nobr
|
||||
* @memberof external:String.prototype
|
||||
* @param {...string} args
|
||||
* @returns {string}
|
||||
*/
|
||||
String.prototype.nobr = function()
|
||||
{
|
||||
return this.replace(/[\s\n]+/g, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string using positional arguments.
|
||||
* @function format
|
||||
* @memberof external:String
|
||||
* @param {...string} args
|
||||
* @returns {string}
|
||||
*/
|
||||
String.format = function()
|
||||
{
|
||||
const a = [ ];
|
||||
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
a.push(arguments[i]);
|
||||
}
|
||||
|
||||
return ''.format.apply(arguments[0], a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string using positional arguments.
|
||||
* @function nobr
|
||||
* @memberof external:String
|
||||
* @param {...string} args
|
||||
* @returns {string}
|
||||
*/
|
||||
String.nobr = function()
|
||||
{
|
||||
const a = [ ];
|
||||
|
||||
for (let i = 1; i < arguments.length; i++)
|
||||
a.push(arguments[i]);
|
||||
|
||||
return ''.nobr.apply(arguments[0], a);
|
||||
}
|
||||
|
||||
if (window.NodeList && !NodeList.prototype.forEach) {
|
||||
NodeList.prototype.forEach = function (callback, thisArg) {
|
||||
thisArg = thisArg || window;
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
callback.call(thisArg, this[i], i, this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame = function(f) {
|
||||
window.setTimeout(function() {
|
||||
f(new Date().getTime())
|
||||
}, 1000/30);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the element for input which may be an element or an id.
|
||||
* @param {Element|string} e - Element or id.
|
||||
* @returns {HTMLElement|null}
|
||||
*/
|
||||
function isElem(e) { return L.dom.elem(e) }
|
||||
|
||||
/**
|
||||
* Test whether node matches a CSS selector.
|
||||
* @param {Node} node - Node to test.
|
||||
* @param {string} selector - CSS selector.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function matchesElem(node, selector) { return L.dom.matches(node, selector) }
|
||||
|
||||
/**
|
||||
* Find the parent matching selector from node upwards.
|
||||
* @param {Node} node - Starting node.
|
||||
* @param {string} selector - CSS selector to match ancestor.
|
||||
* @returns {HTMLElement|null}
|
||||
*/
|
||||
function findParent(node, selector) { return L.dom.parent(node, selector) }
|
||||
|
||||
/**
|
||||
* Create DOM elements using {@link L.dom.create} helper (convenience wrapper).
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function E() { return L.dom.create.apply(L.dom, arguments) }
|
||||
|
||||
/**
|
||||
* Initialize a dropdown element into an {@link L.ui.Dropdown} instance and bind it.
|
||||
* If already bound, this is a no-op.
|
||||
* @param {HTMLElement} sb - The select element to convert.
|
||||
* @returns {L.ui.Dropdown|undefined} Dropdown instance or undefined when already bound.
|
||||
*/
|
||||
function cbi_dropdown_init(sb) {
|
||||
if (sb && L.dom.findClassInstance(sb) instanceof L.ui.Dropdown)
|
||||
return;
|
||||
|
||||
const dl = new L.ui.Dropdown(sb, null, { name: sb.getAttribute('name') });
|
||||
return dl.bind(sb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update or initialize a table UI widget with new data.
|
||||
* @param {HTMLElement|string} table - Table element or selector.
|
||||
* @param {...Node[]} data - Data to update the table with.
|
||||
* @param {string} [placeholder] - Placeholder text when empty.
|
||||
*/
|
||||
function cbi_update_table(table, data, placeholder) {
|
||||
const target = isElem(table) ? table : document.querySelector(table);
|
||||
|
||||
if (!isElem(target))
|
||||
return;
|
||||
|
||||
let t = L.dom.findClassInstance(target);
|
||||
|
||||
if (!(t instanceof L.ui.Table)) {
|
||||
t = new L.ui.Table(target);
|
||||
L.dom.bindClassInstance(target, t);
|
||||
}
|
||||
|
||||
t.update(data, placeholder);
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('validation-failure', function(ev) {
|
||||
if (ev.target === document.activeElement)
|
||||
L.showTooltip(ev);
|
||||
});
|
||||
|
||||
document.addEventListener('validation-success', function(ev) {
|
||||
if (ev.target === document.activeElement)
|
||||
L.hideTooltip(ev);
|
||||
});
|
||||
|
||||
L.require('ui').then(function(ui) {
|
||||
document.querySelectorAll('.table').forEach(cbi_update_table);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
||||
<defs>
|
||||
<radialGradient id="a" cx="0" cy="1" r="1">
|
||||
<stop offset="0" stop-color="#89b"/>
|
||||
<stop offset="1" stop-color="#def"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g stroke="#000" stroke-width="2">
|
||||
<path d="M9 2h23l2 1 9 9 1 2v31l-2 1H9l-1-1V4l1-2z" fill="url(#a)"/>
|
||||
<path d="M32 2v11l1 1h11" fill="url(#a)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 389 B |
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
||||
<defs>
|
||||
<radialGradient id="a" cx="0" cy="0" r="1">
|
||||
<stop offset="0" stop-color="#ddf"/>
|
||||
<stop offset="1" stop-color="#46b"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g stroke="#024" stroke-width="2">
|
||||
<path d="M44 14l1 2v25l-1 1H4l-1-1V18v0l1-6 1-2h17l2 2v1l1 1z" fill="url(#a)"/>
|
||||
<path d="M3 18h21l1-1v-3" fill="none"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 415 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
|
||||
<defs>
|
||||
<radialGradient id="a" cx="0" cy="1" r="1">
|
||||
<stop offset="0" stop-color="#89b"/>
|
||||
<stop offset="1" stop-color="#def"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g stroke="#000" stroke-width="2">
|
||||
<path d="M9 2h23l2 1 9 9 1 2v31l-2 1H9l-1-1V4l1-2z" fill="url(#a)"/>
|
||||
<path d="M32 2v11l1 1h11" fill="url(#a)"/>
|
||||
</g>
|
||||
<path d="M13 33h13v6l12-10-12-11v7H13z" fill="#035"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 444 B |
@@ -0,0 +1,594 @@
|
||||
'use strict';
|
||||
'require uci';
|
||||
'require rpc';
|
||||
'require tools.prng as random';
|
||||
|
||||
|
||||
/**
|
||||
* Load the firewall configuration.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function initFirewallState() {
|
||||
return L.resolveDefault(uci.load('firewall'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an enum value.
|
||||
* @param {?string} s
|
||||
* @param {Array<string>} values
|
||||
* @returns {string}
|
||||
*/
|
||||
function parseEnum(s, values) {
|
||||
if (s == null)
|
||||
return null;
|
||||
|
||||
s = String(s).toUpperCase();
|
||||
|
||||
if (s == '')
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < values.length; i++)
|
||||
if (values[i].toUpperCase().indexOf(s) == 0)
|
||||
return values[i];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a policy value, or defaultValue if not found.
|
||||
* @param {?string} s
|
||||
* @param {Array<string>} [defaultValue=['DROP', 'REJECT', 'ACCEPT']]
|
||||
* @returns {?string}
|
||||
*/
|
||||
function parsePolicy(s, defaultValue) {
|
||||
return parseEnum(s, ['DROP', 'REJECT', 'ACCEPT']) || (arguments.length < 2 ? null : defaultValue);
|
||||
}
|
||||
|
||||
|
||||
var Firewall, AbstractFirewallItem, Defaults, Zone, Forwarding, Redirect, Rule;
|
||||
|
||||
/**
|
||||
* Look up a firewall zone.
|
||||
* @param {?string} name
|
||||
* @returns {?Zone}
|
||||
*/
|
||||
function lookupZone(name) {
|
||||
var z = uci.get('firewall', name);
|
||||
|
||||
if (z != null && z['.type'] == 'zone')
|
||||
return new Zone(z['.name']);
|
||||
|
||||
var sections = uci.sections('firewall', 'zone');
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].name != name)
|
||||
continue;
|
||||
|
||||
return new Zone(sections[i]['.name']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a colour for a name.
|
||||
* @param {?string} forName
|
||||
* @returns {string}
|
||||
*/
|
||||
function getColorForName(forName) {
|
||||
if (forName == null)
|
||||
return '#eeeeee';
|
||||
else if (forName == 'lan')
|
||||
return '#90f090';
|
||||
else if (forName == 'wan')
|
||||
return '#f09090';
|
||||
|
||||
return random.derive_color(forName);
|
||||
}
|
||||
|
||||
|
||||
Firewall = L.Class.extend({
|
||||
getDefaults: function() {
|
||||
return initFirewallState().then(function() {
|
||||
return new Defaults();
|
||||
});
|
||||
},
|
||||
|
||||
newZone: function() {
|
||||
return initFirewallState().then(L.bind(async function() {
|
||||
var name = 'newzone',
|
||||
count = 1;
|
||||
|
||||
while ((await this.getZone(name)) != null)
|
||||
name = 'newzone%d'.format(++count);
|
||||
|
||||
return this.addZone(name);
|
||||
}, this));
|
||||
},
|
||||
|
||||
addZone: function(name) {
|
||||
return initFirewallState().then(L.bind(function() {
|
||||
if (name == null || !/^[a-zA-Z0-9_]+$/.test(name))
|
||||
return null;
|
||||
|
||||
if (lookupZone(name) != null)
|
||||
return null;
|
||||
|
||||
var d = new Defaults(),
|
||||
z = uci.add('firewall', 'zone');
|
||||
|
||||
uci.set('firewall', z, 'name', name);
|
||||
uci.set('firewall', z, 'input', d.getInput() || 'DROP');
|
||||
uci.set('firewall', z, 'output', d.getOutput() || 'DROP');
|
||||
uci.set('firewall', z, 'forward', d.getForward() || 'DROP');
|
||||
|
||||
return new Zone(z);
|
||||
}, this));
|
||||
},
|
||||
|
||||
getZone: function(name) {
|
||||
return initFirewallState().then(function() {
|
||||
return lookupZone(name);
|
||||
});
|
||||
},
|
||||
|
||||
getZones: function() {
|
||||
return initFirewallState().then(function() {
|
||||
const sections = uci.sections('firewall', 'zone');
|
||||
const zones = [];
|
||||
|
||||
for (let s of sections)
|
||||
zones.push(new Zone(s['.name']));
|
||||
|
||||
zones.sort(function(a, b) { return L.naturalCompare(a.getName() || '', b.getName() || '') });
|
||||
|
||||
return zones;
|
||||
});
|
||||
},
|
||||
|
||||
getZoneByNetwork: function(network) {
|
||||
return initFirewallState().then(function() {
|
||||
const sections = uci.sections('firewall', 'zone');
|
||||
|
||||
for (let s of sections)
|
||||
if (L.toArray(s.network).indexOf(network) != -1)
|
||||
return new Zone(s['.name']);
|
||||
|
||||
return null;
|
||||
});
|
||||
},
|
||||
|
||||
deleteZone: function(name) {
|
||||
return initFirewallState().then(function() {
|
||||
const section = uci.get('firewall', name);
|
||||
let found = false;
|
||||
|
||||
if (section != null && section['.type'] == 'zone') {
|
||||
found = true;
|
||||
name = section.name;
|
||||
uci.remove('firewall', section['.name']);
|
||||
}
|
||||
else if (name != null) {
|
||||
const sections = uci.sections('firewall', 'zone');
|
||||
|
||||
for (let s of sections) {
|
||||
if (s.name != name)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
uci.remove('firewall', s['.name']);
|
||||
}
|
||||
}
|
||||
|
||||
if (found == true) {
|
||||
const sections = uci.sections('firewall');
|
||||
|
||||
for (let s of sections) {
|
||||
if (s['.type'] != 'rule' &&
|
||||
s['.type'] != 'redirect' &&
|
||||
s['.type'] != 'forwarding')
|
||||
continue;
|
||||
|
||||
if (s.src == name || s.dest == name)
|
||||
uci.remove('firewall', s['.name']);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
},
|
||||
|
||||
renameZone: function(oldName, newName) {
|
||||
return initFirewallState().then(L.bind(function() {
|
||||
if (oldName == null || newName == null || !/^[a-zA-Z0-9_]+$/.test(newName))
|
||||
return false;
|
||||
|
||||
if (lookupZone(newName) != null)
|
||||
return false;
|
||||
|
||||
const sections = uci.sections('firewall', 'zone');
|
||||
let found = false;
|
||||
|
||||
for (let s of sections) {
|
||||
if (s.name != oldName)
|
||||
continue;
|
||||
|
||||
uci.set('firewall', s['.name'], 'name', newName);
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found == true) {
|
||||
const sections = uci.sections('firewall');
|
||||
|
||||
for (let s of sections) {
|
||||
if (s['.type'] != 'rule' &&
|
||||
s['.type'] != 'redirect' &&
|
||||
s['.type'] != 'forwarding')
|
||||
continue;
|
||||
|
||||
if (s.src == oldName)
|
||||
uci.set('firewall', s['.name'], 'src', newName);
|
||||
|
||||
if (s.dest == oldName)
|
||||
uci.set('firewall', s['.name'], 'dest', newName);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}, this));
|
||||
},
|
||||
|
||||
deleteNetwork: function(network) {
|
||||
return this.getZones().then(L.bind(function(zones) {
|
||||
var rv = false;
|
||||
|
||||
for (var i = 0; i < zones.length; i++)
|
||||
if (zones[i].deleteNetwork(network))
|
||||
rv = true;
|
||||
|
||||
return rv;
|
||||
}, this));
|
||||
},
|
||||
|
||||
getColorForName: getColorForName,
|
||||
|
||||
getZoneColorStyle: function(zone) {
|
||||
var hex = (zone instanceof Zone) ? zone.getColor() : getColorForName((zone != null && zone != '*') ? zone : null);
|
||||
|
||||
return '--zone-color-rgb:%d, %d, %d; background-color:rgb(var(--zone-color-rgb))'.format(
|
||||
parseInt(hex.substring(1, 3), 16),
|
||||
parseInt(hex.substring(3, 5), 16),
|
||||
parseInt(hex.substring(5, 7), 16)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
AbstractFirewallItem = L.Class.extend({
|
||||
get: function(option) {
|
||||
return uci.get('firewall', this.sid, option);
|
||||
},
|
||||
|
||||
set: function(option, value) {
|
||||
return uci.set('firewall', this.sid, option, value);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Defaults = AbstractFirewallItem.extend({
|
||||
__init__: function() {
|
||||
var sections = uci.sections('firewall', 'defaults');
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
this.sid = sections[i]['.name'];
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.sid == null)
|
||||
this.sid = uci.add('firewall', 'defaults');
|
||||
},
|
||||
|
||||
isSynFlood: function() {
|
||||
return (this.get('syn_flood') == '1');
|
||||
},
|
||||
|
||||
isDropInvalid: function() {
|
||||
return (this.get('drop_invalid') == '1');
|
||||
},
|
||||
|
||||
getInput: function() {
|
||||
return parsePolicy(this.get('input'), 'DROP');
|
||||
},
|
||||
|
||||
getOutput: function() {
|
||||
return parsePolicy(this.get('output'), 'DROP');
|
||||
},
|
||||
|
||||
getForward: function() {
|
||||
return parsePolicy(this.get('forward'), 'DROP');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Zone = AbstractFirewallItem.extend({
|
||||
__init__: function(name) {
|
||||
var section = uci.get('firewall', name);
|
||||
|
||||
if (section != null && section['.type'] == 'zone') {
|
||||
this.sid = name;
|
||||
this.data = section;
|
||||
}
|
||||
else if (name != null) {
|
||||
var sections = uci.get('firewall', 'zone');
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].name != name)
|
||||
continue;
|
||||
|
||||
this.sid = sections[i]['.name'];
|
||||
this.data = sections[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isMasquerade: function() {
|
||||
return (this.get('masq') == '1');
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
return this.get('name');
|
||||
},
|
||||
|
||||
getNetwork: function() {
|
||||
return this.get('network');
|
||||
},
|
||||
|
||||
getInput: function() {
|
||||
return parsePolicy(this.get('input'), (new Defaults()).getInput());
|
||||
},
|
||||
|
||||
getOutput: function() {
|
||||
return parsePolicy(this.get('output'), (new Defaults()).getOutput());
|
||||
},
|
||||
|
||||
getForward: function() {
|
||||
return parsePolicy(this.get('forward'), (new Defaults()).getForward());
|
||||
},
|
||||
|
||||
addNetwork: function(network) {
|
||||
var section = uci.get('network', network);
|
||||
|
||||
if (section == null || section['.type'] != 'interface')
|
||||
return false;
|
||||
|
||||
var newNetworks = this.getNetworks();
|
||||
|
||||
if (newNetworks.filter(function(net) { return net == network }).length)
|
||||
return false;
|
||||
|
||||
newNetworks.push(network);
|
||||
this.set('network', newNetworks);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
deleteNetwork: function(network) {
|
||||
var oldNetworks = this.getNetworks(),
|
||||
newNetworks = oldNetworks.filter(function(net) { return net != network });
|
||||
|
||||
if (newNetworks.length > 0)
|
||||
this.set('network', newNetworks);
|
||||
else
|
||||
this.set('network', null);
|
||||
|
||||
return (newNetworks.length < oldNetworks.length);
|
||||
},
|
||||
|
||||
getNetworks: function() {
|
||||
return L.toArray(this.get('network'));
|
||||
},
|
||||
|
||||
clearNetworks: function() {
|
||||
this.set('network', null);
|
||||
},
|
||||
|
||||
getDevices: function() {
|
||||
return L.toArray(this.get('device'));
|
||||
},
|
||||
|
||||
getSubnets: function() {
|
||||
return L.toArray(this.get('subnet'));
|
||||
},
|
||||
|
||||
getForwardingsBy: function(what) {
|
||||
var sections = uci.sections('firewall', 'forwarding'),
|
||||
forwards = [];
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].src == null || sections[i].dest == null)
|
||||
continue;
|
||||
|
||||
if (sections[i][what] != this.getName())
|
||||
continue;
|
||||
|
||||
forwards.push(new Forwarding(sections[i]['.name']));
|
||||
}
|
||||
|
||||
return forwards;
|
||||
},
|
||||
|
||||
addForwardingTo: function(dest) {
|
||||
var forwards = this.getForwardingsBy('src'),
|
||||
zone = lookupZone(dest);
|
||||
|
||||
if (zone == null || zone.getName() == this.getName())
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < forwards.length; i++)
|
||||
if (forwards[i].getDestination() == zone.getName())
|
||||
return null;
|
||||
|
||||
var sid = uci.add('firewall', 'forwarding');
|
||||
|
||||
uci.set('firewall', sid, 'src', this.getName());
|
||||
uci.set('firewall', sid, 'dest', zone.getName());
|
||||
|
||||
return new Forwarding(sid);
|
||||
},
|
||||
|
||||
addForwardingFrom: function(src) {
|
||||
var forwards = this.getForwardingsBy('dest'),
|
||||
zone = lookupZone(src);
|
||||
|
||||
if (zone == null || zone.getName() == this.getName())
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < forwards.length; i++)
|
||||
if (forwards[i].getSource() == zone.getName())
|
||||
return null;
|
||||
|
||||
var sid = uci.add('firewall', 'forwarding');
|
||||
|
||||
uci.set('firewall', sid, 'src', zone.getName());
|
||||
uci.set('firewall', sid, 'dest', this.getName());
|
||||
|
||||
return new Forwarding(sid);
|
||||
},
|
||||
|
||||
deleteForwardingsBy: function(what) {
|
||||
var sections = uci.sections('firewall', 'forwarding'),
|
||||
found = false;
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].src == null || sections[i].dest == null)
|
||||
continue;
|
||||
|
||||
if (sections[i][what] != this.getName())
|
||||
continue;
|
||||
|
||||
uci.remove('firewall', sections[i]['.name']);
|
||||
found = true;
|
||||
}
|
||||
|
||||
return found;
|
||||
},
|
||||
|
||||
deleteForwarding: function(forwarding) {
|
||||
if (!(forwarding instanceof Forwarding))
|
||||
return false;
|
||||
|
||||
var section = uci.get('firewall', forwarding.sid);
|
||||
|
||||
if (!section || section['.type'] != 'forwarding')
|
||||
return false;
|
||||
|
||||
uci.remove('firewall', section['.name']);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
addRedirect: function(options) {
|
||||
var sid = uci.add('firewall', 'redirect');
|
||||
|
||||
if (options != null && typeof(options) == 'object')
|
||||
for (var key in options)
|
||||
if (options.hasOwnProperty(key))
|
||||
uci.set('firewall', sid, key, options[key]);
|
||||
|
||||
uci.set('firewall', sid, 'src', this.getName());
|
||||
|
||||
return new Redirect(sid);
|
||||
},
|
||||
|
||||
addRule: function(options) {
|
||||
var sid = uci.add('firewall', 'rule');
|
||||
|
||||
if (options != null && typeof(options) == 'object')
|
||||
for (var key in options)
|
||||
if (options.hasOwnProperty(key))
|
||||
uci.set('firewall', sid, key, options[key]);
|
||||
|
||||
uci.set('firewall', sid, 'src', this.getName());
|
||||
|
||||
return new Rule(sid);
|
||||
},
|
||||
|
||||
getColor: function(forName) {
|
||||
var name = (arguments.length > 0 ? forName : this.getName());
|
||||
|
||||
return getColorForName(name);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Forwarding = AbstractFirewallItem.extend({
|
||||
__init__: function(sid) {
|
||||
this.sid = sid;
|
||||
},
|
||||
|
||||
getSource: function() {
|
||||
return this.get('src');
|
||||
},
|
||||
|
||||
getDestination: function() {
|
||||
return this.get('dest');
|
||||
},
|
||||
|
||||
getSourceZone: function() {
|
||||
return lookupZone(this.getSource());
|
||||
},
|
||||
|
||||
getDestinationZone: function() {
|
||||
return lookupZone(this.getDestination());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Rule = AbstractFirewallItem.extend({
|
||||
__init__: function(sid) {
|
||||
this.sid = sid;
|
||||
},
|
||||
|
||||
getSource: function() {
|
||||
return this.get('src');
|
||||
},
|
||||
|
||||
getDestination: function() {
|
||||
return this.get('dest');
|
||||
},
|
||||
|
||||
getSourceZone: function() {
|
||||
return lookupZone(this.getSource());
|
||||
},
|
||||
|
||||
getDestinationZone: function() {
|
||||
return lookupZone(this.getDestination());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Redirect = AbstractFirewallItem.extend({
|
||||
__init__: function(sid) {
|
||||
this.sid = sid;
|
||||
},
|
||||
|
||||
getSource: function() {
|
||||
return this.get('src');
|
||||
},
|
||||
|
||||
getDestination: function() {
|
||||
return this.get('dest');
|
||||
},
|
||||
|
||||
getSourceZone: function() {
|
||||
return lookupZone(this.getSource());
|
||||
},
|
||||
|
||||
getDestinationZone: function() {
|
||||
return lookupZone(this.getDestination());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return Firewall;
|
||||
@@ -0,0 +1,469 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
'require request';
|
||||
'require baseclass';
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileStatEntry
|
||||
* @memberof LuCI.fs
|
||||
*
|
||||
* @property {string} name - Name of the directory entry
|
||||
* @property {string} type - Type of the entry, one of `block`, `char`, `directory`, `fifo`, `symlink`, `file`, `socket` or `unknown`
|
||||
* @property {number} size - Size in bytes
|
||||
* @property {number} mode - Access permissions
|
||||
* @property {number} atime - Last access time in seconds since epoch
|
||||
* @property {number} mtime - Last modification time in seconds since epoch
|
||||
* @property {number} ctime - Last change time in seconds since epoch
|
||||
* @property {number} inode - Inode number
|
||||
* @property {number} uid - Numeric owner id
|
||||
* @property {number} gid - Numeric group id
|
||||
* @property {string} user - User name of owner
|
||||
* @property {string} group - Group name of owner
|
||||
* @property {Object?} target - a dictionary of properties of any symlink target for `list` operation result entries
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileExecResult
|
||||
* @memberof LuCI.fs
|
||||
*
|
||||
* @property {number} code - The exit code of the invoked command
|
||||
* @property {string} [stdout] - The stdout produced by the command, if any
|
||||
* @property {string} [stderr] - The stderr produced by the command, if any
|
||||
*/
|
||||
|
||||
const callFileList = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'list',
|
||||
params: [ 'path' ]
|
||||
});
|
||||
|
||||
const callFileStat = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'stat',
|
||||
params: [ 'path' ]
|
||||
});
|
||||
|
||||
const callFileLStat = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'lstat',
|
||||
params: [ 'path' ]
|
||||
});
|
||||
|
||||
const callFileRead = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'read',
|
||||
params: [ 'path' ]
|
||||
});
|
||||
|
||||
const callFileWrite = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'write',
|
||||
params: [ 'path', 'data', 'mode' ]
|
||||
});
|
||||
|
||||
const callFileRemove = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'remove',
|
||||
params: [ 'path' ]
|
||||
});
|
||||
|
||||
const callFileExec = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'exec',
|
||||
params: [ 'command', 'params', 'env' ]
|
||||
});
|
||||
|
||||
const rpcErrors = [
|
||||
null,
|
||||
'InvalidCommandError',
|
||||
'InvalidArgumentError',
|
||||
'MethodNotFoundError',
|
||||
'NotFoundError',
|
||||
'NoDataError',
|
||||
'PermissionError',
|
||||
'TimeoutError',
|
||||
'UnsupportedError'
|
||||
];
|
||||
|
||||
/**
|
||||
* Handle an RPC reply.
|
||||
* @param {object} expect
|
||||
* @param {number} rc
|
||||
* @throws {Error}
|
||||
* @returns {number}
|
||||
*/
|
||||
function handleRpcReply(expect, rc) {
|
||||
if (typeof(rc) == 'number' && rc != 0) {
|
||||
let e = new Error(rpc.getStatusText(rc)); e.name = rpcErrors[rc] || 'Error';
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (expect) {
|
||||
const type = Object.prototype.toString;
|
||||
|
||||
for (let key in expect) {
|
||||
if (rc != null && key != '')
|
||||
rc = rc[key];
|
||||
|
||||
if (rc == null || type.call(rc) != type.call(expect[key])) {
|
||||
let e = new Error(_('Unexpected reply data format')); e.name = 'TypeError';
|
||||
throw e;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a CGI-IO reply.
|
||||
* @param {object} res
|
||||
* @throws {Error}
|
||||
* @returns {string}
|
||||
*/
|
||||
function handleCgiIoReply(res) {
|
||||
if (!res.ok || res.status != 200) {
|
||||
var e = new Error(res.statusText);
|
||||
switch (res.status) {
|
||||
case 400:
|
||||
e.name = 'InvalidArgumentError';
|
||||
break;
|
||||
|
||||
case 403:
|
||||
e.name = 'PermissionError';
|
||||
break;
|
||||
|
||||
case 404:
|
||||
e.name = 'NotFoundError';
|
||||
break;
|
||||
|
||||
default:
|
||||
e.name = 'Error';
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
switch (this.type) {
|
||||
case 'blob':
|
||||
return res.blob();
|
||||
|
||||
case 'json':
|
||||
return res.json();
|
||||
|
||||
default:
|
||||
return res.text();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class fs
|
||||
* @memberof LuCI
|
||||
* @hideconstructor
|
||||
* @classdesc
|
||||
*
|
||||
* Provides high level utilities to wrap file system related RPC calls.
|
||||
* To import the class in views, use `'require fs'`, to import it in
|
||||
* external JavaScript, use `L.require("fs").then(...)`.
|
||||
*/
|
||||
var FileSystem = baseclass.extend(/** @lends LuCI.fs.prototype */ {
|
||||
/**
|
||||
* Obtains a listing of the specified directory.
|
||||
*
|
||||
* @param {string} path
|
||||
* The directory path to list.
|
||||
*
|
||||
* @returns {Promise<LuCI.fs.FileStatEntry[]>}
|
||||
* Returns a promise resolving to an array of stat detail objects or
|
||||
* rejecting with an error stating the failure reason.
|
||||
*/
|
||||
list(path) {
|
||||
return callFileList(path).then(handleRpcReply.bind(this, { entries: [] }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Return file stat information on the specified path.
|
||||
*
|
||||
* @param {string} path
|
||||
* The filesystem path to stat.
|
||||
*
|
||||
* @returns {Promise<LuCI.fs.FileStatEntry>}
|
||||
* Returns a promise resolving to a stat detail object or
|
||||
* rejecting with an error stating the failure reason.
|
||||
*/
|
||||
stat(path) {
|
||||
return callFileStat(path).then(handleRpcReply.bind(this, { '': {} }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Return symlink aware file stat information on the specified path. This
|
||||
* call differs from stat in that it gives information about the symlink
|
||||
* instead of following the symlink, whereby size is the length of the
|
||||
* string of the symlink target path and file name.
|
||||
*
|
||||
* @param {string} path
|
||||
* The filesystem path to lstat.
|
||||
*
|
||||
* @returns {Promise<LuCI.fs.FileStatEntry>}
|
||||
* Returns a promise resolving to a stat detail object or
|
||||
* rejecting with an error stating the failure reason.
|
||||
*/
|
||||
lstat(path) {
|
||||
return callFileLStat(path).then(handleRpcReply.bind(this, { '': {} }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the contents of the given file and return them.
|
||||
* Note: this function is unsuitable for obtaining binary data.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to read.
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
* Returns a promise resolving to a string containing the file contents or
|
||||
* rejecting with an error stating the failure reason.
|
||||
*/
|
||||
read(path) {
|
||||
return callFileRead(path).then(handleRpcReply.bind(this, { data: '' }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Write the given data to the specified file path.
|
||||
* If the specified file path does not exist, it will be created, given
|
||||
* sufficient permissions.
|
||||
*
|
||||
* Note: `data` will be converted to a string using `String(data)` or to
|
||||
* `''` when it is `null`.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to write to.
|
||||
*
|
||||
* @param {*} [data]
|
||||
* The file data to write. If it is null, it will be set to an empty
|
||||
* string.
|
||||
*
|
||||
* @param {number} [mode]
|
||||
* The permissions to use on file creation. Default is 420 (0644).
|
||||
*
|
||||
* @returns {Promise<number>}
|
||||
* Returns a promise resolving to `0` or rejecting with an error stating
|
||||
* the failure reason.
|
||||
*/
|
||||
write(path, data, mode) {
|
||||
data = (data != null) ? String(data) : '';
|
||||
mode = (mode != null) ? mode : 420; // 0644
|
||||
return callFileWrite(path, data, mode).then(handleRpcReply.bind(this, { '': 0 }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Unlink the given file.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to remove.
|
||||
*
|
||||
* @returns {Promise<number>}
|
||||
* Returns a promise resolving to `0` or rejecting with an error stating
|
||||
* the failure reason.
|
||||
*/
|
||||
remove(path) {
|
||||
return callFileRemove(path).then(handleRpcReply.bind(this, { '': 0 }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute the specified command, optionally passing params and
|
||||
* environment variables.
|
||||
*
|
||||
* Note: The `command` must be either the path to an executable,
|
||||
* or a basename without arguments in which case it will be searched
|
||||
* in $PATH. If specified, the values given in `params` will be passed
|
||||
* as arguments to the command.
|
||||
*
|
||||
* The key/value pairs in the optional `env` table are translated to
|
||||
* `setenv()` calls prior to running the command.
|
||||
*
|
||||
* @param {string} command
|
||||
* The command to invoke.
|
||||
*
|
||||
* @param {string[]} [params]
|
||||
* The arguments to pass to the command.
|
||||
*
|
||||
* @param {Object.<string, string>} [env]
|
||||
* Environment variables to set.
|
||||
*
|
||||
* @returns {Promise<LuCI.fs.FileExecResult>}
|
||||
* Returns a promise resolving to an object describing the execution
|
||||
* results or rejecting with an error stating the failure reason.
|
||||
*/
|
||||
exec(command, params, env) {
|
||||
if (!Array.isArray(params))
|
||||
params = null;
|
||||
|
||||
if (!L.isObject(env))
|
||||
env = null;
|
||||
|
||||
return callFileExec(command, params, env).then(handleRpcReply.bind(this, { '': {} }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the contents of the given file, trim leading and trailing white
|
||||
* space and return the trimmed result. In case of errors, return an empty
|
||||
* string instead.
|
||||
*
|
||||
* Note: this function is useful to read single-value files in `/sys`
|
||||
* or `/proc`.
|
||||
*
|
||||
* This function is guaranteed to not reject its promises, on failure,
|
||||
* an empty string will be returned.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to read.
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
* Returns a promise resolving to the file contents or the empty string
|
||||
* on failure.
|
||||
*/
|
||||
trimmed(path) {
|
||||
return L.resolveDefault(this.read(path), '').then(function(s) {
|
||||
return s.trim();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the contents of the given file, split it into lines, trim
|
||||
* leading and trailing white space of each line and return the
|
||||
* resulting array.
|
||||
*
|
||||
* This function is guaranteed to not reject its promises, on failure,
|
||||
* an empty array will be returned.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to read.
|
||||
*
|
||||
* @returns {Promise<string[]>}
|
||||
* Returns a promise resolving to an array containing the stripped lines
|
||||
* of the given file or `[]` on failure.
|
||||
*/
|
||||
lines(path) {
|
||||
return L.resolveDefault(this.read(path), '').then(function(s) {
|
||||
var lines = [];
|
||||
|
||||
s = s.trim();
|
||||
|
||||
if (s != '') {
|
||||
var l = s.split(/\n/);
|
||||
|
||||
for (var i = 0; i < l.length; i++)
|
||||
lines.push(l[i].trim());
|
||||
}
|
||||
|
||||
return lines;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the contents of the given file and return them, bypassing ubus.
|
||||
*
|
||||
* This function will read the requested file through the cgi-io
|
||||
* helper applet at `/cgi-bin/cgi-download` which bypasses the ubus rpc
|
||||
* transport. This is useful to fetch large file contents which might
|
||||
* exceed the ubus message size limits or which contain binary data.
|
||||
*
|
||||
* The cgi-io helper will enforce the same access permission rules as
|
||||
* the ubus based read call.
|
||||
*
|
||||
* @param {string} path
|
||||
* The file path to read.
|
||||
*
|
||||
* @param {"blob"|"text"|"json"} [type=text]
|
||||
* The expected type of read file contents. Valid values are `text` to
|
||||
* interpret the contents as string, `json` to parse the contents as JSON
|
||||
* or `blob` to return the contents as Blob instance.
|
||||
*
|
||||
* @returns {Promise<*>}
|
||||
* Returns a promise resolving with the file contents interpreted according
|
||||
* to the specified type or rejecting with an error stating the failure
|
||||
* reason.
|
||||
*/
|
||||
read_direct(path, type) {
|
||||
var postdata = 'sessionid=%s&path=%s'
|
||||
.format(encodeURIComponent(L.env.sessionid), encodeURIComponent(path));
|
||||
|
||||
return request.post(L.env.cgi_base + '/cgi-download', postdata, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
responseType: (type == 'blob') ? 'blob' : 'text'
|
||||
}).then(handleCgiIoReply.bind({ type: type }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute the specified command, bypassing ubus.
|
||||
*
|
||||
* Note: The `command` must be either the path to an executable,
|
||||
* or a basename without arguments in which case it will be searched
|
||||
* in $PATH. If specified, the values given in `params` will be passed
|
||||
* as arguments to the command.
|
||||
*
|
||||
* This function will invoke the requested commands through the cgi-io
|
||||
* helper applet at `/cgi-bin/cgi-exec` which bypasses the ubus rpc
|
||||
* transport. This is useful to fetch large command outputs which might
|
||||
* exceed the ubus message size limits or which contain binary data.
|
||||
*
|
||||
* The cgi-io helper will enforce the same access permission rules as
|
||||
* the ubus based exec call.
|
||||
*
|
||||
* @param {string} command
|
||||
* The command to invoke.
|
||||
*
|
||||
* @param {string[]} [params]
|
||||
* The arguments to pass to the command.
|
||||
*
|
||||
* @param {"blob"|"text"|"json"} [type=text]
|
||||
* The expected output type of the invoked program. Valid values are
|
||||
* `text` to interpret the output as string, `json` to parse the output
|
||||
* as JSON or `blob` to return the output as Blob instance.
|
||||
*
|
||||
* @param {boolean} [latin1=false]
|
||||
* Whether to encode the command line as Latin1 instead of UTF-8. This
|
||||
* is usually not needed but can be useful for programs that cannot
|
||||
* handle UTF-8 input.
|
||||
*
|
||||
* @param {boolean} [stderr=false]
|
||||
* Whether to include stderr output in command output. This is usually
|
||||
* not needed but can be useful to execute a command and get full output.
|
||||
*
|
||||
* @param {function()} [responseProgress=null]
|
||||
* An optional request callback function which receives ProgressEvent
|
||||
* instances as sole argument during the HTTP response transfer. This is
|
||||
* usually not needed but can be useful to receive realtime command
|
||||
* output before command exit.
|
||||
*
|
||||
* @returns {Promise<*>}
|
||||
* Returns a promise resolving with the command stdout output interpreted
|
||||
* according to the specified type or rejecting with an error stating the
|
||||
* failure reason.
|
||||
*/
|
||||
exec_direct(command, params, type, latin1, stderr, responseProgress) {
|
||||
var cmdstr = String(command)
|
||||
.replace(/\\/g, '\\\\').replace(/(\s)/g, '\\$1');
|
||||
|
||||
if (Array.isArray(params))
|
||||
for (var i = 0; i < params.length; i++)
|
||||
cmdstr += ' ' + String(params[i])
|
||||
.replace(/\\/g, '\\\\').replace(/(\s)/g, '\\$1');
|
||||
|
||||
if (latin1)
|
||||
cmdstr = escape(cmdstr).replace(/\+/g, '%2b');
|
||||
else
|
||||
cmdstr = encodeURIComponent(cmdstr);
|
||||
|
||||
var postdata = 'sessionid=%s&command=%s&stderr=%d'
|
||||
.format(encodeURIComponent(L.env.sessionid), cmdstr, stderr ? 1 : 0);
|
||||
|
||||
return request.post(L.env.cgi_base + '/cgi-exec', postdata, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
responseType: (type == 'blob') ? 'blob' : 'text', responseProgress
|
||||
}).then(handleCgiIoReply.bind({ type: type }));
|
||||
}
|
||||
});
|
||||
|
||||
return FileSystem;
|
||||
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><radialGradient id="radialGradient3390" cx="24.84" cy="30.78" r="23" gradientTransform="matrix(1.156 0 0 .5026 10.03 34.95)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#eeeeec" offset="1"/></radialGradient><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-opacity="0" offset="1"/></radialGradient><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.9Line truncated
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><radialGradient id="radialGradient3390" cx="24.84" cy="30.78" r="23" gradientTransform="matrix(1.156 0 0 .5026 10.03 34.95)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#eeeeec" offset="1"/></radialGradient><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7919" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(1.297 0 0 1.297 -13.6 -.805)" enable-background="new"><rect x="14.5" y="1.5" width="32" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient7887)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path transform="matrix(2.143 0 0 2.087 44.43 -.6302)" d="m-12.5 1.498c-0.573 0-1.002 0Line truncated
|
||||
|
After Width: | Height: | Size: 8.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7822-4"><stop offset="0"/><stop stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient1643253" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><filter id="filter5386-58" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4175"/><linearGradient id="linearGradient4175"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/><linearGradient id="linearGradient7652-3"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient><radialGradient id="radialGradient81" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(1.058 -1.042 .4439 .4509 -55.95 372.2)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618" x="-.1134" y="-.08587" width="1.226" height="1.205"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient85" x1="-75.84" x2="-75.96" y1="48.62" y2="53.84" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="Line truncated
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.779 0 0 2.707 11.17 99.85)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-1" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 -55.24 83.65)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 -51.37 86.57)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient1667502" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2.594 0 0 2.507 9.965 101.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7887"/><linearGradient id="linearGradient1667504" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientTransform="matrix(1.5 0 0 1.5 -51.37 85.07)" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-1-2" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(.5536 0 0 .5536 38.5 -31.69)"><rect x="-27.65" y="102.6" width="41.5" height="37.61" rx="3.731" ry="3.607" fill="url(#lineaLine truncated
|
||||
|
After Width: | Height: | Size: 8.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-opacity="0" offset="1"/></radialGradient><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" strLine truncated
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7919" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(1.297 0 0 1.297 -13.6 -.805)" enable-background="new"><rect x="14.5" y="1.5" width="32" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient7887)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path transform="matrix(2.143 0 0 2.087 44.43 -.6302)" d="m-12.5 1.498c-0.573 0-1.002 0.429-1.002 1.002v11c0 0.573 0.429 1.002 1.002 1.002h12c0.573 0 1.002-0.429 1.002-1.002v-11c0-0.573-0.429-1.002-1.002-1.002z" fill="none" stroke="url(#linearGradient7889)" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-Line truncated
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,2 @@
|
||||
<svg width="48" height="48" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><rect x="11" y="1" width="2" height="5" opacity=".14"/><rect x="11" y="1" width="2" height="5" transform="rotate(30 12 12)" opacity=".29"/><rect x="11" y="1" width="2" height="5" transform="rotate(60 12 12)" opacity=".43"/><rect x="11" y="1" width="2" height="5" transform="rotate(90 12 12)" opacity=".57"/><rect x="11" y="1" width="2" height="5" transform="rotate(120 12 12)" opacity=".71"/><rect x="11" y="1" width="2" height="5" transform="rotate(150 12 12)" opacity=".86"/><rect x="11" y="1" width="2" height="5" transform="rotate(180 12 12)"/><animateTransform attributeName="transform" type="rotate" calcMode="discrete" dur="0.75s" values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12" repeatCount="indefinite"/></g></svg>
|
||||
<!-- https://github.com/n3r4zzurr0/svg-spinners MIT License -->
|
||||
|
After Width: | Height: | Size: 958 B |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7919" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(1.297 0 0 1.297 -13.6 -.805)" enable-background="new"><rect x="14.5" y="1.5" width="32" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient7887)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path transform="matrix(2.143 0 0 2.087 44.43 -.6302)" d="m-12.5 1.498c-0.573 0-1.002 0.429-1.002 1.002v11c0 0.573 0.429 1.002 1.002 1.002h12c0.573 0 1.002-0.429 1.002-1.002v-11c0-0.573-0.429-1.002-1.002-1.002z" fill="none" stroke="url(#linearGradient7889)" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-Line truncated
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7919" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(1.297 0 0 1.297 -13.6 -.805)" enable-background="new"><rect x="14.5" y="1.5" width="32" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient7887)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path transform="matrix(2.143 0 0 2.087 44.43 -.6302)" d="m-12.5 1.498c-0.573 0-1.002 0.429-1.002 1.002v11c0 0.573 0.429 1.002 1.002 1.002h12c0.573 0 1.002-0.429 1.002-1.002v-11c0-0.573-0.429-1.002-1.002-1.002z" fill="none" stroke="url(#linearGradient7889)" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-Line truncated
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-opacity="0" offset="1"/></radialGradient><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#a04030" offset="0"/><stop stop-color="#a04030" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#d06447" offset="0"/><stop stop-color="#d06447" stop-opacity="0" offset="1"/></linearGradient></defs><g transform="matrix(1.297 0 0 1.297 -13.6 -.805)" enable-background="new"><g enable-background="new"><rect x="14.5" y="1.5" width="32" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient7887)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path transform="matrix(2.143 0 0 2.087 44.43 -.6302)" d="m-12.5 1.498c-0.573 0-1.002 0.429-1.002 1.002v11c0 0.573 0.429 1.002 1.002 1.002h12c0.573 0 1.002-0.429 1.002-1.002v-11c0-0.573-0.429-1.002-1.002-1.002z" fill="none" stroke="url(#linearGradient7889)" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924" stroke-width=".4729"/><rect transform="matrix(1.016 0 0 1.016 -.49 -.2715)" x="15.38" y="2.875" width="32" height="29" rx="3.723" ry="3.723" fill-rule="evenodd" filter="url(#filter5386)" opacity=".1205"/></g></g><g transform="matrix(1.785 0 0 1.785 -557 -94.28)" enable-background="new"><path d="m325 59.07c-0.64 0-1.16 0.516-1.16 1.154v0.288c0 0.293-0.23 0.543-0.54 0.543h-0.12c-0.64 0-1.16 0.704-1.16 1.342v5.445c0 0.638 0.52 1.154 1.16 1.154h6.56c0.64 0 1.16-0.516 1.16-1.154v-5.445c0-0.638-0.52-1.342-1.16-1.342h-0.14c-0.26 0.02-0.55-0.186-0.55-0.526v-0.305c0-0.638-0.51-1.154-1.15-1.154z" fill="url(#linearGradient9)" fill-rule="evenodd" stroke="#fff" stroke-width="2"/><path d="m325 59.07c-0.64 0-1.16 0.516-1.16 1.154v0.288c0 0.293-0.23 0.543-0.54 0.543h-0.12c-0.64 0-1.16 0.704-1.16 1.342v5.445c0 0.638 0.52 1.154 1.16 1.154h6.56c0.64 0 1.16-0.516 1.16-1.154v-5.445c0-0.638-0.52-1.342-1.16-1.342h-0.14c-0.26 0.02-0.55-0.186-0.55-0.526v-0.305c0-0.638-0.51-1.154-1.15-1.154z" fill="url(#linearGradient9)" fill-rule="evenodd"/><rect x="325" y="60" width="3" height="2" rx=".3978" ry=".3978" color="#000000" fill="url(#linearGradient11)"/><rect x="323.5" y="62.5" width="6" height="5" rx=".1768" ry=".1768" color="#000000" fill="#d3d7cf" stroke="url(#linearGradient12)"/><rect transform="scale(-1)" x="-328.5" y="-66.5" width="4" height="3" rx=".1768" ry=".1768" color="#000000" fill="#888a85" stroke="url(#linearGradient13)"/><path d="m325 63.81c-1.03 8.083-9.29 14.95-16.38 19.75-3.54 2.401-6.67 4.247-8.53 5.718-0.46 0.368-0.85 0.712-1.18 Line truncated
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-opacity="0" offset="1"/></radialGradient><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" strLine truncated
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v56c0 1.273179-.75249 2.326579-1.84375 2.78125 1.62807Line truncated
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" y1="14" y2="-18"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 Line truncated
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#c" y1="14" y2="-66"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#c" y1="14" y2="-50"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="k" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#d)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#e)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#f)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#g)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#h)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.031Line truncated
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" y1="14" y2="-66"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 Line truncated
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#395d93"/><stop offset="1" stop-color="#6e92c7"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.027772"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.140317"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.010415"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.007812"/><g transform="translate(0 74)"><path d="m74-67.96875c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v11.28125c-1.274027-1.358769-3.036218-2.25-5.03125-2.25h-8c-3.827486 0-6.96875 3.141264-6.96875 6.96875v24c0 3.827486 3.141264 6.96875 6.96875 6.96875h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c2.611074 0 4.807585-1.51241 6-3.65625 1.192415 2.14384 3.388926 3.65625 6 3.65625h8c3.827486 0 6.96875-3.141264 6.96875-6.96875v-72c0-3.827486-3.141264-6.96875-6.96875-6.96875z" opacity=".08"/><path d="m74-66.96875c-3.283091 0-5.96875 2.685659-5.96875 5.96875v72c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-72c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v56c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-56c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v40c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-40c0-3.283091-2.685659-5.96875-5.96875-5.96875zm-20 16c-3.283091 0-5.96875 2.685659-5.96875 5.96875v24c0 3.283091 2.685659 5.96875 5.96875 5.96875h8c3.283091 0 5.96875-2.685659 5.96875-5.96875v-24c0-3.283091-2.685659-5.96875-5.96875-5.96875z" opacity=".1"/><path d="m74-66.03125c-2.763365 0-5.03125 2.267885-5.03125 5.03125v72c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-72c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v56c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-56c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v40c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-40c0-2.763365-2.267885-5.03125-5.03125-5.03125zm-20 16c-2.763365 0-5.03125 2.267885-5.03125 5.03125v24c0 2.763365 2.267885 5.03125 5.03125 5.03125h8c2.763365 0 5.03125-2.267885 5.03125-5.03125v-24c0-2.763365-2.267885-5.03125-5.03125-5.03125z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-72c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v72c0 1.273179-.75249 2.326579-1.84375 2.78125 1.628072-.506247 2.8125-1.982301 2.8125-3.78125v-72c0-2.216-1.784-4-4-4z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.798949 1.184428 3.275003 2.8125 3.78125-1.09126-.454671-1.84375-1.508071-1.84375-2.78125v-56c0-1.697572 1.333678-3.03125 3.03125-3.03125h8c1.697572 0 3.03125 1.333678 3.03125 3.03125v56c0 1.273179-.75249 2.326579-1.84375 2.78125 1.62Line truncated
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32" width="32" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#aaa"/><stop offset="1" stop-color="#f0f0f0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="76" x2="76" xlink:href="#b" y1="14" y2="-66"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="56" x2="56" xlink:href="#b" y1="14" y2="-50"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="44" x2="44" xlink:href="#b" y1="14" y2="-34"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="16" x2="16" xlink:href="#b" y1="14" y2="-18"/><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="78" x2="78" xlink:href="#a" y1="-66" y2="6.028"/><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="19" x2="19" xlink:href="#a" y1="-18" y2="14.14"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="37" x2="37" xlink:href="#a" y1="-34" y2="14.01"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="57" x2="57" xlink:href="#a" y1="-50" y2="14.01"/><g transform="translate(0 74)"><path d="m74-67.97c-3.827 0-6.969 3.141-6.969 6.969v11.28c-1.274-1.359-3.036-2.25-5.031-2.25h-8c-3.827 0-6.969 3.141-6.969 6.969v11.28c-1.274-1.359-3.036-2.25-5.031-2.25h-8c-3.827 0-6.969 3.141-6.969 6.969v11.28c-1.274-1.359-3.036-2.25-5.031-2.25h-8c-3.827 0-6.969 3.141-6.969 6.969v24c0 3.827 3.141 6.969 6.969 6.969h8c2.611 0 4.808-1.512 6-3.656 1.192 2.144 3.389 3.656 6 3.656h8c2.611 0 4.808-1.512 6-3.656 1.192 2.144 3.389 3.656 6 3.656h8c2.611 0 4.808-1.512 6-3.656 1.192 2.144 3.389 3.656 6 3.656h8c3.827 0 6.969-3.141 6.969-6.969v-72c0-3.827-3.141-6.969-6.969-6.969h-8z" opacity=".08"/><path d="m74-66.97c-3.283 0-5.969 2.686-5.969 5.969v72c0 3.283 2.686 5.969 5.969 5.969h8c3.283 0 5.969-2.686 5.969-5.969v-72c0-3.283-2.686-5.969-5.969-5.969zm-20 16c-3.283 0-5.969 2.686-5.969 5.969v56c0 3.283 2.686 5.969 5.969 5.969h8c3.283 0 5.969-2.686 5.969-5.969v-56c0-3.283-2.686-5.969-5.969-5.969zm-20 16c-3.283 0-5.969 2.686-5.969 5.969v40c0 3.283 2.686 5.969 5.969 5.969h8c3.283 0 5.969-2.686 5.969-5.969v-40c0-3.283-2.686-5.969-5.969-5.969zm-20 16c-3.283 0-5.969 2.686-5.969 5.969v24c0 3.283 2.686 5.969 5.969 5.969h8c3.283 0 5.969-2.686 5.969-5.969v-24c0-3.283-2.686-5.969-5.969-5.969z" opacity=".1"/><path d="m74-66.03c-2.763 0-5.031 2.268-5.031 5.031v72c0 2.763 2.268 5.031 5.031 5.031h8c2.763 0 5.031-2.268 5.031-5.031v-72c0-2.763-2.268-5.031-5.031-5.031zm-20 16c-2.763 0-5.031 2.268-5.031 5.031v56c0 2.763 2.268 5.031 5.031 5.031h8c2.763 0 5.031-2.268 5.031-5.031v-56c0-2.763-2.268-5.031-5.031-5.031zm-20 16c-2.763 0-5.031 2.268-5.031 5.031v40c0 2.763 2.268 5.031 5.031 5.031h8c2.763 0 5.031-2.268 5.031-5.031v-40c0-2.763-2.268-5.031-5.031-5.031zm-20 16c-2.763 0-5.031 2.268-5.031 5.031v24c0 2.763 2.268 5.031 5.031 5.031h8c2.763 0 5.031-2.268 5.031-5.031v-24c0-2.763-2.268-5.031-5.031-5.031z" opacity=".15"/><path d="m74-65c-2.216 0-4 1.784-4 4v72c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-72c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v56c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-56c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v40c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-40c0-2.216-1.784-4-4-4zm-20 16c-2.216 0-4 1.784-4 4v24c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-24c0-2.216-1.784-4-4-4z" opacity=".3"/><rect fill="url(#c)" height="80" rx="4" width="16" x="70" y="-66"/><rect fill="url(#d)" height="64" rx="4" width="16" x="50" y="-50"/><rect fill="url(#e)" height="48" rx="4" width="16" x="30" y="-34"/><rect fill="url(#f)" height="32" rx="4" width="16" x="10" y="-18"/><path d="m74-66c-2.216 0-4 1.784-4 4v72c0 1.799 1.184 3.275 2.812 3.781-1.091-.4547-1.844-1.508-1.844-2.781v-72c0-1.698 1.334-3.031 3.031-3.031h8c1.698 0 3.031 1.334 3.031 3.031v72c0 1.273-.7525 2.327-1.844 2.781 1.628-.5062 2.812-1.982 2.812-3.781v-72c0-2.216-1.784-4-4-4h-8z" fill="url(#g)" opacity=".6"/><path d="m54-50c-2.216 0-4 1.784-4 4v56c0 1.799 1.184 3.275 2.812 3.781-1.091-.4547-1.844-1.508-1.844-2.781v-56c0-1.698 1.334-3.031 3.031-3.031h8c1.698 0 3.031 1.334 3.031 3.031v56c0 1.273-.7525 2.327-1.844 2.781 1.628-.5062 2.812-1.982 2.812-3.781v-56c0-2.216-1.784-4-4-4h-8z" fill="url(#j)" opacity=".6"/><path d="m34-34c-2.216 0-4 1.784-4 4v40c0 1.799 1.184 3.275 2.812 3.781-1.091-.4547-1.844-1.508-1.844-2.781v-40c0-1.698 1.334-3.031 3.031-3.031h8c1.698 0 3.031 1.334 3.031 3.031v40c0 1.273-.7525 2.327-1.844 2.781 1.628-.5062 2.812-1.982 2.812-3.781v-40c0-2.216-1.784-4-4-4h-8z" fill="url(#i)" opacity=".6"/><path d="m14-18c-2.216 0-4 1.784-4 4v24c0 1.799 1.184 3.275 2.812 3.781-1.091-.4547-1.844-1.508-1.844-2.781v-24c0-1.698 1.334-3.031 3.031-3.031h8c1.698 0 3.031 1.334 3.031 3.031v24c0 1.273-.7525 2.327-1.844 2.781 1.628-.5062 2.812-1.982 2.812-3.781v-24c0-2.216-1.784-4-4-4h-8z" fill="url(#h)" opacity=".6"/><path d="m41.5-36.18c-3.9Line truncated
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient565184-2-0" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient565186-6-5" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient565196-0-2" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7422"/><linearGradient id="linearGradient576026-2" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.98 -63.51)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient576028-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.143 0 0 2.087 44.91 -64.67)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-64-0" x="-.008195" y="-.02176" width="1.016" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-opacity="0" offset="1"/></radialGradient><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152Line truncated
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient565184-2" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient565186-6" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient565196-0" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7422"/><linearGradient id="linearGradient576026-2" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.98 -63.51)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient576028-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.143 0 0 2.087 44.91 -64.67)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-64-0" x="-.008195" y="-.02176" width="1.016" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g opacity=".7"><g transform="matrix(.5923 0 0 .5923 -7.406 54.4)" enable-background="new"><rect x="14.98" y="-62.54" width="77" height="29" rx="2.877" ry="2.781" fill="url(#linearGradient576026-2)" fill-rule="evenodd" stroke="#888a85" stroke-dashoffset=".7" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".9924"/><path d="m18.12-61.5Line truncated
|
||||
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7822-4"><stop offset="0"/><stop stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7652-3"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient1643253" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><filter id="filter10631-9-19" x="-.0544" y="-.09756" width="1.109" height="1.195"><feGaussianBlur stdDeviation="0.5906498"/></filter><radialGradient id="radialGradient8346" cx="18.25" cy="15.72" r="29.99" gradientTransform="matrix(.4532 0 0 .452 115.9 33.56)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3e9ff" offset="0"/><stop stop-color="#f3f9ff" offset=".1552"/><stop stop-color="#376497" offset=".6311"/><stop stop-color="#273e5d" offset=".8155"/><stop stop-color="#526ea5" offset="1"/></radialGradient><linearGradient id="linearGradient8348" x1="145.2" x2="144.4" y1="-41.41" y2="46.08" gradientTransform="matrix(.08489 0 0 .08523 116.4 34.32)" gradientUnits="userSpaceOnUse"><stop stop-color="#acc5ed" offset="0"/><stop stop-color="#193b6e" offset="1"/></linearGradient><radialGradient id="radialGradient8350" cx="24.88" cy="23" r="19.19" gradientTransform="matrix(1 0 0 .9316 0 1.573)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><radialGradient id="radialGradient8380" cx="24.88" cy="23" r="19.19" gradientTransform="matrix(1 0 0 .9316 .6567 2.136)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><radialGradient id="radialGradient8410" cx="23.93" cy="14.66" r="19.19" gradientTransform="matrix(1.7 0 0 1.584 -16.91 -7.702)" gradientUnits="userSpaceOnUse"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".4992"/><stop stop-color="#9a9a8d" offset=".7619"/><stop stop-color="#fff" offset="1"/></radialGradient><radialGradient id="radialGradient8412" cx="24.14" cy="14.21" r="19.19" gradientTransform="matrix(1.7 0 0 1.584 -16.91 -7.702)" gradientUnits="userSpaceOnUse"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".381"/><stop stop-color="#c5c5be" offset=".7619"/><stop stop-color="#fff" offset="1"/></radialGradient><radialGradient id="radialGradient8440" cx="24.74" cy="17.35" r="19.19" gradientTransform="matrix(1.381 0 0 1.286 -9.42 -3.294)" gradientUnits="userSpaceOnUse"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".538"/><stop stop-color="#97978a" offset=".8543"/><stop stop-color="#fff" offset="1"/></radialGradient><radialGradient id="radialGradient8470" cx="77.56" cy="152.5" r="13.03" gradientTransform="matrix(1.963 0 0 1.094 -74.66 -21.12)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><filter id="filter5386-2" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient6175" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/><linearGradient id="linearGradient6239" x1="22.69" x2="27.97" y1="11.85" y2="11.85" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4175"/><linearGradient id="linearGradient4175"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradienLine truncated
|
||||
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient36138"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7822-4"><stop offset="0"/><stop stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient5911-7-1"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".381"/><stop stop-color="#c5c5be" offset=".7619"/><stop stop-color="#fff" offset="1"/></linearGradient><filter id="filter10631-9-19-8" x="-.05439" y="-.09755" width="1.109" height="1.195"><feGaussianBlur stdDeviation="0.5906498"/></filter><radialGradient id="radialGradient8346-8" cx="18.25" cy="15.72" r="29.99" gradientTransform="matrix(.43 0 0 .4288 2.023 23.88)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#eeeeec" offset=".1552"/><stop stop-color="#eeeeec" offset=".6311"/><stop stop-color="#babdb6" offset=".8155"/><stop stop-color="#888a85" offset="1"/></radialGradient><radialGradient id="radialGradient8350-2" cx="24.88" cy="23" r="19.19" gradientTransform="matrix(.4286 0 0 .3992 16.53 89.55)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><radialGradient id="radialGradient8380-4" cx="24.88" cy="23" r="19.19" gradientTransform="matrix(.4286 0 0 .3992 16.81 89.8)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><radialGradient id="radialGradient8410-6" cx="23.93" cy="14.66" r="19.19" gradientTransform="matrix(.7542 0 0 .7024 8.717 84.97)" gradientUnits="userSpaceOnUse"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".4992"/><stop stop-color="#9a9a8d" offset=".7619"/><stop stop-color="#fff" offset="1"/></radialGradient><radialGradient id="radialGradient8416-0" cx="24.14" cy="14.21" r="19.19" gradientTransform="matrix(.7542 0 0 .7024 8.717 84.97)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5911-7-1"/><radialGradient id="radialGradient8440-0" cx="24.74" cy="17.35" r="19.19" gradientTransform="matrix(.6124 0 0 .5703 12.04 86.93)" gradientUnits="userSpaceOnUse"><stop stop-color="#f6f6f5" offset="0"/><stop stop-color="#ecece9" offset=".538"/><stop stop-color="#97978a" offset=".8543"/><stop stop-color="#fff" offset="1"/></radialGradient><radialGradient id="radialGradient8470-2" cx="77.56" cy="152.5" r="13.03" gradientTransform="matrix(1.963 0 0 1.094 -74.66 -21.12)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></radialGradient><linearGradient id="linearGradient3387"><stop stop-color="#8f9388" offset="0"/><stop stop-color="#c6cac2" offset=".5"/><stop stop-color="#d3d7cf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient32908" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3387"/><linearGradient id="linearGradient36140" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><linearGradient id="linearGradient36952" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><filter id="filter5386-65" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><filter id="filter5386-2-2" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient2128329" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(.903 0 0 .9021 36.25 -116.5)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient2128331" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(.8304 0 0 .8304 38.39 -114.9)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><linearGradient id="linearGradient2128333" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientTransform="matrix(.8304 0 0 .8304 38.39 -115.7)" gradientUnits="userSpaceOnULine truncated
|
||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient565184-2" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient565186-6" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient565196-0" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7422"/><linearGradient id="linearGradient576026-2" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.98 -63.51)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient576028-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.143 0 0 2.087 44.91 -64.67)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-64-0" x="-.008195" y="-.02176" width="1.016" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient12756"><stop stop-color="#5789ca" offset="0"/><stop stop-color="#023c88" offset="1"/></linearGradient><linearGradient id="linearGradient8813" x1="88" x2="178" y1="44.5" y2="202.5" gradientTransform="matrix(.04808 0 0 .04032 303.9 219.1)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient11544" x1="110.5" x2="110.5" y1="406.4" y2="381.4" gradientUnits="userSpaceOnUse"><stop stop-color="#4b4d49" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11542" x1="169.5" x2="169.5" y1="406.3" y2="381.7" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#d3d7cf" offset="1"/></linearGradient><linearGradient id="linearGradient3830" x1="306.6" x2="306.6" y1="233.9" y2="232.7" gradientTransform="matrix(.7656 0 0 .7656 786.1 -36.93)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><filter id="filter10920" x="-.2043" y="-.379" width="1.41" height="1.811" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.5435346"/></filter><linearGradient id="linearGradient3880" x1="306.6" x2="306.6" y1="233.9" y2="232.7" gradientTransform="matrix(.7656 0 0 .7656 779.2 -36.93)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><radialGradient id="radialGradient3908" cx="326" cy="58" r="12.5" gradientTransform="matrix(-.5241 2.303e-7 .02554 -.3735 476.1 243.7)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><radialGradient id="radialGradient3906" cx="327.5" cy="58" r="12.5" gradientTransform="matrix(2.031 1.561e-8 0 .3864 -353.1 199.6)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient3900" x1="317.3" x2="298.3" y1="86.37" y2="-18.47" gradientTransform="matrix(.2223 0 0 .2385 239.4 207.3)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5538"/><radialGradient id="radialGradient3898" cx="314.2" cy="56.92" r="23" gradientTransform="matrix(.2107 .7334 -.2821 .08108 259.3 -13.83)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8702"/><linearGradient id="linearGradient3712" x1="316.2" x2="316.2" y1="83.21" y2="92.05" gradientTransform="matrix(.248 0 0 .4 231.7 197.2)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient3698" x1="317.9" x2="298.3" y1="92.35" y2="-18.47" gradientTransform="matrix(.2904 0 0 .3002 218 204.1)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5538"/><radialGradient id="radialGradient3696" cx="314.2" cy="56.92" r="23" gradientTransform="matrix(.2753 .9228 -.3686 .102 244.1 -74.18)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8702"/><linearGradient id="linearGradient3694" x1="307.7" x2="307.7" y1="229.2" y2="230.5" gradientTransform="translate(0,1)" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#555753Line truncated
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient3983"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient565184-2" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 98.35 78.44)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient565186-6" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 102.2 81.36)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient565196-0" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7422"/><linearGradient id="linearGradient576026-2" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.98 -63.51)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient576028-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.143 0 0 2.087 44.91 -64.67)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-64-0" x="-.008195" y="-.02176" width="1.016" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient11596"><stop stop-color="#fff" offset="0"/><stop offset="1"/></linearGradient><linearGradient id="linearGradient8813" x1="88" x2="178" y1="44.5" y2="202.5" gradientTransform="matrix(.04808 0 0 .04032 303.9 219.1)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient11544" x1="110.5" x2="110.5" y1="406.4" y2="381.4" gradientUnits="userSpaceOnUse"><stop stop-color="#4b4d49" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11542" x1="169.5" x2="169.5" y1="406.3" y2="381.7" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#d3d7cf" offset="1"/></linearGradient><linearGradient id="linearGradient3830" x1="306.6" x2="306.6" y1="233.9" y2="232.7" gradientTransform="matrix(.7656 0 0 .7656 786.1 -36.93)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><filter id="filter10920" x="-.2043" y="-.379" width="1.41" height="1.811" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.5435346"/></filter><linearGradient id="linearGradient3880" x1="306.6" x2="306.6" y1="233.9" y2="232.7" gradientTransform="matrix(.7656 0 0 .7656 779.2 -36.93)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3983"/><radialGradient id="radialGradient3908" cx="326" cy="58" r="12.5" gradientTransform="matrix(-.5241 2.303e-7 .02554 -.3735 476.1 243.7)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><radialGradient id="radialGradient3906" cx="327.5" cy="58" r="12.5" gradientTransform="matrix(2.031 1.561e-8 0 .3864 -353.1 199.6)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient3900" x1="317.3" x2="298.3" y1="86.37" y2="-18.47" gradientTransform="matrix(.1702 0 0 .2029 963.2 123.1)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5538"/><radialGradient id="radialGradient3898" cx="314.2" cy="56.92" r="23" gradientTransform="matrix(.1613 .6239 -.216 .06897 986.9 -65.02)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8702"/><radialGradient id="radialGradient3926" cx="314.2" cy="56.92" r="23" gradientTransform="matrix(.1613 .6239 -.216 .06897 978.5 -65.02)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8702"/><linearGradient id="linearGradient3712" x1="316.2" x2="316.2" y1="83.21" y2="92.05" gradientTransform="matrix(.1899 0 0 .3063 961.2 118.6)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient3698" x1="317.9" x2="298.3" y1="92.35" y2="-18.47" gradientTransform="matrix(.2223 0 0 .2298 950.8 124)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5538"/><radialGradient id="radialGradient3696" cx="314.2" cy="56.92" r="23" gradientTransform="matrix(.2108 .7066 -.2822 .07812 970.7 -89.13)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8702"/><linearGradient id="linearGradienLine truncated
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7822-4"><stop offset="0"/><stop stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient1643253" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><filter id="filter5386-58" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient9" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient11" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612-0" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618-7" x="-.07545" y="-.06204" width="1.151" height="1.143"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient12" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient13" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient14" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/><linearGradient id="linearGradient7652-3"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient15" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient><radialGradient id="radialGradient81" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(1.058 -1.042 .4439 .4509 -55.95 372.2)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618" x="-.1134" y="-.08588" width="1.226" height="1.205"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient85" x1="-75.84" x2="-75.96" y1="48.62" y2="53.84" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.Line truncated
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889-6" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientTransform="matrix(2.779 0 0 2.707 11.17 99.85)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-1" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7907" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(1.631 0 0 1.63 -55.24 83.65)" gradientUnits="userSpaceOnUse"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient7909" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(1.5 0 0 1.5 -51.37 86.57)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient1667502" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2.594 0 0 2.507 9.965 101.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7887"/><linearGradient id="linearGradient1667504" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientTransform="matrix(1.5 0 0 1.5 -51.37 85.07)" gradientUnits="userSpaceOnUse"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><filter id="filter5386-1-2" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.913 0.83-5.293 1.22-6.473 1.13 0.62-0.95 2.3-2.56 4.16-4.1 3.721-3.08 7.969-6.37 7.969-6.37z"/></clipPath><mask id="B" maskUnits="userSpaceOnUse"><rect x="-115.6" y="147" width="51.28" height="17.34" rx=".6657" fill="url(#C)" fill-rule="evenodd" stroke-width="2"/></mask><linearGradient id="C" x1="-112.3" x2="-112.3" y1="148.9" y2="164.5" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop stop-color="#fff" offset=".2177"/><stop stop-color="#fff" offset=".7659"/><stop offset="1"/></linearGradient><filter id="D" x="-.0125" y="-.04971" width="1.026" height="1.099" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.001 0.244"/></filter><filter id="H" x="-.395" y="-.5737" width="1.79" height="2.147" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="2.8946329"/></filter><g transform="matrix(.01359 0 0 .01359 12.37 35.5)" fill="#999" stroke-width="75"><path d="m-328.5-519h-150v150h150z"/><path d="m-328.5-219h-150v150h150z"/><patLine truncated
|
||||
|
After Width: | Height: | Size: 9.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32.011" viewBox="0 0 24.892 32.011" width="24.892" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="10.28" cy="8.071" gradientTransform="matrix(1 0 0 .8274 0 1.122)" gradientUnits="userSpaceOnUse" r="4.525" xlink:href="#e"/><radialGradient id="b" cx="10.28" cy="9.842" gradientTransform="matrix(4.681 0 0 1.277 -37.84 -3.301)" gradientUnits="userSpaceOnUse" r="4.525" xlink:href="#g"/><radialGradient id="c" cx="10.74" cy="19.5" gradientTransform="matrix(1 0 0 .3026 0 13.6)" gradientUnits="userSpaceOnUse" r="8.263" xlink:href="#d"/><linearGradient id="d"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#729fcf"/><stop offset="1" stop-color="#729fcf" stop-opacity="0"/></linearGradient><radialGradient id="f" cx="10.28" cy="10.02" gradientTransform="matrix(4.681 0 0 1.277 -37.84 -3.301)" gradientUnits="userSpaceOnUse" r="4.525" xlink:href="#g"/><linearGradient id="g"><stop offset="0" stop-color="#3465a4"/><stop offset="1" stop-color="#3465a4" stop-opacity="0"/></linearGradient><linearGradient id="h" gradientUnits="userSpaceOnUse" x1="11.22" x2="11.22" xlink:href="#d" y1="43.14" y2="23.04"/><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="24.84" x2="21.04" y1="44.53" y2="21.04"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="39.07" x2="39.42" y1="28.5" y2="10.94"><stop offset="0" stop-color="#888a85"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="k" cx="10.28" cy="7.825" gradientTransform="matrix(.6984 0 0 .5779 3.1 2.744)" gradientUnits="userSpaceOnUse" r="4.525" xlink:href="#e"/><radialGradient id="l" cx="8.906" cy="1.729" gradientTransform="matrix(.7375 0 0 .7202 2.434 .6617)" gradientUnits="userSpaceOnUse" r="1.995"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d3d7cf"/></radialGradient><radialGradient id="m" cx="8.305" cy="1.126" gradientTransform="matrix(1.86 0 0 1.817 -7.14 -.8942)" gradientUnits="userSpaceOnUse" r="2.051"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><g enable-background="new" transform="matrix(.6237 0 0 .6237 -2.5201 3.0118)"><ellipse cx="10.74" cy="19.5" fill="url(#c)" opacity=".1" rx="8.263" ry="2.5" stroke-linecap="round" stroke-linejoin="round" transform="matrix(2.305 0 0 2.378 -1.198 -5.82)"/><ellipse cx="10.28" cy="6.5" rx="4.281" ry="3.5" style="opacity:.6;stroke-width:.1997;stroke-linecap:round;stroke-linejoin:round;fill:url(#a);stroke:url(#f)" transform="matrix(4.555 0 0 5.507 -22.83 -20.8)"/><path d="m24 12.55a.4507.4507 0 0 0 -.4.244l-16 31a.4507.4507 0 0 0 .4004.658h3.4996a.4507.4507 0 0 0 .406-.256l2.416-5.007 21.06 3.531.711 1.476a.4507.4507 0 0 0 .406.256h3.5a.4507.4507 0 0 0 .4-.658l-16-31a.4507.4507 0 0 0 -.4-.244zm0 6.465 3.172 6.619-5.627-1.463zm-3.756 7.826 5.738 1.478-8.398 4.088zm9.201 3.545 3.864 8.027-15.18-2.531z" fill="url(#h)" fill-rule="evenodd" opacity=".153" transform="matrix(1 0 0 .4005 0 26.14)"/><ellipse cx="10.28" cy="6.5" rx="4.281" ry="3.5" style="opacity:.8;stroke-width:.2685;stroke-linecap:round;stroke-linejoin:round;stroke:url(#b);fill:url(#a)" transform="matrix(3.387 0 0 4.094 -10.82 -11.61)"/><g transform="translate(0 -.5)"><path d="m24 13-16 31h3.5l2.563-5.312 21.62 3.625.812 1.687h3.5zm0 4.969 4 8.343-7.094-1.843zm-4 8.343 7.281 1.875-10.66 5.188zm9.656 3.469 4.438 9.219-17.44-2.906z" fill="url(#i)" fill-rule="evenodd" stroke="url(#j)"/><g fill="none" stroke="#fff" stroke-linecap="round"><path d="m38.41 43.03-14.41-27.91-14.41 27.91"/><path d="m15.78 34.91 13.03-6.344"/><path d="m15.09 36.84 19.66 3.281"/></g></g><g stroke-linecap="round" stroke-linejoin="round"><ellipse cx="10.28" cy="6.5" fill="url(#k)" rx="4.281" ry="3.5" stroke="url(#b)" stroke-width=".4075" transform="matrix(2.219 0 0 2.714 1.186 -2.643)"/><g transform="matrix(2.24 0 0 2.23 -19.68 9.389)"><ellipse cx="9.203" cy="2.25" fill="url(#l)" rx="1.797" ry="1.75" stroke="#555753" stroke-width=".3967" transform="matrix(1.113 0 0 1.143 9.256 -.07143)"/><circle cx="18.874" cy="1.7892" fill="#fff" r=".906" stroke-width="1.812"/></g><ellipse cx="9.203" cy="2.25" fill="none" rx="1.797" ry="1.75" stroke="url(#m)" stroke-width=".5078" transform="matrix(1.948 0 0 1.991 6.074 10.48)"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg height="32.011" viewBox="0 0 24.892 32.011" width="24.892" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="10.74" cy="19.5" gradientTransform="matrix(1 0 0 .3026 0 13.6)" gradientUnits="userSpaceOnUse" r="8.263" xlink:href="#b"/><linearGradient id="b"><stop offset="0"/><stop offset="1" stop-opacity="0"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="11.22" x2="11.22" xlink:href="#b" y1="43.14" y2="23.04"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="24.84" x2="21.04" y1="44.53" y2="21.04"><stop offset="0" stop-color="#babdb6"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="39.07" x2="39.42" y1="28.5" y2="10.94"><stop offset="0" stop-color="#888a85"/><stop offset="1" stop-color="#555753"/></linearGradient><radialGradient id="f" cx="8.906" cy="1.729" gradientTransform="matrix(.7375 0 0 .7202 2.434 .6617)" gradientUnits="userSpaceOnUse" r="1.995"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#d3d7cf"/></radialGradient><radialGradient id="g" cx="8.305" cy="1.126" gradientTransform="matrix(1.86 0 0 1.817 -7.14 -.8942)" gradientUnits="userSpaceOnUse" r="2.051"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><g enable-background="new" transform="matrix(.6237 0 0 .6237 -2.5201 3.0118)"><ellipse cx="10.74" cy="19.5" fill="url(#a)" opacity=".1" rx="8.263" ry="2.5" stroke-linecap="round" stroke-linejoin="round" transform="matrix(2.305 0 0 2.378 -1.198 -5.82)"/><path d="m24 12.55a.4507.4507 0 0 0 -.4.244l-16 31a.4507.4507 0 0 0 .4004.658h3.4996a.4507.4507 0 0 0 .406-.256l2.416-5.007 21.06 3.531.711 1.476a.4507.4507 0 0 0 .406.256h3.5a.4507.4507 0 0 0 .4-.658l-16-31a.4507.4507 0 0 0 -.4-.244zm0 6.465 3.172 6.619-5.627-1.463zm-3.756 7.826 5.738 1.478-8.398 4.088zm9.201 3.545 3.864 8.027-15.18-2.531z" fill="url(#c)" fill-rule="evenodd" opacity=".153" transform="matrix(1 0 0 .4005 0 26.14)"/><g transform="translate(0 -.5)"><path d="m24 13-16 31h3.5l2.563-5.312 21.62 3.625.812 1.687h3.5zm0 4.969 4 8.343-7.094-1.843zm-4 8.343 7.281 1.875-10.66 5.188zm9.656 3.469 4.438 9.219-17.44-2.906z" fill="url(#d)" fill-rule="evenodd" stroke="url(#e)"/><g fill="none" stroke="#fff" stroke-linecap="round"><path d="m38.41 43.03-14.41-27.91-14.41 27.91"/><path d="m15.78 34.91 13.03-6.344"/><path d="m15.09 36.84 19.66 3.281"/></g></g><g stroke-linecap="round" stroke-linejoin="round"><g transform="matrix(2.24 0 0 2.23 -19.68 9.389)"><ellipse cx="9.203" cy="2.25" fill="url(#f)" rx="1.797" ry="1.75" stroke="#555753" stroke-width=".3967" transform="matrix(1.113 0 0 1.143 9.256 -.07143)"/><circle cx="18.874" cy="1.7892" fill="#fff" r=".906" stroke-width="1.812"/></g><ellipse cx="9.203" cy="2.25" fill="none" rx="1.797" ry="1.75" stroke="url(#g)" stroke-width=".5078" transform="matrix(1.948 0 0 1.991 6.074 10.48)"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient7822-4"><stop offset="0"/><stop stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient4598"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7652-3"><stop stop-color="#729fcf" offset="0"/><stop stop-color="#729fcf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient6175" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/><linearGradient id="linearGradient6239" x1="22.69" x2="27.97" y1="11.85" y2="11.85" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><filter id="filter4684" x="-.09275" y="-.106" width="1.186" height="1.212"><feGaussianBlur stdDeviation="0.71917802"/></filter><linearGradient id="linearGradient3278" x1="-6.411" x2="-10.07" y1="25.76" y2="1.873" gradientTransform="matrix(1.5 0 0 1.4 336.2 52.8)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient6991"/><linearGradient id="linearGradient6991"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient4307" x1="25.05" x2="27.76" y1="16.17" y2="24.54" gradientTransform="matrix(1.088 0 0 1.086 294.4 40.06)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7340-2"/><linearGradient id="linearGradient7340-2"><stop stop-color="#555753" offset="0"/><stop stop-color="#888a85" offset="1"/></linearGradient><linearGradient id="linearGradient4182" x1="326.5" x2="326.5" y1="61.7" y2="60.69" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4175"/><linearGradient id="linearGradient4175"><stop stop-color="#babdb6" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><radialGradient id="radialGradient4612" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(2.238 -.5404 .1485 .615 -392 204.4)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><filter id="filter4618" x="-.1134" y="-.08587" width="1.226" height="1.205"><feGaussianBlur stdDeviation="0.89652215"/></filter><linearGradient id="linearGradient4212" x1="322.3" x2="328.4" y1="62.62" y2="68.74" gradientTransform="matrix(.75 0 0 .8333 81.62 10.42)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4206"><stop stop-color="#fff" offset="0"/><stop stop-color="#babdb6" offset="1"/></linearGradient><linearGradient id="linearGradient4231" x1="325.4" x2="328.4" y1="63.27" y2="68.74" gradientTransform="matrix(.5 0 0 .5 -489.8 -97.75)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4206"/><linearGradient id="linearGradient4380" x1="320" x2="330.2" y1="60.75" y2="87.75" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4598"/><linearGradient id="linearGradient3248-0" x1="-47.16" x2="-46.15" y1="39.38" y2="44.17" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/><linearGradient id="linearGradient3250-1" x1="-48" x2="-46.75" y1="40.38" y2="45.69" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse"><stop stop-color="#3465a4" offset="0"/><stop stop-color="#3465a4" stop-opacity="0" offset="1"/></linearGradient><radialGradient id="radialGradient81" cx="306.5" cy="86.38" r="21.91" gradientTransform="matrix(1.058 -1.042 .4439 .4509 -55.95 372.2)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7822-4"/><linearGradient id="linearGradient85" x1="-75.84" x2="-75.96" y1="48.62" y2="53.84" gradientTransform="translate(386,50)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7652-3"/></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter Line truncated
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="linearGradient36138"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient7887" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse"><stop stop-color="#d3d7cf" offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient7889" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient5940"><stop stop-color="#2e3436" offset="0"/><stop stop-color="#555753" offset="1"/></linearGradient><linearGradient id="linearGradient3387"><stop stop-color="#8f9388" offset="0"/><stop stop-color="#c6cac2" offset=".5"/><stop stop-color="#d3d7cf" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient32908" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient3387"/><linearGradient id="linearGradient36140" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><linearGradient id="linearGradient36952" x1="22.36" x2="28.25" y1="11.89" y2="11.89" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><filter id="filter5386-65" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><filter id="filter5386-2-2" x="-.01972" y="-.02176" width="1.039" height="1.044" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="0.26293105"/></filter><linearGradient id="linearGradient7422"><stop stop-color="#edd400" offset="0"/><stop stop-color="#edd400" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="linearGradient2128329" x1="32.81" x2="32.81" y1="21" y2="26.2" gradientTransform="matrix(.903 0 0 .9021 36.25 -116.5)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient5940"/><linearGradient id="linearGradient2128331" x1="28.88" x2="29" y1="29" y2="16" gradientTransform="matrix(.8304 0 0 .8304 38.39 -114.9)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient36138"/><linearGradient id="linearGradient2128333" x1="30.31" x2="30.31" y1="27.31" y2="24.69" gradientTransform="matrix(.8304 0 0 .8304 38.39 -115.7)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7422"/><linearGradient id="linearGradient50053" x1="-7.975" x2="-11.01" y1="25.36" y2="-6.568" gradientTransform="matrix(2 0 0 1.933 43.5 .5333)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7887"/><linearGradient id="linearGradient50055" x1="-7.852" x2="-5.51" y1="3.755" y2="18.94" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient7889"/></defs><clipPath id="b"><rect x="68.78" y="-.0933" width="58.26" height="58.26" rx="2.648"/></clipPath><filter id="c" x="-.021" y="-.021" width="1.042" height="1.042" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".28282197"/></filter><clipPath id="h"><path d="m-6.562 24.53c-0.3877 0-0.6917 0.219-0.9062 0.469l-0.031-0.03-0.031 0.06-0.3438 0.313-4.25 1.218c-0.03 0-0.06 0.02-0.09 0.03-0.549 0.274-0.902 0.554-1.094 0.937-0.192 0.384-0.116 0.867 0.125 1.156 0.329 0.394 0.858 0.553 1.407 0.657l-0.407 0.437c-0.06 0.05-0.1 0.116-0.125 0.188-0.03 0.121-0.07 0.316-0.125 0.5-0.02 0.04-0.03 0.08-0.03 0.125v6.656c0 0.299 0.113 0.582 0.313 0.813 0.199 0.23 0.511 0.406 0.875 0.406h7.843c0.3236 0 0.6569-0.116 0.9063-0.375l4.651-4.81c0.2259-0.235 0.3437-0.539 0.3437-0.875v-6.625c0-0.335-0.1178-0.64-0.3437-0.875-0.2227-0.229-0.5504-0.375-0.874-0.375z"/></clipPath><filter id="i" x="-.03844" y="-.04352" width="1.077" height="1.087" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".1491362"/></filter><filter id="p" x="-.02026" y="-.02354" width="1.04" height="1.047" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".071069152"/></filter><filter id="x" x="-.03625" y="-.04222" width="1.071" height="1.083" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation=".16679387"/></filter><clipPath id="A"><path d="m-95.3 143.8s-4.189 3.27-8.1 6.5c-1.95 1.62-3.69 3.22-4.72 4.78-0.51 0.78-0.98 1.62-0.65 2.78 0.16 0.58 0.61 1.12 1.09 1.41 0.48 0.28 0.96 0.4 1.5 0.47 2.13 0.24 4.73-0.4 7.849-1.28 3.113-0.89 6.669-2.09 10.25-3.25 3.581-1.17 7.196-2.31 10.34-3 3.147-0.7 5.835-0.89 7.375-0.5 0.729 0.18 0.745 0.3 0.75 0.31 0 0 0.06 0.33-0.219 0.94-0.567 1.2-2.245 3.11-4.187 4.93-3.885 3.64-8.844 7.13-8.844 7.13l1.75 2.44s5.041-3.52 9.156-7.38c2.058-1.93 3.879-3.89 4.813-5.87 0.466-1 0.776-2.12 0.343-3.25-0.433-1.14-1.541-1.87-2.812-2.19-2.46-0.62-5.444-0.21-8.781 0.53-3.337 0.73-7.019 1.85-10.62 3.03-3.607 1.18-7.129 2.4-10.12 3.25-2.Line truncated
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
'require form';
|
||||
'require network';
|
||||
|
||||
var callFileRead = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'read',
|
||||
params: [ 'path' ],
|
||||
expect: { data: '' },
|
||||
filter: function(value) { return value.trim() }
|
||||
});
|
||||
|
||||
return network.registerProtocol('dhcp', {
|
||||
getI18n: function() {
|
||||
return _('DHCP client');
|
||||
},
|
||||
|
||||
renderFormOptions: function(s) {
|
||||
var o;
|
||||
|
||||
o = s.taboption('general', form.Value, 'hostname', _('Hostname to send when requesting DHCP'));
|
||||
o.default = '';
|
||||
o.value('', _('Send the hostname of this device'));
|
||||
o.value('*', _('Do not send a hostname'));
|
||||
o.datatype = 'or(hostname, "*")';
|
||||
o.load = function(section_id) {
|
||||
return callFileRead('/proc/sys/kernel/hostname').then(L.bind(function(hostname) {
|
||||
this.placeholder = hostname;
|
||||
return form.Value.prototype.load.apply(this, [section_id]);
|
||||
}, this));
|
||||
};
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'broadcast', _('Use broadcast flag'), _('Required for certain ISPs, e.g. Charter with DOCSIS 3'));
|
||||
o.default = o.disabled;
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'clientid', _('Client ID to send when requesting DHCP'));
|
||||
o.datatype = 'hexstring';
|
||||
|
||||
s.taboption('advanced', form.Value, 'vendorid', _('Vendor Class to send when requesting DHCP'));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
'require network';
|
||||
|
||||
return network.registerProtocol('none', {
|
||||
getI18n: function() {
|
||||
return _('Unmanaged');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,222 @@
|
||||
'use strict';
|
||||
'require form';
|
||||
'require network';
|
||||
'require validation';
|
||||
|
||||
/**
|
||||
* Determine whether a provided value is a CIDR format IP string.
|
||||
* @param {string} value the IP string to test.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isCIDR(value) {
|
||||
return Array.isArray(value) || /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d{1,2}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the broadcast IP for a given IP.
|
||||
* @param {Node} s the ui element to test.
|
||||
* @param {boolean} use_cfgvalue whether to use the config or form value.
|
||||
* @returns {string}
|
||||
*/
|
||||
function calculateBroadcast(s, use_cfgvalue) {
|
||||
const readfn = use_cfgvalue ? 'cfgvalue' : 'formvalue';
|
||||
const addropt = s.children.find(o => o.option == 'ipaddr');
|
||||
const addrvals = addropt ? L.toArray(addropt[readfn](s.section)) : [];
|
||||
const maskopt = s.children.find(o => o.option == 'netmask');
|
||||
const maskval = maskopt ? maskopt[readfn](s.section) : null;
|
||||
let firstsubnet = null;
|
||||
|
||||
/* only form a subnet if both parts exist */
|
||||
if (addrvals.length && addrvals[0] && maskval)
|
||||
firstsubnet = addrvals[0] + '/' + maskval;
|
||||
else if (addrvals.length)
|
||||
firstsubnet = addrvals.find(a => a.indexOf('/') > 0);
|
||||
|
||||
if (!firstsubnet)
|
||||
return null;
|
||||
|
||||
const [addr_str, mask_str] = firstsubnet.split('/');
|
||||
const addr = validation.parseIPv4(addr_str);
|
||||
if (!addr)
|
||||
return null;
|
||||
|
||||
let mask = mask_str;
|
||||
|
||||
if (!isNaN(mask))
|
||||
mask = validation.parseIPv4(network.prefixToMask(+mask));
|
||||
else
|
||||
mask = validation.parseIPv4(mask);
|
||||
|
||||
if (!mask)
|
||||
return null;
|
||||
|
||||
const bc = [
|
||||
addr[0] | (~mask[0] >>> 0 & 255),
|
||||
addr[1] | (~mask[1] >>> 0 & 255),
|
||||
addr[2] | (~mask[2] >>> 0 & 255),
|
||||
addr[3] | (~mask[3] >>> 0 & 255)
|
||||
];
|
||||
|
||||
return bc.join('.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a broadcast IP for a section value.
|
||||
* @param {string} section_id
|
||||
* @param {string} value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function validateBroadcast(section_id, value) {
|
||||
const opt = this.map.lookupOption('broadcast', section_id);
|
||||
const node = opt ? this.map.findElement('id', opt[0].cbid(section_id)) : null;
|
||||
const addr = node ? calculateBroadcast(this.section, false) : null;
|
||||
|
||||
if (node != null) {
|
||||
if (addr != null)
|
||||
node.querySelector('input').setAttribute('placeholder', addr);
|
||||
else
|
||||
node.querySelector('input').removeAttribute('placeholder');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return network.registerProtocol('static', {
|
||||
CBIIPValue: form.Value.extend({
|
||||
handleSwitch(section_id, option_index, ev) {
|
||||
const maskopt = this.map.lookupOption('netmask', section_id);
|
||||
|
||||
if (maskopt == null || !this.isValid(section_id))
|
||||
return;
|
||||
|
||||
const maskval = maskopt[0].formvalue(section_id);
|
||||
const addrval = this.formvalue(section_id);
|
||||
const prefix = maskval ? network.maskToPrefix(maskval) : 32;
|
||||
|
||||
if (prefix == null)
|
||||
return;
|
||||
|
||||
this.datatype = 'or(cidr4,ipmask4)';
|
||||
|
||||
let parent = L.dom.parent(ev.target, '.cbi-value-field');
|
||||
L.dom.content(parent, form.DynamicList.prototype.renderWidget.apply(this, [
|
||||
section_id,
|
||||
option_index,
|
||||
addrval ? '%s/%d'.format(addrval, prefix) : ''
|
||||
]));
|
||||
|
||||
const masknode = this.map.findElement('id', maskopt[0].cbid(section_id));
|
||||
if (masknode) {
|
||||
parent = L.dom.parent(masknode, '.cbi-value');
|
||||
parent.parentNode.removeChild(parent);
|
||||
}
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
const widget = isCIDR(cfgvalue) ? 'DynamicList' : 'Value';
|
||||
|
||||
if (widget == 'DynamicList') {
|
||||
this.datatype = 'or(cidr4,ipmask4)';
|
||||
this.placeholder = _('Add IPv4 address…');
|
||||
}
|
||||
else {
|
||||
this.datatype = 'ip4addr("nomask")';
|
||||
}
|
||||
|
||||
const node = form[widget].prototype.renderWidget.apply(this, [ section_id, option_index, cfgvalue ]);
|
||||
|
||||
if (widget == 'Value')
|
||||
L.dom.append(node, E('button', {
|
||||
'class': 'cbi-button cbi-button-neutral',
|
||||
'title': _('Switch to CIDR list notation'),
|
||||
'aria-label': _('Switch to CIDR list notation'),
|
||||
'click': L.bind(this.handleSwitch, this, section_id, option_index)
|
||||
}, '…'));
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
validate: validateBroadcast
|
||||
}),
|
||||
|
||||
CBINetmaskValue: form.Value.extend({
|
||||
render(option_index, section_id, in_table) {
|
||||
var addropt = this.section.children.filter(function(o) { return o.option == 'ipaddr' })[0],
|
||||
addrval = addropt ? addropt.cfgvalue(section_id) : null;
|
||||
|
||||
if (addrval != null && isCIDR(addrval))
|
||||
return E([]);
|
||||
|
||||
this.value('255.255.255.0');
|
||||
this.value('255.255.0.0');
|
||||
this.value('255.0.0.0');
|
||||
|
||||
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
||||
},
|
||||
|
||||
datatype: 'ip4addr("true")',
|
||||
validate: validateBroadcast
|
||||
}),
|
||||
|
||||
CBIGatewayValue: form.Value.extend({
|
||||
datatype: 'ip4addr("nomask")',
|
||||
|
||||
render(option_index, section_id, in_table) {
|
||||
return network.getWANNetworks().then(L.bind(function(wans) {
|
||||
if (wans.length == 1) {
|
||||
var gwaddr = wans[0].getGatewayAddr();
|
||||
this.placeholder = gwaddr ? '%s (%s)'.format(gwaddr, wans[0].getName()) : '';
|
||||
}
|
||||
|
||||
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
||||
}, this));
|
||||
},
|
||||
|
||||
validate(section_id, value) {
|
||||
const addropt = this.section.children.filter(function(o) { return o.option == 'ipaddr' })[0];
|
||||
const addrval = addropt ? L.toArray(addropt.cfgvalue(section_id)) : null;
|
||||
|
||||
if (addrval != null) {
|
||||
for (let a of addrval) {
|
||||
const addr = a.split('/')[0];
|
||||
if (value == addr)
|
||||
return _('The gateway address must not be a local IP address');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
|
||||
CBIBroadcastValue: form.Value.extend({
|
||||
datatype: 'ip4addr("nomask")',
|
||||
|
||||
render(option_index, section_id, in_table) {
|
||||
this.placeholder = calculateBroadcast(this.section, true);
|
||||
return form.Value.prototype.render.apply(this, [ option_index, section_id, in_table ]);
|
||||
}
|
||||
}),
|
||||
|
||||
getI18n() {
|
||||
return _('Static address');
|
||||
},
|
||||
|
||||
renderFormOptions(s) {
|
||||
let o;
|
||||
|
||||
s.taboption('general', this.CBIIPValue, 'ipaddr', _('IPv4 address'));
|
||||
s.taboption('general', this.CBINetmaskValue, 'netmask', _('IPv4 netmask'));
|
||||
s.taboption('general', this.CBIGatewayValue, 'gateway', _('IPv4 gateway'));
|
||||
s.taboption('general', this.CBIBroadcastValue, 'broadcast', _('IPv4 broadcast'));
|
||||
|
||||
o = s.taboption('general', form.DynamicList, 'ip6addr', _('IPv6 address'));
|
||||
o.datatype = 'ip6addr';
|
||||
o.placeholder = _('Add IPv6 address…');
|
||||
|
||||
o = s.taboption('general', form.Value, 'ip6gw', _('IPv6 gateway'));
|
||||
o.datatype = 'ip6addr("nomask")';
|
||||
|
||||
o = s.taboption('general', form.Value, 'ip6prefix', _('IPv6 routed prefix'), _('Public prefix routed to this device for distribution to clients.'));
|
||||
o.datatype = 'ip6addr';
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,496 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require request';
|
||||
|
||||
let rpcRequestID = 1;
|
||||
let rpcSessionID = L.env.sessionid ?? '00000000000000000000000000000000';
|
||||
let rpcBaseURL = L.url('admin/ubus');
|
||||
const rpcInterceptorFns = [];
|
||||
|
||||
/**
|
||||
* @class rpc
|
||||
* @memberof LuCI
|
||||
* @hideconstructor
|
||||
* @classdesc
|
||||
*
|
||||
* The `LuCI.rpc` class provides high level ubus JSON-RPC abstractions
|
||||
* and means for listing and invoking remove RPC methods.
|
||||
*/
|
||||
return baseclass.extend(/** @lends LuCI.rpc.prototype */ {
|
||||
/* privates */
|
||||
call(req, cb, nobatch) {
|
||||
let q = '';
|
||||
|
||||
if (Array.isArray(req)) {
|
||||
if (req.length == 0)
|
||||
return Promise.resolve([]);
|
||||
|
||||
for (let i = 0; i < req.length; i++)
|
||||
if (req[i].params)
|
||||
q += '%s%s.%s'.format(
|
||||
q ? ';' : '/',
|
||||
req[i].params[1],
|
||||
req[i].params[2]
|
||||
);
|
||||
}
|
||||
|
||||
return request.post(rpcBaseURL + q, req, {
|
||||
timeout: (L.env.rpctimeout ?? 20) * 1000,
|
||||
nobatch,
|
||||
credentials: true
|
||||
}).then(cb, cb);
|
||||
},
|
||||
|
||||
parseCallReply(req, res) {
|
||||
let msg = null;
|
||||
|
||||
if (res instanceof Error)
|
||||
return req.reject(res);
|
||||
|
||||
try {
|
||||
if (!res.ok)
|
||||
L.raise('RPCError', 'RPC call to %s/%s failed with HTTP error %d: %s',
|
||||
req.object, req.method, res.status, res.statusText || '?');
|
||||
|
||||
msg = res.json();
|
||||
}
|
||||
catch (e) {
|
||||
return req.reject(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* The interceptor args are intentionally swapped.
|
||||
* Response is passed as first arg to align with Request class interceptors
|
||||
*/
|
||||
Promise.all(rpcInterceptorFns.map(fn => fn(msg, req)))
|
||||
.then(this.handleCallReply.bind(this, req, msg))
|
||||
.catch(req.reject);
|
||||
},
|
||||
|
||||
handleCallReply(req, msg) {
|
||||
const type = Object.prototype.toString;
|
||||
let ret = null;
|
||||
|
||||
try {
|
||||
/* verify message frame */
|
||||
if (!L.isObject(msg) || msg.jsonrpc != '2.0')
|
||||
L.raise('RPCError', 'RPC call to %s/%s returned invalid message frame',
|
||||
req.object, req.method);
|
||||
|
||||
/* check error condition */
|
||||
if (L.isObject(msg.error) && msg.error.code && msg.error.message)
|
||||
L.raise('RPCError', 'RPC call to %s/%s failed with error %d: %s',
|
||||
req.object, req.method, msg.error.code, msg.error.message || '?');
|
||||
}
|
||||
catch (e) {
|
||||
return req.reject(e);
|
||||
}
|
||||
|
||||
if (!req.object && !req.method) {
|
||||
ret = msg.result;
|
||||
}
|
||||
else if (Array.isArray(msg.result)) {
|
||||
if (req.raise && msg.result[0] !== 0)
|
||||
L.raise('RPCError', 'RPC call to %s/%s failed with ubus code %d: %s',
|
||||
req.object, req.method, msg.result[0], this.getStatusText(msg.result[0]));
|
||||
|
||||
ret = (msg.result.length > 1) ? msg.result[1] : msg.result[0];
|
||||
}
|
||||
|
||||
if (req.expect) {
|
||||
for (const key in req.expect) {
|
||||
if (ret != null && key != '')
|
||||
ret = ret[key];
|
||||
|
||||
if (ret == null || type.call(ret) != type.call(req.expect[key]))
|
||||
ret = req.expect[key];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* apply filter */
|
||||
if (typeof(req.filter) == 'function') {
|
||||
req.priv[0] = ret;
|
||||
req.priv[1] = req.params;
|
||||
ret = req.filter.apply(this, req.priv);
|
||||
}
|
||||
|
||||
req.resolve(ret);
|
||||
},
|
||||
|
||||
/**
|
||||
* Lists available remote ubus objects or the method signatures of
|
||||
* specific objects.
|
||||
*
|
||||
* This function has two signatures and is sensitive to the number of
|
||||
* arguments passed to it:
|
||||
* - `list()` -
|
||||
* Returns an array containing the names of all remote `ubus` objects
|
||||
* - `list("objname", ...)`
|
||||
* Returns method signatures for each given `ubus` object name.
|
||||
*
|
||||
* @param {...string} [args] (objectNames)
|
||||
* If any object names are given, this function will return the method
|
||||
* signatures of each given object.
|
||||
*
|
||||
* @returns {Promise<Array<string>|Object<string, Object<string, Object<string, string>>>>}
|
||||
* When invoked without arguments, this function will return a promise
|
||||
* resolving to an array of `ubus` object names. When invoked with one or
|
||||
* more arguments, a promise resolving to an object describing the method
|
||||
* signatures of each requested `ubus` object name will be returned.
|
||||
*/
|
||||
list(...args) {
|
||||
const msg = {
|
||||
jsonrpc: '2.0',
|
||||
id: rpcRequestID++,
|
||||
method: 'list',
|
||||
params: args.length ? args : undefined
|
||||
};
|
||||
|
||||
return new Promise(L.bind(function(resolve, reject) {
|
||||
/* store request info */
|
||||
const req = { resolve, reject };
|
||||
|
||||
/* call rpc */
|
||||
this.call(msg, this.parseCallReply.bind(this, req));
|
||||
}, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeclareOptions
|
||||
* @memberof LuCI.rpc
|
||||
*
|
||||
* @property {string} object
|
||||
* The name of the remote `ubus` object to invoke.
|
||||
*
|
||||
* @property {string} method
|
||||
* The name of the remote `ubus` method to invoke.
|
||||
*
|
||||
* @property {string[]} [params]
|
||||
* Lists the named parameters expected by the remote `ubus` RPC method.
|
||||
* The arguments passed to the resulting generated method call function
|
||||
* will be mapped to named parameters in the order they appear in this
|
||||
* array.
|
||||
*
|
||||
* Extraneous parameters passed to the generated function will not be
|
||||
* sent to the remote procedure but are passed to the
|
||||
* {@link LuCI.rpc.filterFn filter function} if one is specified.
|
||||
*
|
||||
* Examples:
|
||||
* - `params: [ "foo", "bar" ]` -
|
||||
* When the resulting call function is invoked with `fn(true, false)`,
|
||||
* the corresponding args object sent to the remote procedure will be
|
||||
* `{ foo: true, bar: false }`.
|
||||
* - `params: [ "test" ], filter: function(reply, args, extra) { ... }` -
|
||||
* When the resulting generated function is invoked with
|
||||
* `fn("foo", "bar", "baz")` then `{ "test": "foo" }` will be sent as
|
||||
* argument to the remote procedure and the filter function will be
|
||||
* invoked with `filterFn(reply, [ "foo" ], "bar", "baz")`
|
||||
*
|
||||
* @property {Object<string,*>} [expect]
|
||||
* Describes the expected return data structure. The given object is
|
||||
* supposed to contain a single key selecting the value to use from
|
||||
* the returned `ubus` reply object. The value of the sole key within
|
||||
* the `expect` object is used to infer the expected type of the received
|
||||
* `ubus` reply data.
|
||||
*
|
||||
* If the received data does not contain `expect`'s key, or if the
|
||||
* type of the data differs from the type of the value in the expect
|
||||
* object, the expect object's value is returned as default instead.
|
||||
*
|
||||
* The key in the `expect` object may be an empty string (`''`) in which
|
||||
* case the entire reply object is selected instead of one of its subkeys.
|
||||
*
|
||||
* If the `expect` option is omitted, the received reply will be returned
|
||||
* as-is, regardless of its format or type.
|
||||
*
|
||||
* Examples:
|
||||
* - `expect: { '': { error: 'Invalid response' } }` -
|
||||
* This requires the entire `ubus` reply to be a plain JavaScript
|
||||
* object. If the reply isn't an object but e.g. an array or a numeric
|
||||
* error code instead, it will get replaced with
|
||||
* `{ error: 'Invalid response' }` instead.
|
||||
* - `expect: { results: [] }` -
|
||||
* This requires the received `ubus` reply to be an object containing
|
||||
* a key `results` with an array as value. If the received reply does
|
||||
* not contain such a key, or if `reply.results` points to a non-array
|
||||
* value, the empty array (`[]`) will be used instead.
|
||||
* - `expect: { success: false }` -
|
||||
* This requires the received `ubus` reply to be an object containing
|
||||
* a key `success` with a boolean value. If the reply does not contain
|
||||
* `success` or if `reply.success` is not a boolean value, `false` will
|
||||
* be returned as default instead.
|
||||
*
|
||||
* @property {LuCI.rpc.filterFn} [filter]
|
||||
* Specifies an optional filter function which is invoked to transform the
|
||||
* received reply data before it is returned to the caller.
|
||||
*
|
||||
* @property {boolean} [reject=false]
|
||||
* If set to `true`, non-zero ubus call status codes are treated as fatal
|
||||
* error and lead to the rejection of the call promise. The default
|
||||
* behaviour is to resolve with the call return code value instead.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The filter function is invoked to transform a received `ubus` RPC call
|
||||
* reply before returning it to the caller.
|
||||
*
|
||||
* @callback LuCI.rpc.filterFn
|
||||
*
|
||||
* @param {*} data
|
||||
* The received `ubus` reply data or a subset of it as described in the
|
||||
* `expect` option of the RPC call declaration. In case of remote call
|
||||
* errors, `data` is numeric `ubus` error code instead.
|
||||
*
|
||||
* @param {Array<*>} args
|
||||
* The arguments the RPC method has been invoked with.
|
||||
*
|
||||
* @param {...*} extraArgs
|
||||
* All extraneous arguments passed to the RPC method exceeding the number
|
||||
* of arguments describes in the RPC call declaration.
|
||||
*
|
||||
* @returns {*}
|
||||
* The return value of the filter function will be returned to the caller
|
||||
* of the RPC method as-is.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The generated invocation function is returned by
|
||||
* {@link LuCI.rpc#declare rpc.declare()} and encapsulates a single
|
||||
* RPC method call.
|
||||
*
|
||||
* Calling this function will execute a remote `ubus` HTTP call request
|
||||
* using the arguments passed to it as arguments and return a promise
|
||||
* resolving to the received reply values.
|
||||
*
|
||||
* @callback LuCI.rpc.invokeFn
|
||||
*
|
||||
* @param {...*} params
|
||||
* The parameters to pass to the remote procedure call. The given
|
||||
* positional arguments will be named to named RPC parameters according
|
||||
* to the names specified in the `params` array of the method declaration.
|
||||
*
|
||||
* Any additional parameters exceeding the amount of arguments in the
|
||||
* `params` declaration are passed as private extra arguments to the
|
||||
* declared filter function.
|
||||
*
|
||||
* @returns {Promise<*>}
|
||||
* Returns a promise resolving to the result data of the remote `ubus`
|
||||
* RPC method invocation, optionally substituted and filtered according
|
||||
* to the `expect` and `filter` declarations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes a remote RPC call procedure and returns a function
|
||||
* implementing it.
|
||||
*
|
||||
* @param {LuCI.rpc.DeclareOptions} options
|
||||
* If any object names are given, this function will return the method
|
||||
* signatures of each given object.
|
||||
*
|
||||
* @returns {LuCI.rpc.invokeFn}
|
||||
* Returns a new function implementing the method call described in
|
||||
* `options`.
|
||||
*/
|
||||
declare(options) {
|
||||
return Function.prototype.bind.call(function(rpc, options, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
/* build parameter object */
|
||||
let p_off = 0;
|
||||
const params = { };
|
||||
if (Array.isArray(options.params)) {
|
||||
// Array style: parameter names are positional
|
||||
for (p_off = 0; p_off < options.params.length; p_off++)
|
||||
params[options.params[p_off]] = args[p_off];
|
||||
} else if (typeof(options.params) === 'object') {
|
||||
// Object style: first arg is an object with the parameter keys
|
||||
const argObj = args[0];
|
||||
if (argObj && typeof(argObj) === 'object') {
|
||||
for (let key in options.params)
|
||||
if (key in argObj)
|
||||
params[key] = argObj[key];
|
||||
}
|
||||
p_off = 1;
|
||||
}
|
||||
|
||||
/* all remaining arguments are private args */
|
||||
const priv = [ undefined, undefined ];
|
||||
for (; p_off < args.length; p_off++)
|
||||
priv.push(args[p_off]);
|
||||
|
||||
/* store request info */
|
||||
const req = {
|
||||
expect: options.expect,
|
||||
filter: options.filter,
|
||||
resolve,
|
||||
reject,
|
||||
params,
|
||||
priv,
|
||||
object: options.object,
|
||||
method: options.method,
|
||||
raise: options.reject
|
||||
};
|
||||
|
||||
/* build message object */
|
||||
const msg = {
|
||||
jsonrpc: '2.0',
|
||||
id: rpcRequestID++,
|
||||
method: 'call',
|
||||
params: [
|
||||
rpcSessionID,
|
||||
options.object,
|
||||
options.method,
|
||||
params
|
||||
]
|
||||
};
|
||||
|
||||
/* call rpc */
|
||||
rpc.call(msg, rpc.parseCallReply.bind(rpc, req), options.nobatch);
|
||||
});
|
||||
}, this, this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current RPC session id.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the 32 byte session ID string used for authenticating remote
|
||||
* requests.
|
||||
*/
|
||||
getSessionID() {
|
||||
return rpcSessionID;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the RPC session id to use.
|
||||
*
|
||||
* @param {string} sid
|
||||
* Sets the 32 byte session ID string used for authenticating remote
|
||||
* requests.
|
||||
*/
|
||||
setSessionID(sid) {
|
||||
rpcSessionID = sid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current RPC base URL.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the RPC URL endpoint to issue requests against.
|
||||
*/
|
||||
getBaseURL() {
|
||||
return rpcBaseURL;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the RPC base URL to use.
|
||||
*
|
||||
* @param {string} url
|
||||
* Sets the RPC URL endpoint to issue requests against.
|
||||
*/
|
||||
setBaseURL(url) {
|
||||
rpcBaseURL = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Translates a numeric `ubus` error code into a human readable
|
||||
* description.
|
||||
*
|
||||
* @param {number} statusCode
|
||||
* The numeric status code.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the textual description of the code.
|
||||
*/
|
||||
getStatusText(statusCode) {
|
||||
switch (statusCode) {
|
||||
case 0: return _('Command OK');
|
||||
case 1: return _('Invalid command');
|
||||
case 2: return _('Invalid argument');
|
||||
case 3: return _('Method not found');
|
||||
case 4: return _('Resource not found');
|
||||
case 5: return _('No data received');
|
||||
case 6: return _('Permission denied');
|
||||
case 7: return _('Request timeout');
|
||||
case 8: return _('Not supported');
|
||||
case 9: return _('Unspecified error');
|
||||
case 10: return _('Connection lost');
|
||||
default: return _('Unknown error code');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Registered interceptor functions are invoked before the standard reply
|
||||
* parsing and handling logic.
|
||||
*
|
||||
* By returning rejected promises, interceptor functions can cause the
|
||||
* invocation function to fail, regardless of the received reply.
|
||||
*
|
||||
* Interceptors may also modify their message argument in-place to
|
||||
* rewrite received replies before they're processed by the standard
|
||||
* response handling code.
|
||||
*
|
||||
* A common use case for such functions is to detect failing RPC replies
|
||||
* due to expired authentication in order to trigger a new login.
|
||||
*
|
||||
* @callback LuCI.rpc~interceptorFn
|
||||
*
|
||||
* @param {*} msg
|
||||
* The unprocessed, JSON decoded remote RPC method call reply.
|
||||
*
|
||||
* Since interceptors run before the standard parsing logic, the reply
|
||||
* data is not verified for correctness or filtered according to
|
||||
* `expect` and `filter` specifications in the declarations.
|
||||
*
|
||||
* @param {Object} req
|
||||
* The related request object which is an extended variant of the
|
||||
* declaration object, allowing access to internals of the invocation
|
||||
* function such as `filter`, `expect` or `params` values.
|
||||
*
|
||||
* @returns {Promise<*>|*}
|
||||
* Interceptor functions may return a promise to defer response
|
||||
* processing until some delayed work completed. Any values the returned
|
||||
* promise resolves to are ignored.
|
||||
*
|
||||
* When the returned promise rejects with an error, the invocation
|
||||
* function will fail too, forwarding the error to the caller.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Registers a new interceptor function.
|
||||
*
|
||||
* @param {LuCI.rpc.interceptorFn} interceptorFn
|
||||
* The interceptor function to register.
|
||||
*
|
||||
* @returns {LuCI.rpc.interceptorFn}
|
||||
* Returns the given function value.
|
||||
*/
|
||||
addInterceptor(interceptorFn) {
|
||||
if (typeof(interceptorFn) == 'function')
|
||||
rpcInterceptorFns.push(interceptorFn);
|
||||
|
||||
return interceptorFn;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a registered interceptor function.
|
||||
*
|
||||
* @param {LuCI.rpc.interceptorFn} interceptorFn
|
||||
* The interceptor function to remove.
|
||||
*
|
||||
* @returns {boolean}
|
||||
* Returns `true` if the given function has been removed or `false`
|
||||
* if it has not been found.
|
||||
*/
|
||||
removeInterceptor(interceptorFn) {
|
||||
const oldlen = rpcInterceptorFns.length;
|
||||
let i = oldlen;
|
||||
|
||||
while (i--)
|
||||
if (rpcInterceptorFns[i] === interceptorFn)
|
||||
rpcInterceptorFns.splice(i, 1);
|
||||
|
||||
return (rpcInterceptorFns.length < oldlen);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,183 @@
|
||||
'use strict';
|
||||
|
||||
var s = [0x0000, 0x0000, 0x0000, 0x0000];
|
||||
|
||||
/**
|
||||
* Multiply two 64-bit values represented as arrays of four 16-bit words.
|
||||
*
|
||||
* Arrays use little-endian word order (least-significant 16-bit word first).
|
||||
* The result is truncated to the lower 64 bits and returned as a 4-element
|
||||
* array of 16-bit words.
|
||||
*
|
||||
* @param {Array<number>} a - Multiplicand (4 × 16-bit words, little-endian)
|
||||
* @param {Array<number>} b - Multiplier (4 × 16-bit words, little-endian)
|
||||
* @returns {Array<number>} Product as 4 × 16-bit words (little-endian)
|
||||
*/
|
||||
function mul(a, b) {
|
||||
var r = [0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000];
|
||||
|
||||
for (var j = 0; j < 4; j++) {
|
||||
var k = 0;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
var t = a[i] * b[j] + r[i+j] + k;
|
||||
r[i+j] = t & 0xffff;
|
||||
k = t >>> 16;
|
||||
}
|
||||
r[j+4] = k;
|
||||
}
|
||||
|
||||
r.length = 4;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a small integer to a 64-bit value represented as four 16-bit words.
|
||||
*
|
||||
* Treats `a` as a little-endian 64-bit value (4 × 16-bit words). Adds the
|
||||
* integer `n` to the least-significant word and propagates carry across
|
||||
* subsequent 16-bit words. The result is truncated to 64 bits and returned
|
||||
* as a 4-element array of 16-bit words (little-endian).
|
||||
*
|
||||
* @param {Array<number>} a - Addend as 4 × 16-bit words (little-endian)
|
||||
* @param {number} n - Value to add (integer carry)
|
||||
* @returns {Array<number>} Sum as 4 × 16-bit words (little-endian)
|
||||
*/
|
||||
function add(a, n) {
|
||||
var r = [0x0000, 0x0000, 0x0000, 0x0000],
|
||||
k = n;
|
||||
|
||||
for (var i = 0; i < 4; i++) {
|
||||
var t = a[i] + k;
|
||||
r[i] = t & 0xffff;
|
||||
k = t >>> 16;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift a 64-bit value (4 × 16-bit words, little-endian) right by `n` bits.
|
||||
*
|
||||
* The input array is treated as little-endian 16-bit words. Bits shifted out
|
||||
* on the right are discarded; the returned array contains the lower 64-bit
|
||||
* result after the logical right shift.
|
||||
*
|
||||
* @param {Array<number>} a - Source value as 4 × 16-bit words (little-endian)
|
||||
* @param {number} n - Number of bits to shift right (non-negative integer)
|
||||
* @returns {Array<number>} Shifted value as 4 × 16-bit words (little-endian)
|
||||
*/
|
||||
function shr(a, n) {
|
||||
var r = [a[0], a[1], a[2], a[3], 0x0000],
|
||||
i = 4,
|
||||
k = 0;
|
||||
|
||||
for (; n > 16; n -= 16, i--)
|
||||
for (var j = 0; j < 4; j++)
|
||||
r[j] = r[j+1];
|
||||
|
||||
for (; i > 0; i--) {
|
||||
var s = r[i-1];
|
||||
r[i-1] = (s >>> n) | k;
|
||||
k = ((s & ((1 << n) - 1)) << (16 - n));
|
||||
}
|
||||
|
||||
r.length = 4;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
return L.Class.extend({
|
||||
/**
|
||||
* Seed the PRNG state.
|
||||
*
|
||||
* The seed is treated as a 32-bit integer; the lower 16 bits are stored
|
||||
* in `s[0]`, the upper 16 bits in `s[1]`. `s[2]` and `s[3]` are zeroed.
|
||||
*
|
||||
* @param {number} n - Seed value (32-bit integer)
|
||||
* @returns {void}
|
||||
*/
|
||||
seed: function(n) {
|
||||
n = (n - 1)|0;
|
||||
s[0] = n & 0xffff;
|
||||
s[1] = n >>> 16;
|
||||
s[2] = 0;
|
||||
s[3] = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Produce the next PRNG 32-bit integer.
|
||||
*
|
||||
* Advances the internal state and returns a 32-bit pseudo-random integer
|
||||
* derived from the current state.
|
||||
*
|
||||
* @returns {number} 32-bit pseudo-random integer (JS number)
|
||||
*/
|
||||
int: function() {
|
||||
s = mul(s, [0x7f2d, 0x4c95, 0xf42d, 0x5851]);
|
||||
s = add(s, 1);
|
||||
|
||||
var r = shr(s, 33);
|
||||
return (r[1] << 16) | r[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a pseudo-random value.
|
||||
*
|
||||
* Overloads:
|
||||
* - get() -> number in [0, 1]
|
||||
* - get(upper) -> integer in [1, upper]
|
||||
* - get(lower, upper) -> integer in [lower, upper]
|
||||
*
|
||||
* @param {number} [lower=0] - Lower bound (when two args supplied)
|
||||
* @param {number} [upper=0] - Upper bound (when one or two args supplied)
|
||||
* @returns {number} Random value (float in [0,1] or integer in requested range)
|
||||
*/
|
||||
get: function() {
|
||||
var r = (this.int() % 0x7fffffff) / 0x7fffffff, l, u;
|
||||
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return r;
|
||||
|
||||
case 1:
|
||||
l = 1;
|
||||
u = arguments[0]|0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
l = arguments[0]|0;
|
||||
u = arguments[1]|0;
|
||||
break;
|
||||
}
|
||||
|
||||
return Math.floor(r * (u - l + 1)) + l;
|
||||
},
|
||||
|
||||
/**
|
||||
* Derive a deterministic hex color from an input string.
|
||||
*
|
||||
* The color is produced by seeding the PRNG from a string-derived
|
||||
* hash and producing RGB components. Returns a `#rrggbb` hex string.
|
||||
*
|
||||
* @param {string} string - Input string used to derive the color
|
||||
* @returns {string} Hex color string in `#rrggbb` format
|
||||
*/
|
||||
derive_color: function(string) {
|
||||
this.seed(parseInt(sfh(string), 16));
|
||||
|
||||
var r = this.get(128),
|
||||
g = this.get(128),
|
||||
min = 0,
|
||||
max = 128;
|
||||
|
||||
if ((r + g) < 128)
|
||||
min = 128 - r - g;
|
||||
else
|
||||
max = 255 - r - g;
|
||||
|
||||
var b = min + Math.floor(this.get() * (max - min));
|
||||
|
||||
return '#%02x%02x%02x'.format(0xff - r, 0xff - g, 0xff - b);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,295 @@
|
||||
'use strict';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
/* Note that any view implementing this log reader requires the log read
|
||||
acl permission */
|
||||
|
||||
const callLogRead = rpc.declare({
|
||||
object: 'log',
|
||||
method: 'read',
|
||||
params: [ 'lines', 'stream', 'oneshot' ],
|
||||
expect: { log: [] }
|
||||
});
|
||||
|
||||
var CBILogreadBox = function(logtag, name) {
|
||||
return L.view.extend({
|
||||
|
||||
logFacilityFilter: 'any',
|
||||
invertLogFacilitySearch: false,
|
||||
logSeverityFilter: 'any',
|
||||
invertLogSeveritySearch: false,
|
||||
logTextFilter: '',
|
||||
invertLogTextSearch: false,
|
||||
logTagFilter: logtag ? logtag : '',
|
||||
logName: name ? name : _('System Log'),
|
||||
fetchMaxRows: 1000,
|
||||
|
||||
facilities: [
|
||||
['any', 'any', _('Any')],
|
||||
['0', 'kern', _('Kernel')],
|
||||
['1', 'user', _('User')],
|
||||
['2', 'mail', _('Mail')],
|
||||
['3', 'daemon', _('Daemon')],
|
||||
['4', 'auth', _('Auth')],
|
||||
['5', 'syslog', _('Syslog')],
|
||||
['6', 'lpr', _('LPR')],
|
||||
['7', 'news', _('News')],
|
||||
['8', 'uucp', _('UUCP')],
|
||||
['9', 'cron', _('Cron')],
|
||||
['10', 'authpriv', _('Auth Priv')],
|
||||
['11', 'ftp', _('FTP')],
|
||||
['12', 'ntp', _('NTP')],
|
||||
['13', 'security', _('Log audit')],
|
||||
['14', 'console', _('Log alert')],
|
||||
['15', 'cron', _('Scheduling daemon')],
|
||||
['16', 'local0', _('Local 0')],
|
||||
['17', 'local1', _('Local 1')],
|
||||
['18', 'local2', _('Local 2')],
|
||||
['19', 'local3', _('Local 3')],
|
||||
['20', 'local4', _('Local 4')],
|
||||
['21', 'local5', _('Local 5')],
|
||||
['22', 'local6', _('Local 6')],
|
||||
['23', 'local7', _('Local 7')]
|
||||
],
|
||||
|
||||
severity: [
|
||||
['any','any', _('Any')],
|
||||
['0', 'emerg', _('Emergency')],
|
||||
['1', 'alert', _('Alert')],
|
||||
['2', 'crit', _('Critical')],
|
||||
['3', 'err', _('Error')],
|
||||
['4', 'warn', _('Warning')],
|
||||
['5', 'notice', _('Notice')],
|
||||
['6', 'info', _('Info')],
|
||||
['7', 'debug', _('Debug')]
|
||||
],
|
||||
|
||||
|
||||
async retrieveLog() {
|
||||
try {
|
||||
const tz = uci.get('system', '@system[0]', 'zonename')?.replaceAll(' ', '_');
|
||||
const ts = uci.get('system', '@system[0]', 'clock_timestyle') || 0;
|
||||
const hc = uci.get('system', '@system[0]', 'clock_hourcycle') || 0;
|
||||
let loglines = await callLogRead(this.fetchMaxRows, false, true)
|
||||
.then((logEntries) => {
|
||||
const dateObj = new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: (ts == 0) ? 'long' : 'full',
|
||||
hourCycle: (hc == 0) ? undefined : hc,
|
||||
timeZone: tz
|
||||
});
|
||||
|
||||
return logEntries.map(entry => {
|
||||
const time = new Date(entry?.time);
|
||||
const datestr = dateObj.format(time);
|
||||
/* remember to add one since the 'any' entry occupies 1st position i.e. [0] */
|
||||
const facility = this.facilities[Math.floor(entry?.priority / 8) + 1][1] ?? 'unknown';
|
||||
const severity = this.severity[(entry?.priority % 8) + 1][1] ?? 'unknown';
|
||||
return `[${datestr}] ${facility}.${severity}: ${entry?.msg}`;
|
||||
});
|
||||
})
|
||||
.catch(function (){
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/usr/libexec/syslog-wrapper'), null),
|
||||
]).then((stat) => {
|
||||
const logger = stat[0]?.path;
|
||||
return fs.exec_direct(logger)
|
||||
.then(logdata => {
|
||||
return logdata.trim().split(/\n/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
loglines = loglines.filter(line => {
|
||||
const sevMatch = this.logSeverityFilter === 'any' || line.includes(`.${this.logSeverityFilter}`);
|
||||
const facMatch = this.logFacilityFilter === 'any' || line.includes(`${this.logFacilityFilter}.`);
|
||||
return (this.invertLogSeveritySearch != sevMatch)
|
||||
&& (this.invertLogFacilitySearch != facMatch);
|
||||
});
|
||||
|
||||
loglines = loglines.filter(line => {
|
||||
return line.toLowerCase().includes(this.logTagFilter?.toLowerCase());
|
||||
});
|
||||
|
||||
loglines = loglines.filter(line => {
|
||||
const match = line.includes(this.logTextFilter);
|
||||
return this.invertLogTextSearch ? !match : match;
|
||||
});
|
||||
|
||||
return {
|
||||
value: loglines?.join('\n'),
|
||||
rows: loglines?.length + 1
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
ui.addNotification(null, E('p', {}, _('Unable to load log data: ' + err.message)));
|
||||
return {
|
||||
value: '',
|
||||
rows: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
async pollLog() {
|
||||
const element = document.getElementById('syslog');
|
||||
if (element) {
|
||||
const log = await this.retrieveLog();
|
||||
element.value = log?.value;
|
||||
element.rows = log?.rows;
|
||||
}
|
||||
},
|
||||
|
||||
async load() {
|
||||
poll.add(this.pollLog.bind(this));
|
||||
return Promise.all([
|
||||
uci.load('system'),
|
||||
]).then(() => this.retrieveLog());
|
||||
},
|
||||
|
||||
render(loglines) {
|
||||
const scrollDownButton = E('button', {
|
||||
'id': 'scrollDownButton',
|
||||
'class': 'cbi-button cbi-button-neutral'
|
||||
}, _('Scroll to tail', 'scroll to bottom (the tail) of the log file')
|
||||
);
|
||||
scrollDownButton.addEventListener('click', () => {
|
||||
scrollUpButton.scrollIntoView();
|
||||
scrollDownButton.blur();
|
||||
});
|
||||
|
||||
const scrollUpButton = E('button', {
|
||||
'id' : 'scrollUpButton',
|
||||
'class': 'cbi-button cbi-button-neutral'
|
||||
}, _('Scroll to head', 'scroll to top (the head) of the log file')
|
||||
);
|
||||
scrollUpButton.addEventListener('click', () => {
|
||||
scrollDownButton.scrollIntoView();
|
||||
scrollUpButton.blur();
|
||||
});
|
||||
|
||||
const self = this;
|
||||
|
||||
// Create facility invert checkbox
|
||||
const facilityInvert = E('input', {
|
||||
'id': 'invertLogFacilitySearch',
|
||||
'type': 'checkbox',
|
||||
'class': 'cbi-input-checkbox',
|
||||
});
|
||||
|
||||
// Create facility select-dropdown from facilities map
|
||||
const facilitySelect = E('select', {
|
||||
'id': 'logFacilitySelect',
|
||||
'class': 'cbi-input-select',
|
||||
'style': 'margin-bottom:10px',
|
||||
},
|
||||
this.facilities.map(([ , val, label]) =>
|
||||
(val == 'any') ? E('option', { value: val, selected: '' }, label) : E('option', { value: val }, label)
|
||||
));
|
||||
|
||||
// Create severity invert checkbox
|
||||
const severityInvert = E('input', {
|
||||
'id': 'invertLogSeveritySearch',
|
||||
'type': 'checkbox',
|
||||
'class': 'cbi-input-checkbox',
|
||||
});
|
||||
|
||||
// Create severity select-dropdown from facilities map
|
||||
const severitySelect = E('select', {
|
||||
'id': 'logSeveritySelect',
|
||||
'class': 'cbi-input-select',
|
||||
},
|
||||
this.severity.map(([ , val, label]) =>
|
||||
(val == 'any') ? E('option', { value: val, selected: '' }, label) : E('option', { value: val }, label)
|
||||
));
|
||||
|
||||
// Create raw text search invert checkbox
|
||||
const filterTextInvert = E('input', {
|
||||
'id': 'invertLogTextSearch',
|
||||
'type': 'checkbox',
|
||||
'class': 'cbi-input-checkbox',
|
||||
});
|
||||
|
||||
// Create raw text search text input
|
||||
const filterTextInput = E('input', {
|
||||
'id': 'logTextFilter',
|
||||
'class': 'cbi-input-text',
|
||||
});
|
||||
|
||||
// Create max rows input
|
||||
const filterMaxRows = E('input', {
|
||||
'id': 'logMaxRows',
|
||||
'type': 'number',
|
||||
'class': 'cbi-input',
|
||||
});
|
||||
|
||||
/**
|
||||
* Update the form when log filter parameters change
|
||||
*/
|
||||
function handleLogFilterChange() {
|
||||
self.logFacilityFilter = facilitySelect.value;
|
||||
self.invertLogFacilitySearch = facilityInvert.checked;
|
||||
self.logSeverityFilter = severitySelect.value;
|
||||
self.invertLogSeveritySearch = severityInvert.checked;
|
||||
self.logTextFilter = filterTextInput.value;
|
||||
self.invertLogTextSearch = filterTextInvert.checked;
|
||||
self.fetchMaxRows = Number.parseInt(filterMaxRows.value);
|
||||
self.pollLog();
|
||||
}
|
||||
|
||||
facilitySelect.addEventListener('change', handleLogFilterChange);
|
||||
facilityInvert.addEventListener('change', handleLogFilterChange);
|
||||
severitySelect.addEventListener('change', handleLogFilterChange);
|
||||
severityInvert.addEventListener('change', handleLogFilterChange);
|
||||
filterTextInput.addEventListener('input', handleLogFilterChange);
|
||||
filterTextInvert.addEventListener('change', handleLogFilterChange);
|
||||
filterMaxRows.addEventListener('change', handleLogFilterChange);
|
||||
|
||||
return E([], [
|
||||
E('h2', {}, [ this.logName ]),
|
||||
E('div', { 'id': 'content_syslog' }, [
|
||||
E('div', { class: 'cbi-section-descr' }, this.logTagFilter ? _('The syslog output, pre-filtered for messages related to: ' + this.logTagFilter) : '') ,
|
||||
E('div', { 'style': 'margin-bottom:10px' }, [
|
||||
E('label', { 'for': 'invertLogFacilitySearch', 'style': 'margin-right:5px' }, _('Not')),
|
||||
facilityInvert,
|
||||
E('label', { 'for': 'logFacilitySelect', 'style': 'margin: 0 5px' }, _('facility:')),
|
||||
facilitySelect,
|
||||
E('label', { 'for': 'invertLogSeveritySearch', 'style': 'margin: 0 5px' }, _('Not')),
|
||||
severityInvert,
|
||||
E('label', { 'for': 'logSeveritySelect', 'style': 'margin: 0 5px' }, _('severity:')),
|
||||
severitySelect,
|
||||
]),
|
||||
E('div', { 'style': 'margin-bottom:10px' }, [
|
||||
E('label', { 'for': 'invertLogTextSearch', 'style': 'margin-right:5px' }, _('Not')),
|
||||
filterTextInvert,
|
||||
E('label', { 'for': 'logTextFilter', 'style': 'margin: 0 5px' }, _('including:')),
|
||||
filterTextInput,
|
||||
E('label', { 'for': 'logMaxRows', 'style': 'margin: 0 5px' }, _('Max rows:')),
|
||||
filterMaxRows,
|
||||
]),
|
||||
E('div', {'style': 'padding-bottom: 20px'}, [scrollDownButton]),
|
||||
E('textarea', {
|
||||
'id': 'syslog',
|
||||
'style': 'font-size:12px',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': loglines?.rows,
|
||||
}, [ loglines?.value ]),
|
||||
E('div', {'style': 'padding-bottom: 20px'}, [scrollUpButton])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
||||
};
|
||||
|
||||
return L.Class.extend({
|
||||
LogreadBox: CBILogreadBox,
|
||||
});
|
||||
@@ -0,0 +1,855 @@
|
||||
'use strict';
|
||||
'require ui';
|
||||
'require form';
|
||||
'require network';
|
||||
'require firewall';
|
||||
'require fs';
|
||||
'require uci';
|
||||
|
||||
|
||||
/**
|
||||
* Get users found in `/etc/passwd`.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function getUsers() {
|
||||
return fs.lines('/etc/passwd').then(function(lines) {
|
||||
return lines.map(function(line) { return line.split(/:/)[0] });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users found in `/etc/group`.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function getGroups() {
|
||||
return fs.lines('/etc/group').then(function(lines) {
|
||||
return lines.map(function(line) { return line.split(/:/)[0] });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bridge devices or Layer 3 devices of a network object.
|
||||
* @param {object} network
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function getDevices(network) {
|
||||
if (network.isBridge()) {
|
||||
var devices = network.getDevices();
|
||||
return devices ? devices : [];
|
||||
} else {
|
||||
return L.toArray(network.getL3Device());
|
||||
}
|
||||
}
|
||||
|
||||
var CBIZoneSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.ZoneSelect',
|
||||
|
||||
load(section_id) {
|
||||
return Promise.all([ firewall.getZones(), network.getNetworks() ]).then(L.bind(function(zn) {
|
||||
this.zones = zn[0];
|
||||
this.networks = zn[1];
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
lookupZone(name) {
|
||||
return this.zones.filter(function(zone) { return zone.getName() == name })[0];
|
||||
},
|
||||
|
||||
lookupNetwork(name) {
|
||||
return this.networks.filter(function(network) { return network.getName() == name })[0];
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
const values = L.toArray((cfgvalue != null) ? cfgvalue : this.default);
|
||||
let isOutputOnly = false;
|
||||
const choices = {};
|
||||
let datatype_str = 'ucifw4zonename';
|
||||
if (!L.hasSystemFeature('firewall4'))
|
||||
datatype_str = `and(${datatype_str},maxlength(11))`;
|
||||
if (this.allowany && this.nocreate)
|
||||
datatype_str = `or(${datatype_str},"*")`;
|
||||
if (this.multiple)
|
||||
datatype_str = `list(${datatype_str})`;
|
||||
|
||||
if (this.option == 'dest') {
|
||||
for (let c of this.section.children) {
|
||||
const opt = c;
|
||||
if (opt.option == 'src') {
|
||||
const val = opt.cfgvalue(section_id) || opt.default;
|
||||
isOutputOnly = (val == null || val == '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.title = isOutputOnly ? _('Output zone') : _('Destination zone');
|
||||
}
|
||||
|
||||
if (this.allowlocal) {
|
||||
choices[''] = E('span', {
|
||||
'class': 'zonebadge',
|
||||
'style': firewall.getZoneColorStyle(null)
|
||||
}, [
|
||||
E('strong', _('Device')),
|
||||
(this.allowany || this.allowlocal)
|
||||
? E('span', ' (%s)'.format(this.option != 'dest' ? _('output') : _('input'))) : ''
|
||||
]);
|
||||
}
|
||||
else if (!this.multiple && (this.rmempty || this.optional)) {
|
||||
choices[''] = E('span', {
|
||||
'class': 'zonebadge',
|
||||
'style': firewall.getZoneColorStyle(null)
|
||||
}, E('em', _('unspecified')));
|
||||
}
|
||||
|
||||
if (this.allowany) {
|
||||
choices['*'] = E('span', {
|
||||
'class': 'zonebadge',
|
||||
'style': firewall.getZoneColorStyle(null)
|
||||
}, [
|
||||
E('strong', _('Any zone')),
|
||||
(this.allowany && this.allowlocal && !isOutputOnly) ? E('span', ' (%s)'.format(_('forward'))) : ''
|
||||
]);
|
||||
}
|
||||
|
||||
for (let zone of this.zones) {
|
||||
const name = zone.getName();
|
||||
const networks = zone.getNetworks();
|
||||
const ifaces = [];
|
||||
|
||||
if (!this.filter(section_id, name))
|
||||
continue;
|
||||
|
||||
for (let n of networks) {
|
||||
const network = this.lookupNetwork(n);
|
||||
|
||||
if (!network)
|
||||
continue;
|
||||
|
||||
const span = E('span', {
|
||||
'class': 'ifacebadge' + (network.isUp() ? ' ifacebadge-active' : '')
|
||||
}, network.getName() + ': ');
|
||||
|
||||
const devices = getDevices(network);
|
||||
|
||||
for (let d of devices) {
|
||||
span.appendChild(E('img', {
|
||||
'title': d.getI18n(),
|
||||
'src': L.resource('icons/%s%s.svg'.format(d.getType(), d.isUp() ? '' : '_disabled'))
|
||||
}));
|
||||
}
|
||||
|
||||
if (!devices.length)
|
||||
span.appendChild(E('em', _('(empty)')));
|
||||
|
||||
ifaces.push(span);
|
||||
}
|
||||
|
||||
if (!ifaces.length)
|
||||
ifaces.push(E('em', _('(empty)')));
|
||||
|
||||
choices[name] = E('span', {
|
||||
'class': 'zonebadge',
|
||||
'style': firewall.getZoneColorStyle(zone)
|
||||
}, [ E('strong', name) ].concat(ifaces));
|
||||
}
|
||||
|
||||
const widget = new ui.Dropdown(values, choices, {
|
||||
id: this.cbid(section_id),
|
||||
sort: true,
|
||||
multiple: this.multiple,
|
||||
optional: this.optional || this.rmempty,
|
||||
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
|
||||
select_placeholder: E('em', _('unspecified')),
|
||||
display_items: this.display_size || this.size || 3,
|
||||
dropdown_items: this.dropdown_size || this.size || 5,
|
||||
validate: L.bind(this.validate, this, section_id),
|
||||
datatype: datatype_str,
|
||||
create: !this.nocreate,
|
||||
create_markup: '' +
|
||||
'<li data-value="{{value}}">' +
|
||||
'<span class="zonebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
|
||||
'<strong>{{value}}:</strong> <em>('+_('create')+')</em>' +
|
||||
'</span>' +
|
||||
'</li>'
|
||||
});
|
||||
|
||||
const elem = widget.render();
|
||||
|
||||
if (this.option == 'src') {
|
||||
elem.addEventListener('cbi-dropdown-change', L.bind(function(ev) {
|
||||
const opt = this.map.lookupOption('dest', section_id);
|
||||
const val = ev.detail.instance.getValue();
|
||||
|
||||
if (opt == null)
|
||||
return;
|
||||
|
||||
const cbid = opt[0].cbid(section_id);
|
||||
const label = document.querySelector('label[for="widget.%s"]'.format(cbid));
|
||||
const node = document.getElementById(cbid);
|
||||
|
||||
L.dom.content(label, val == '' ? _('Output zone') : _('Destination zone'));
|
||||
|
||||
if (val == '') {
|
||||
if (L.dom.callClassMethod(node, 'getValue') == '')
|
||||
L.dom.callClassMethod(node, 'setValue', '*');
|
||||
|
||||
const emptyval = node.querySelector('[data-value=""]');
|
||||
const anyval = node.querySelector('[data-value="*"]');
|
||||
|
||||
L.dom.content(anyval.querySelector('span'), E('strong', _('Any zone')));
|
||||
|
||||
if (emptyval != null)
|
||||
emptyval.parentNode.removeChild(emptyval);
|
||||
}
|
||||
else {
|
||||
const anyval = node.querySelector('[data-value="*"]') || '';
|
||||
let emptyval = node.querySelector('[data-value=""]') || '';
|
||||
|
||||
if (emptyval == null && anyval) {
|
||||
emptyval = anyval.cloneNode(true);
|
||||
emptyval.removeAttribute('display');
|
||||
emptyval.removeAttribute('selected');
|
||||
emptyval.setAttribute('data-value', '');
|
||||
}
|
||||
|
||||
if (opt[0]?.allowlocal && emptyval)
|
||||
L.dom.content(emptyval.querySelector('span'), [
|
||||
E('strong', _('Device')), E('span', ' (%s)'.format(_('input')))
|
||||
]);
|
||||
if (opt[0]?.allowany && anyval && emptyval) {
|
||||
L.dom.content(anyval.querySelector('span'), [
|
||||
E('strong', _('Any zone')), E('span', ' (%s)'.format(_('forward')))
|
||||
]);
|
||||
|
||||
anyval.parentNode.insertBefore(emptyval, anyval);
|
||||
}
|
||||
}
|
||||
|
||||
}, this));
|
||||
}
|
||||
else if (isOutputOnly) {
|
||||
const emptyval = elem.querySelector('[data-value=""]');
|
||||
emptyval.parentNode.removeChild(emptyval);
|
||||
}
|
||||
|
||||
return elem;
|
||||
},
|
||||
});
|
||||
|
||||
var CBIZoneForwards = form.DummyValue.extend({
|
||||
__name__: 'CBI.ZoneForwards',
|
||||
|
||||
load(section_id) {
|
||||
return Promise.all([
|
||||
firewall.getDefaults(),
|
||||
firewall.getZones(),
|
||||
network.getNetworks(),
|
||||
network.getDevices()
|
||||
]).then(L.bind(function(dznd) {
|
||||
this.defaults = dznd[0];
|
||||
this.zones = dznd[1];
|
||||
this.networks = dznd[2];
|
||||
this.devices = dznd[3];
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
renderZone(zone) {
|
||||
const name = zone.getName();
|
||||
const networks = zone.getNetworks();
|
||||
const devices = zone.getDevices();
|
||||
const subnets = zone.getSubnets();
|
||||
const ifaces = [];
|
||||
|
||||
for (let n of networks) {
|
||||
const network = this.networks.filter(function(net) { return net.getName() == n })[0];
|
||||
|
||||
if (!network)
|
||||
continue;
|
||||
|
||||
const span = E('span', {
|
||||
'class': 'ifacebadge' + (network.isUp() ? ' ifacebadge-active' : '')
|
||||
}, network.getName() + ': ');
|
||||
|
||||
const subdevs = getDevices(network);
|
||||
|
||||
for (let s of subdevs) {
|
||||
span.appendChild(E('img', {
|
||||
'title': s.getI18n(),
|
||||
'src': L.resource('icons/%s%s.svg'.format(s.getType(), s.isUp() ? '' : '_disabled'))
|
||||
}));
|
||||
}
|
||||
|
||||
if (!subdevs.length)
|
||||
span.appendChild(E('em', _('(empty)')));
|
||||
|
||||
ifaces.push(span);
|
||||
}
|
||||
|
||||
for (let d of devices) {
|
||||
const device = this.devices.filter(function(dev) { return dev.getName() == d })[0];
|
||||
const title = device ? device.getI18n() : _('Absent Interface');
|
||||
const type = device ? device.getType() : 'ethernet';
|
||||
const up = device ? device.isUp() : false;
|
||||
|
||||
ifaces.push(E('span', { 'class': 'ifacebadge' }, [
|
||||
E('img', {
|
||||
'title': title,
|
||||
'src': L.resource('icons/%s%s.svg'.format(type, up ? '' : '_disabled'))
|
||||
}),
|
||||
device ? device.getName() : d
|
||||
]));
|
||||
}
|
||||
|
||||
if (subnets.length > 0)
|
||||
ifaces.push(E('span', { 'class': 'ifacebadge' }, [ '{ %s }'.format(subnets.join('; ')) ]));
|
||||
|
||||
if (!ifaces.length)
|
||||
ifaces.push(E('span', { 'class': 'ifacebadge' }, E('em', _('(empty)'))));
|
||||
|
||||
return E('label', {
|
||||
'class': 'zonebadge cbi-tooltip-container',
|
||||
'style': firewall.getZoneColorStyle(zone)
|
||||
}, [
|
||||
E('strong', name),
|
||||
E('div', { 'class': 'cbi-tooltip' }, ifaces)
|
||||
]);
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
const value = (cfgvalue != null) ? cfgvalue : this.default;
|
||||
const zone = this.zones.filter(function(z) { return z.getName() == value })[0];
|
||||
|
||||
if (!zone)
|
||||
return E([]);
|
||||
|
||||
const forwards = zone.getForwardingsBy('src');
|
||||
const dzones = [];
|
||||
|
||||
for (var i = 0; i < forwards.length; i++) {
|
||||
const dzone = forwards[i].getDestinationZone();
|
||||
|
||||
if (!dzone)
|
||||
continue;
|
||||
|
||||
dzones.push(this.renderZone(dzone));
|
||||
}
|
||||
|
||||
if (!dzones.length)
|
||||
dzones.push(E('label', { 'class': 'zonebadge zonebadge-empty' },
|
||||
E('strong', this.defaults.getForward())));
|
||||
else
|
||||
dzones.push(E('label', { 'class': 'zonebadge zonebadge-empty' },
|
||||
E('strong', '%s %s'.format(this.defaults.getForward(), ('all others')))));
|
||||
|
||||
return E('div', { 'class': 'zone-forwards' }, [
|
||||
E('div', { 'class': 'zone-src' }, this.renderZone(zone)),
|
||||
E('span', '⇒'),
|
||||
E('div', { 'class': 'zone-dest' }, dzones)
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
const CBIIPSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.IPSelect',
|
||||
|
||||
load(section_id) {
|
||||
return network.getDevices().then(L.bind(function(devices) {
|
||||
this.devices = devices;
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
renderIfaceBadge(device, ip) {
|
||||
return E('div', {}, [
|
||||
ip,
|
||||
' ',
|
||||
E('span', { 'class': 'ifacebadge', }, [ device.getName(),
|
||||
E('img', {
|
||||
'title': device.getI18n(),
|
||||
'src': L.resource('icons/%s%s.svg'.format(device.getType(), device.isUp() ? '' : '_disabled'))
|
||||
})
|
||||
]),
|
||||
]);
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
let values = L.toArray((cfgvalue != null) ? cfgvalue : this.default);
|
||||
const choices = {};
|
||||
const checked = {};
|
||||
|
||||
for (const val of values)
|
||||
checked[val] = true;
|
||||
|
||||
values = [];
|
||||
|
||||
if (!this.multiple && (this.rmempty || this.optional))
|
||||
choices[''] = E('em', _('unspecified'));
|
||||
|
||||
|
||||
for (const device of (this.devices || [])) {
|
||||
const name = device.getName();
|
||||
|
||||
if (name == this.exclude || !this.filter(section_id, name))
|
||||
continue;
|
||||
|
||||
if (name == 'loopback' && !this.loopback)
|
||||
continue;
|
||||
|
||||
if (this.novirtual && device.isVirtual())
|
||||
continue;
|
||||
|
||||
for (const ip of [...device.getIPAddrs(), ...device.getIP6Addrs()]) {
|
||||
const iponly = ip.split('/')?.[0]
|
||||
if (checked[iponly])
|
||||
values.push(iponly);
|
||||
choices[iponly] = this.renderIfaceBadge(device, iponly);
|
||||
}
|
||||
}
|
||||
|
||||
const widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
|
||||
id: this.cbid(section_id),
|
||||
sort: true,
|
||||
multiple: this.multiple,
|
||||
optional: this.optional || this.rmempty,
|
||||
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
|
||||
select_placeholder: E('em', _('unspecified')),
|
||||
display_items: this.display_size || this.size || 2,
|
||||
dropdown_items: this.dropdown_size || this.size || 5,
|
||||
datatype: this.multiple ? 'list(ipaddr)' : 'ipaddr',
|
||||
validate: L.bind(this.validate, this, section_id),
|
||||
create: false,
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
},
|
||||
|
||||
textvalue(section_id) {
|
||||
const cfgvalue = this.cfgvalue(section_id);
|
||||
const values = L.toArray((cfgvalue != null) ? cfgvalue : this.default);
|
||||
const rv = E([]);
|
||||
|
||||
for (const device of (this.devices || [])) {
|
||||
for (const ip of [...device.getIPAddrs(), ...device.getIP6Addrs()]) {
|
||||
const iponly = ip.split('/')[0];
|
||||
if (values.indexOf(iponly) === -1)
|
||||
continue;
|
||||
|
||||
if (rv.childNodes.length)
|
||||
rv.appendChild(document.createTextNode(' '));
|
||||
|
||||
rv.appendChild(this.renderIfaceBadge(device, iponly));
|
||||
}
|
||||
}
|
||||
|
||||
if (!rv.firstChild)
|
||||
rv.appendChild(E('em', _('unspecified')));
|
||||
|
||||
return rv;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
var CBINetworkSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.NetworkSelect',
|
||||
|
||||
load(section_id) {
|
||||
return network.getNetworks().then(L.bind(function(networks) {
|
||||
this.networks = networks;
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
renderIfaceBadge(network) {
|
||||
const span = E('span', { 'class': 'ifacebadge' }, network.getName() + ': ');
|
||||
const devices = getDevices(network);
|
||||
|
||||
for (let d of devices) {
|
||||
span.appendChild(E('img', {
|
||||
'title': d.getI18n(),
|
||||
'src': L.resource('icons/%s%s.svg'.format(d.getType(), d.isUp() ? '' : '_disabled'))
|
||||
}));
|
||||
}
|
||||
|
||||
if (!devices.length) {
|
||||
span.appendChild(E('em', { 'class': 'hide-close' }, _('(no interfaces attached)')));
|
||||
span.appendChild(E('em', { 'class': 'hide-open' }, '-'));
|
||||
}
|
||||
|
||||
return span;
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
let values = L.toArray((cfgvalue != null) ? cfgvalue : this.default);
|
||||
const choices = {};
|
||||
const checked = {};
|
||||
|
||||
for (var i = 0; i < values.length; i++)
|
||||
checked[values[i]] = true;
|
||||
|
||||
values = [];
|
||||
|
||||
if (!this.multiple && (this.rmempty || this.optional))
|
||||
choices[''] = E('em', _('unspecified'));
|
||||
|
||||
for (let network of this.networks) {
|
||||
const name = network.getName();
|
||||
|
||||
if (name == this.exclude || !this.filter(section_id, name))
|
||||
continue;
|
||||
|
||||
if (name == 'loopback' && !this.loopback)
|
||||
continue;
|
||||
|
||||
if (this.novirtual && network.isVirtual())
|
||||
continue;
|
||||
|
||||
if (checked[name])
|
||||
values.push(name);
|
||||
|
||||
choices[name] = this.renderIfaceBadge(network);
|
||||
}
|
||||
|
||||
const widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
|
||||
id: this.cbid(section_id),
|
||||
sort: true,
|
||||
multiple: this.multiple,
|
||||
optional: this.optional || this.rmempty,
|
||||
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
|
||||
select_placeholder: E('em', _('unspecified')),
|
||||
display_items: this.display_size || this.size || 3,
|
||||
dropdown_items: this.dropdown_size || this.size || 5,
|
||||
datatype: this.multiple ? 'list(uciname)' : 'uciname',
|
||||
validate: L.bind(this.validate, this, section_id),
|
||||
create: !this.nocreate,
|
||||
create_markup: '' +
|
||||
'<li data-value="{{value}}">' +
|
||||
'<span class="ifacebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
|
||||
'{{value}}: <em>('+_('create')+')</em>' +
|
||||
'</span>' +
|
||||
'</li>'
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
},
|
||||
|
||||
textvalue(section_id) {
|
||||
const cfgvalue = this.cfgvalue(section_id);
|
||||
const values = L.toArray((cfgvalue != null) ? cfgvalue : this.default);
|
||||
const rv = E([]);
|
||||
|
||||
for (let network of this.networks) {
|
||||
const name = network.getName();
|
||||
|
||||
if (values.indexOf(name) == -1)
|
||||
continue;
|
||||
|
||||
if (rv.length)
|
||||
L.dom.append(rv, ' ');
|
||||
|
||||
L.dom.append(rv, this.renderIfaceBadge(network));
|
||||
}
|
||||
|
||||
if (!rv.firstChild)
|
||||
rv.appendChild(E('em', _('unspecified')));
|
||||
|
||||
return rv;
|
||||
},
|
||||
});
|
||||
|
||||
var CBIDeviceSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.DeviceSelect',
|
||||
|
||||
load(section_id) {
|
||||
return Promise.all([
|
||||
network.getDevices(),
|
||||
this.noaliases ? null : network.getNetworks()
|
||||
]).then(L.bind(function(data) {
|
||||
this.devices = data[0];
|
||||
this.networks = data[1];
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
renderWidget(section_id, option_index, cfgvalue) {
|
||||
var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default),
|
||||
choices = {},
|
||||
checked = {},
|
||||
order = [];
|
||||
|
||||
for (var i = 0; i < values.length; i++)
|
||||
checked[values[i]] = true;
|
||||
|
||||
values = [];
|
||||
|
||||
if (!this.multiple && (this.rmempty || this.optional))
|
||||
choices[''] = E('em', _('unspecified'));
|
||||
|
||||
for (let device of this.devices) {
|
||||
const name = device.getName();
|
||||
const type = device.getType();
|
||||
|
||||
if (name == 'lo' || name == this.exclude || !this.filter(section_id, name))
|
||||
continue;
|
||||
|
||||
if (this.noaliases && type == 'alias')
|
||||
continue;
|
||||
|
||||
if (this.nobridges && type == 'bridge')
|
||||
continue;
|
||||
|
||||
if (this.noinactive && device.isUp() == false)
|
||||
continue;
|
||||
|
||||
const item = E([
|
||||
E('img', {
|
||||
'title': device.getI18n(),
|
||||
'src': L.resource('icons/%s%s.svg'.format(type, device.isUp() ? '' : '_disabled'))
|
||||
}),
|
||||
E('span', { 'class': 'hide-open' }, [ name ]),
|
||||
E('span', { 'class': 'hide-close'}, [ device.getI18n() ])
|
||||
]);
|
||||
|
||||
const networks = device.getNetworks();
|
||||
|
||||
if (networks.length > 0)
|
||||
L.dom.append(item.lastChild, [ ' (', networks.map(function(n) { return n.getName() }).join(', '), ')' ]);
|
||||
|
||||
if (checked[name])
|
||||
values.push(name);
|
||||
|
||||
choices[name] = item;
|
||||
order.push(name);
|
||||
}
|
||||
|
||||
if (this.networks != null) {
|
||||
for (let net of this.networks) {
|
||||
const device = network.instantiateDevice('@%s'.format(net.getName()), net);
|
||||
const name = device.getName();
|
||||
|
||||
if (name == '@loopback' || name == this.exclude || !this.filter(section_id, name))
|
||||
continue;
|
||||
|
||||
if (this.noinactive && net.isUp() == false)
|
||||
continue;
|
||||
|
||||
const item = E([
|
||||
E('img', {
|
||||
'title': device.getI18n(),
|
||||
'src': L.resource('icons/alias%s.svg'.format(device.isUp() ? '' : '_disabled'))
|
||||
}),
|
||||
E('span', { 'class': 'hide-open' }, [ name ]),
|
||||
E('span', { 'class': 'hide-close'}, [ device.getI18n() ])
|
||||
]);
|
||||
|
||||
if (checked[name])
|
||||
values.push(name);
|
||||
|
||||
choices[name] = item;
|
||||
order.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.includeips) {
|
||||
this.devices.forEach(net_dev => {
|
||||
['getIPAddrs', 'getIP6Addrs'].forEach(fn => {
|
||||
net_dev[fn]().forEach(addr => {
|
||||
const name = addr.split('/')[0];
|
||||
if (checked[name]) values.push(name);
|
||||
|
||||
choices[name] = E([], [name, ' (', E('strong', net_dev.getName()), ')']);
|
||||
order.push(name);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.nocreate) {
|
||||
const keys = Object.keys(checked).sort(L.naturalCompare);
|
||||
|
||||
for (let k of keys) {
|
||||
if (choices.hasOwnProperty(k))
|
||||
continue;
|
||||
|
||||
choices[k] = E([
|
||||
E('img', {
|
||||
'title': _('Absent Interface'),
|
||||
'src': L.resource('icons/ethernet_disabled.svg')
|
||||
}),
|
||||
E('span', { 'class': 'hide-open' }, [ k ]),
|
||||
E('span', { 'class': 'hide-close'}, [ '%s: "%h"'.format(_('Absent Interface'), k) ])
|
||||
]);
|
||||
|
||||
values.push(k);
|
||||
order.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
const widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
|
||||
id: this.cbid(section_id),
|
||||
sort: order,
|
||||
multiple: this.multiple,
|
||||
optional: this.optional || this.rmempty,
|
||||
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
|
||||
select_placeholder: E('em', _('unspecified')),
|
||||
display_items: this.display_size || this.size || 3,
|
||||
dropdown_items: this.dropdown_size || this.size || 5,
|
||||
validate: L.bind(this.validate, this, section_id),
|
||||
create: !this.nocreate,
|
||||
create_markup: '' +
|
||||
'<li data-value="{{value}}">' +
|
||||
'<img title="'+_('Custom Interface')+': "{{value}}"" src="'+L.resource('icons/ethernet_disabled.svg')+'" />' +
|
||||
'<span class="hide-open">{{value}}</span>' +
|
||||
'<span class="hide-close">'+_('Custom Interface')+': "{{value}}"</span>' +
|
||||
'</li>'
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
},
|
||||
});
|
||||
|
||||
var CBIUserSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.UserSelect',
|
||||
|
||||
load(section_id) {
|
||||
return getUsers().then(L.bind(function(users) {
|
||||
delete this.keylist;
|
||||
delete this.vallist;
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
this.value(users[i]);
|
||||
}
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
var CBIGroupSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.GroupSelect',
|
||||
|
||||
load(section_id) {
|
||||
return getGroups().then(L.bind(function(groups) {
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
this.value(groups[i]);
|
||||
}
|
||||
|
||||
return this.super('load', section_id);
|
||||
}, this));
|
||||
},
|
||||
|
||||
filter(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
var CBIWifidogxGroupSelect = form.ListValue.extend({
|
||||
__name__: 'CBI.WifidogxGroupSelect',
|
||||
|
||||
// group_type: 1: Domain Group, 2: MAC Group
|
||||
// add a new property to store the group type
|
||||
group_type: '1',
|
||||
|
||||
load: function(section_id) {
|
||||
this.sappList = [];
|
||||
var sections = uci.sections('wifidogx', 'group');
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i]['g_type'] == this.group_type)
|
||||
this.sappList.push(sections[i]['.name']);
|
||||
}
|
||||
|
||||
return this.super('load', section_id);
|
||||
},
|
||||
|
||||
setGroupType: function(group_type) {
|
||||
if (group_type == 'mac') {
|
||||
this.group_type = '2';
|
||||
} else if (group_type == 'wildcard') {
|
||||
this.group_type = '3';
|
||||
}
|
||||
},
|
||||
|
||||
filter: function(section_id, value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
renderWidget: function(section_id, option_index, cfgvalue) {
|
||||
var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default),
|
||||
choices = {},
|
||||
checked = {};
|
||||
|
||||
for (var i = 0; i < values.length; i++)
|
||||
checked[values[i]] = true;
|
||||
|
||||
values = [];
|
||||
|
||||
if (!this.multiple && (this.rmempty || this.optional))
|
||||
choices[''] = E('em', _('unspecified'));
|
||||
|
||||
for (var i = 0; i < this.sappList.length; i++) {
|
||||
var name = this.sappList[i];
|
||||
|
||||
if (checked[name])
|
||||
values.push(name);
|
||||
|
||||
choices[name] = E('span', { 'class': 'ifacebadge' }, name);
|
||||
}
|
||||
|
||||
var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
|
||||
id: this.cbid(section_id),
|
||||
sort: true,
|
||||
multiple: this.multiple,
|
||||
optional: this.optional || this.rmempty,
|
||||
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
|
||||
select_placeholder: E('em', _('unspecified')),
|
||||
display_items: this.display_size || this.size || 3,
|
||||
dropdown_items: this.dropdown_size || this.size || 5,
|
||||
validate: L.bind(this.validate, this, section_id),
|
||||
create: !this.nocreate,
|
||||
create_markup: '' +
|
||||
'<li data-value="{{value}}">' +
|
||||
'<span class="ifacebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
|
||||
'{{value}}: <em>('+_('create')+')</em>' +
|
||||
'</span>' +
|
||||
'</li>'
|
||||
});
|
||||
|
||||
return widget.render();
|
||||
}
|
||||
});
|
||||
|
||||
return L.Class.extend({
|
||||
ZoneSelect: CBIZoneSelect,
|
||||
ZoneForwards: CBIZoneForwards,
|
||||
IPSelect: CBIIPSelect,
|
||||
NetworkSelect: CBINetworkSelect,
|
||||
DeviceSelect: CBIDeviceSelect,
|
||||
UserSelect: CBIUserSelect,
|
||||
GroupSelect: CBIGroupSelect,
|
||||
WifidogxGroupSelect: CBIWifidogxGroupSelect,
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
/* replaced by luci.js */
|
||||