integrate jsonschema2markdown; add support for inline markdown rendering from templates

This commit is contained in:
James Brumond 2023-05-13 20:31:00 -07:00
parent 4061b40eb4
commit 699c018825
Signed by: james
GPG Key ID: E8F2FC44BAA3357A
19 changed files with 1793 additions and 142 deletions

2
.gitignore vendored
View File

@ -1,4 +1,2 @@
node_modules
build
docs
www

View File

@ -0,0 +1,175 @@
(() => {
const animation = 'linear .5s';
const color_scheme = 'color_scheme';
const color_scheme_attr = 'data-color-scheme';
const transition_attr = 'data-color-transition-enabled';
const prefers_dark_scheme = window.matchMedia('(prefers-color-scheme: dark)');
// Make sure we set the correct starting color scheme where loading
const override = localStorage.getItem(color_scheme);
if (override) {
document.body.setAttribute(color_scheme_attr, override);
}
setTimeout(() => {
if (document.body.scrollHeight > 30000) {
console.warn('document too large, disabling color theme transition animation');
return;
}
document.body.setAttribute(transition_attr, '');
}, 50);
const size = 1.25;
const styles = `
:host {
display: contents;
}
:host .wrapper {
width: ${size}rem;
height: ${size}rem;
padding: 0.5rem;
border-radius: 100%;
cursor: pointer;
overflow: hidden;
position: relative;
}
:host .wrapper .icons {
width: ${size * 2}rem;
display: flex;
flex-direction: row;
justify-content: space-between;
transition: transform ${animation};
pointer-events: none;
}
:host .wrapper .icons[data-mode='light'] {
/* */
}
:host .wrapper .icons[data-mode='dark'] {
transform: translateX(-${size}rem);
}
:host svg.icon {
--icon-size: ${size}rem;
transition: opacity ${animation};
}
:host svg.icon.sun {
color: var(--theme-text-body);
}
:host [data-mode='dark'] svg.icon.sun {
opacity: 0;
}
:host svg.icon.moon {
color: var(--theme-text-body);
}
:host [data-mode='light'] svg.icon.moon {
opacity: 0;
}
`;
const template = `
<style>${styles}</style>
<div class="wrapper" title="Toggle Light / Dark Mode" tabindex="0" role="button" aria-pressed="false">
<div class="icons">
{{{ icons.sun }}}
{{{ icons.moon }}}
</div>
</div>
`;
customElements.define('color-scheme-toggle-button',
class ColorSchemeToggleButton extends HTMLElement {
#wrapper = null;
#icons = null;
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
this.#wrapper = this.shadowRoot.querySelector('.wrapper');
this.#icons = this.shadowRoot.querySelector('.icons');
this.update_icons();
}
connectedCallback() {
this.addEventListener('click', this.onSelect);
this.addEventListener('keydown', this.onKeydown);
this.addEventListener('keyup', this.onKeyup);
}
disconnectedCallback() {
this.removeEventListener('click', this.onSelect);
this.removeEventListener('keydown', this.onKeydown);
this.removeEventListener('keyup', this.onKeyup);
}
onKeydown = (/** @type KeyboardEvent */ event) => {
if (event.keyCode === 32) {
event.preventDefault();
}
if (event.keyCode === 13) {
event.preventDefault();
this.onSelect();
}
};
onKeyup = (/** @type KeyboardEvent */ event) => {
if (event.keyCode === 32) {
event.preventDefault();
this.onSelect();
}
};
onSelect = () => {
toggle();
this.update_icons();
};
update_icons() {
const current = get_current();
this.#icons.setAttribute('data-mode', current);
this.#wrapper.setAttribute('aria-pressed', current === 'dark');
}
}
);
function get_current() {
const override = localStorage.getItem(color_scheme);
if (override) {
return override;
}
return prefers_dark_scheme.matches ? 'dark' : 'light';
}
function toggle() {
if (document.body.hasAttribute(color_scheme_attr)) {
localStorage.removeItem(color_scheme);
document.body.removeAttribute(color_scheme_attr);
}
else {
const preference = prefers_dark_scheme.matches ? 'light' : 'dark';
localStorage.setItem(color_scheme, preference);
document.body.setAttribute(color_scheme_attr, preference);
}
}
})();

View File

@ -0,0 +1,129 @@
(() => {
const size = 1.25;
const outline_attr = 'data-show-outline';
const styles = `
:host {
display: contents;
}
:host .wrapper {
width: ${size}rem;
height: ${size}rem;
padding: 0.5rem;
border-radius: 100%;
cursor: pointer;
overflow: hidden;
position: relative;
}
:host svg.icon {
--icon-size: ${size}rem;
color: var(--theme-text-body);
position: absolute;
top: 0.5rem;
left: 0.5rem;
pointer-events: none;
transition: color linear .5s;
}
`;
const template = `
<style>${styles}</style>
<div class="wrapper" title="Toggle Outline" tabindex="0" role="button" aria-pressed="false">
{{{ icons.list }}}
</div>
<nav id="outline-panel" aria-hidden="true">
<!-- todo: i18n -->
<h2>Outline</h2>
</nav>
`;
customElements.define('outline-button',
class OutlineButton extends HTMLElement {
#wrapper = null;
#outline = null;
#outline_built = false;
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
this.#wrapper = this.shadowRoot.querySelector('.wrapper');
this.#outline = this.shadowRoot.querySelector('#outline-panel');
this.#outline.parentNode.removeChild(this.#outline);
document.body.appendChild(this.#outline);
}
connectedCallback() {
this.addEventListener('click', this.onSelect);
this.addEventListener('keydown', this.onKeydown);
this.addEventListener('keyup', this.onKeyup);
}
disconnectedCallback() {
this.removeEventListener('click', this.onSelect);
this.removeEventListener('keydown', this.onKeydown);
this.removeEventListener('keyup', this.onKeyup);
}
onKeydown = (/** @type KeyboardEvent */ event) => {
if (event.keyCode === 32) {
event.preventDefault();
}
if (event.keyCode === 13) {
event.preventDefault();
this.onSelect();
}
};
onKeyup = (/** @type KeyboardEvent */ event) => {
if (event.keyCode === 32) {
event.preventDefault();
this.onSelect();
}
};
onSelect = () => {
if (! this.#outline_built) {
const root_selector = this.getAttribute('content-root');
this.#outline.innerHTML += `<ol>${build_outline(root_selector)}</ol>`;
this.#outline_built = true;
}
if (document.body.hasAttribute(outline_attr)) {
document.body.removeAttribute(outline_attr);
this.#outline.setAttribute('aria-hidden', 'true');
this.#wrapper.setAttribute('aria-pressed', 'false');
}
else {
document.body.setAttribute(outline_attr, '');
this.#outline.removeAttribute('aria-hidden');
this.#wrapper.setAttribute('aria-pressed', 'true');
}
};
}
);
function build_outline(root_selector) {
const root = document.querySelector(root_selector);
const headings = root.querySelectorAll('h1, h2, h3, h4, h5, h6');
const outline = [ ];
for (const heading of headings) {
outline.push(`
<li data-depth="${heading.tagName.toLowerCase()}">
<a href="#${heading.id}">${heading.innerText}</a>
</li>
`);
}
return outline.join('');
}
})();

View File

@ -0,0 +1,105 @@
(() => {
const template = `
<style>
ol {
list-style: none;
padding: 0;
}
li[data-depth='h1'] {
font-size: 1.2rem;
font-weight: 700;
margin-inline-start: 1rem;
}
li[data-depth='h2'] {
font-size: 1.1rem;
font-weight: 600;
margin-inline-start: 2rem;
}
li[data-depth='h3'] {
margin-inline-start: 3rem;
}
li[data-depth='h4'] {
font-size: 0.9rem;
margin-inline-start: 4rem;
}
li[data-depth='h5'] {
font-size: 0.9rem;
margin-inline-start: 5rem;
}
li[data-depth='h6'] {
font-size: 0.9rem;
margin-inline-start: 6rem;
}
a {
color: var(--theme-text-link);
}
a:active,
a:hover,
a:focus {
color: var(--theme-text-link-active);
}
a:visited {
color: var(--theme-text-link-visited);
}
</style>
<nav id="outline-inline" aria-hidden="true">
<em>Outline will render when the page has loaded...</em>
</nav>
`;
customElements.define('outline-inline',
class OutlineButton extends HTMLElement {
#outline = null;
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = template;
this.#outline = this.shadowRoot.querySelector('#outline-inline');
}
connectedCallback() {
if (document.readyState === 'complete') {
this.#render();
}
window.addEventListener('DOMContentLoaded', () => {
this.#render();
});
}
#render() {
const root_selector = this.getAttribute('content-root');
const outline = build_outline(root_selector);
this.#outline.innerHTML = `<ol>${outline}</ol>`;
}
}
);
function build_outline(root_selector) {
const root = document.querySelector(root_selector);
const headings = root.querySelectorAll('h1, h2, h3, h4, h5, h6');
const outline = [ ];
for (const heading of headings) {
outline.push(`
<li data-depth="${heading.tagName.toLowerCase()}">
<a href="#${heading.id}">${heading.innerText}</a>
</li>
`);
}
return outline.join('');
}
})();

468
extras/prism.css Normal file
View File

@ -0,0 +1,468 @@
/* PrismJS 1.24.1
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+http+jsx+tsx+typescript&plugins=line-highlight+line-numbers+treeview */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*
* ---
* Modified for use with customizable color variables and light/dark theming
*/
code[class*="language-"],
pre[class*="language-"] {
color: var(--theme-code-normal);
background: none;
text-shadow: 0 1px var(--theme-code-shadow);
font-family: var(--font-monospace);
font-weight: 400;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: var(--theme-code-selection);
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: var(--theme-code-selection);
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: var(--theme-code-background);
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1rem;
border-radius: .3rem;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: var(--theme-code-comment);
}
.token.punctuation {
color: var(--theme-code-punc);
}
.token.namespace {
opacity: .7;
}
.token.constant,
.token.symbol,
.token.deleted {
color: var(--theme-code-const-literal);
}
.token.tag {
color: var(--theme-code-tag);
}
.token.number {
color: var(--theme-code-number-literal);
}
.token.boolean {
color: var(--theme-code-boolean-literal);
}
.token.selector,
.token.attr-name {
color: var(--theme-code-attr-name);
}
.token.builtin {
color: var(--theme-code-builtin);
}
.token.string,
.token.char,
.token.inserted {
color: var(--theme-code-string);
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: var(--theme-code-operator);
}
.token.atrule,
.token.attr-value,
.token.keyword,
.token.request-line .token.method,
.token.request-line .token.http-version,
.token.response-status .token.http-version {
color: var(--theme-code-keyword);
}
.token.function {
color: var(--theme-code-func-name);
}
.token.class-name {
color: var(--theme-code-class-name);
}
.token.regex,
.token.important {
color: var(--theme-code-regex-important);
}
.token.property,
.token.variable {
color: var(--theme-code-variable);
}
.token.important,
.token.bold {
font-weight: 700;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
pre[data-line] {
position: relative;
padding: 1rem 0 1rem 3rem;
}
.line-highlight {
position: absolute;
left: 0;
right: 0;
padding: inherit 0;
margin-top: 1rem;
background: var(--theme-code-line-highlight);
pointer-events: none;
line-height: inherit;
white-space: pre;
}
@media print {
.line-highlight {
/*
* This will prevent browsers from replacing the background color with white.
* It's necessary because the element is layered on top of the displayed code.
*/
-webkit-print-color-adjust: exact;
color-adjust: exact;
}
}
.line-highlight:before,
.line-highlight[data-end]:after {
content: attr(data-start);
position: absolute;
top: .4rem;
left: .6rem;
min-width: 1rem;
padding: 0 .5rem;
background: var(--theme-code-line-highlight);
font: bold 65%/1.5 sans-serif;
text-align: center;
vertical-align: .3rem;
border-radius: 999px;
text-shadow: none;
box-shadow: 0 1px white;
}
.line-highlight[data-end]:after {
content: attr(data-end);
top: auto;
bottom: .4rem;
}
.line-numbers .line-highlight:before,
.line-numbers .line-highlight:after {
content: none;
}
pre[id].linkable-line-numbers span.line-numbers-rows {
pointer-events: all;
}
pre[id].linkable-line-numbers span.line-numbers-rows > span:before {
cursor: pointer;
}
pre[id].linkable-line-numbers span.line-numbers-rows > span:hover:before {
/* TODO: Do something with this color */
background-color: rgba(128, 128, 128, .2);
}
pre[class*="language-"].line-numbers {
position: relative;
padding-left: 3.8rem;
counter-reset: linenumber;
}
pre[class*="language-"].line-numbers > code {
position: relative;
white-space: inherit;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
font-size: 100%;
left: -3.8rem;
width: 3rem; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
border-right: 1px solid var(--theme-code-gutter-divider);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.line-numbers-rows > span {
display: block;
counter-increment: linenumber;
}
.line-numbers-rows > span:before {
content: counter(linenumber);
color: var(--theme-code-line-number);
display: block;
padding-right: 0.8rem;
text-align: right;
}
.token.treeview-part .entry-line {
position: relative;
text-indent: -99rem;
display: inline-block;
vertical-align: top;
width: 1.2rem;
}
.token.treeview-part .entry-line:before,
.token.treeview-part .line-h:after {
content: "";
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
}
/* TODO: Do something with these colors */
.token.treeview-part .line-h:before,
.token.treeview-part .line-v:before {
border-left: 1px solid #ccc;
}
.token.treeview-part .line-v-last:before {
height: 50%;
border-left: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.token.treeview-part .line-h:after {
height: 50%;
border-bottom: 1px solid #ccc;
}
.token.treeview-part .entry-name {
position: relative;
display: inline-block;
vertical-align: top;
}
.token.treeview-part .entry-name.dotfile {
opacity: 0.5;
}
/* @GENERATED-FONT */
@font-face {
font-family: "PrismTreeview";
/**
* This font is generated from the .svg files in the `icons` folder. See the `treeviewIconFont` function in
* `gulpfile.js/index.js` for more information.
*
* Use the following escape sequences to refer to a specific icon:
*
* - \ea01 file
* - \ea02 folder
* - \ea03 image
* - \ea04 audio
* - \ea05 video
* - \ea06 text
* - \ea07 code
* - \ea08 archive
* - \ea09 pdf
* - \ea0a excel
* - \ea0b powerpoint
* - \ea0c word
*/
src: url("data:application/font-woff;base64,d09GRgABAAAAAAgYAAsAAAAAEGAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPwAAAFY1UkH9Y21hcAAAAYQAAAB/AAACCtvO7yxnbHlmAAACBAAAA+MAAAlACm1VqmhlYWQAAAXoAAAAKgAAADZfxj5jaGhlYQAABhQAAAAYAAAAJAFbAMFobXR4AAAGLAAAAA4AAAA0CGQAAGxvY2EAAAY8AAAAHAAAABwM9A9CbWF4cAAABlgAAAAfAAAAIAEgAHZuYW1lAAAGeAAAATcAAAJSfUrk+HBvc3QAAAewAAAAZgAAAIka0DSfeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGRYyjiBgZWBgaGQoRZISkLpUAYOBj0GBiYGVmYGrCAgzTWFweEV4ysehs1ArgDDFgZGIA3CDAB2tQjAAHic7ZHLEcMwCESfLCz/VEoKSEE5parURxMOC4c0Ec283WGFdABgBXrwCAzam4bOK9KWeefM3Hhmjyn3ed+hTRq1pS7Ra/HjYGPniHcXMy4G/zNTP7/KW5HTXArkvdBW3ArN19dCG/NRIN8K5HuB/CiQn4U26VeBfBbML9NEH78AeJyVVc1u20YQ3pn905JcSgr/YsuSDTEg3cR1bFEkYyS1HQcQ2jQF2hot6vYSoECKnnPLA/SWUy9NTr31Bfp+6azsNI0SGiolzu7ODnfn+2Z2lnHG3rxhr9nfLGKbLGesncAYYnUHpsVnMG/uwyzNdFIVd6HI6twp8+R3LpT4TSglLoTHwwJgG2/dFvKrl9yI507/p5CCq4LTxB/PlPjkFaMHnWB/0S9je7RTPS+utnGtom1T2q5pk/e3H0M1S18rsXAL7wgpxQuhAmteGGvNjmcfGXuwnFNOPCXxeOGmnjrBLWNyBeNtVq2Hs03yus1aPS3mzSyNVSfu588iW1Q93x/4fjcHn+5EkS2tMxr4xIRa8ese+4L9uKZnxEqs8+ldyN9atU02a5t5uQ8hZGms1QTKpaKYqnipiNNOAIeIADC0JNEOYY+jtSgFoOchiAjRGFACpUTRje8bwIYWGCDEgENY8MEu9bnCYCdAxftoNg0KiSpUtPaHcanYwzXRu6T4r40b5npal3V7UHWCPJW9niyl1vIHgoujEXZjudBkeWkOeMQBRmbEPhKzij1i52t6/TadL+3q7H0U1eq4E8cG4gIIwQLx8VX7ToPXgPrehVc5QXHR7gMSmwjKfaYAP4KvZV+yn9bE18y2IY37LvtyrSg3i7ZK++B603ndlg/gBJpZRsfpBI6hyiaQ6FjlnThz8lAC3LgBIMnXDOAXxBQ4SIgiEhx2AcGCAwAhwjXRpCQms42bwAUt75BvAwgONzdgOfWEwzk4Ylzj4mz+5YEzzXzWX9aNlk7ot65y5QnBHsNlm6zDTu7sspRqG4V+fgJ1lVBZ07Nm7s5nemo3Lf3PO7iwtnroQ5/YDGwPRUip6fV6L+27p+wCHwSvPs85UnHqId8NAn5IBsKdv95KrL9m31Gsf2a/rluDslk1y1J9GE+LUmmVT/OyOHaFKGnapt2H5XeJTmKd6qYNoVVZOy+pWzr7rMip3ndG/4mQSoUcMbAqG/YNIAdXhkAqTVruXhocSKN0iS4Rwj7vSS4fcF/La07BfeQSuRAcFeW+9igjwPhhYPpGCBCBHhxiKMyFMFT7ziRH7RtfIWdiha+TdW+Rqs7bLHdN2ZJIKl0um0x3op9saYr0REeRdj09pl43pMzz4tjztrY8L4o8bzT+oLY27PR/eFtXs/YY5vtwB5Iqad14eYN0ujveMaGWqkdU3TKbQSC5Uvxaf4fA7SAQ3r2tEfIhd4duld91bwMisjqBw22orthNcroXl7KqO1329HBgAexgoCfGAwiDPoBnriki3lmNojrzvD0tjo6E3vPYP6E2BMIAeJxjYGRgYADiY8t3FsTz23xl4GbYzIAB/v9nWM6wBcjgYGAC8QH+QQhZAAB4nGNgZGBg2MzAACeXMzAyoAJeADPyAh14nGNgAILNpGEA0fgIZQAAAAAAAAA2AHIAvgE+AZgCCAKMAv4DlgPsBEYEoHicY2BkYGDgZchi4GQAASYg5gJCBob/YD4DABTSAZcAeJx9kU1uwjAQhV/4qwpqhdSqi67cTTeVEmBXDgBbhBD7AHYISuLUMSD2PUdP0HNwjp6i676k3qQS9Ujjb968mYUNoI8zPJTHw02Vy9PAFatfbpLuHbfIT47b6MF33KH+6riLF0wc93CHN27wWtdUHvHuuIFbfDhuUv903CKfHbfxgC/HHerfjrtYen3HPTx7ambiIl0YKQ+xPM5ltE9CU9NqxVKaItaZGPqDmj6VmTShlRuxOoniEI2sVUIZnYqJzqxMEi1yo3dybf2ttfk4CJTT/bVOMYNBjAIpFiTJOLCWOGLOHGGPBCE7l32XO0tmw04MjQwCQ7774B//lDmrZkJY3hvOrHBiLuiJMKJqoVgrejQ3CP5Yubt0JwxNJa96Oypr6j621VSOMQKG+uP36eKmHylcb0MAeJxtwdEOgjAMBdBeWEFR/Mdl7bTJtMsygc/nwVfPoYF+QP+tGDAigDFhxgVXLLjhjhUPCtmKTtmLaGN7x6dy/Io5bybqoevRQ3LRObb0sk3HKpn1SFqW6ru26vbpYfcmRCccJhqsAAA=")
format("woff");
}
.token.treeview-part .entry-name:before {
content: "\ea01";
font-family: "PrismTreeview";
font-size: inherit;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 2.5ex;
display: inline-block;
}
.token.treeview-part .entry-name.dir:before {
content: "\ea02";
}
.token.treeview-part .entry-name.ext-bmp:before,
.token.treeview-part .entry-name.ext-eps:before,
.token.treeview-part .entry-name.ext-gif:before,
.token.treeview-part .entry-name.ext-jpe:before,
.token.treeview-part .entry-name.ext-jpg:before,
.token.treeview-part .entry-name.ext-jpeg:before,
.token.treeview-part .entry-name.ext-png:before,
.token.treeview-part .entry-name.ext-svg:before,
.token.treeview-part .entry-name.ext-tiff:before {
content: "\ea03";
}
.token.treeview-part .entry-name.ext-cfg:before,
.token.treeview-part .entry-name.ext-conf:before,
.token.treeview-part .entry-name.ext-config:before,
.token.treeview-part .entry-name.ext-csv:before,
.token.treeview-part .entry-name.ext-ini:before,
.token.treeview-part .entry-name.ext-log:before,
.token.treeview-part .entry-name.ext-md:before,
.token.treeview-part .entry-name.ext-nfo:before,
.token.treeview-part .entry-name.ext-txt:before {
content: "\ea06";
}
.token.treeview-part .entry-name.ext-asp:before,
.token.treeview-part .entry-name.ext-aspx:before,
.token.treeview-part .entry-name.ext-c:before,
.token.treeview-part .entry-name.ext-cc:before,
.token.treeview-part .entry-name.ext-cpp:before,
.token.treeview-part .entry-name.ext-cs:before,
.token.treeview-part .entry-name.ext-css:before,
.token.treeview-part .entry-name.ext-h:before,
.token.treeview-part .entry-name.ext-hh:before,
.token.treeview-part .entry-name.ext-htm:before,
.token.treeview-part .entry-name.ext-html:before,
.token.treeview-part .entry-name.ext-jav:before,
.token.treeview-part .entry-name.ext-java:before,
.token.treeview-part .entry-name.ext-js:before,
.token.treeview-part .entry-name.ext-php:before,
.token.treeview-part .entry-name.ext-rb:before,
.token.treeview-part .entry-name.ext-xml:before {
content: "\ea07";
}
.token.treeview-part .entry-name.ext-7z:before,
.token.treeview-part .entry-name.ext-bz:before,
.token.treeview-part .entry-name.ext-bz2:before,
.token.treeview-part .entry-name.ext-gz:before,
.token.treeview-part .entry-name.ext-rar:before,
.token.treeview-part .entry-name.ext-tar:before,
.token.treeview-part .entry-name.ext-tgz:before,
.token.treeview-part .entry-name.ext-zip:before {
content: "\ea08";
}
.token.treeview-part .entry-name.ext-aac:before,
.token.treeview-part .entry-name.ext-au:before,
.token.treeview-part .entry-name.ext-cda:before,
.token.treeview-part .entry-name.ext-flac:before,
.token.treeview-part .entry-name.ext-mp3:before,
.token.treeview-part .entry-name.ext-oga:before,
.token.treeview-part .entry-name.ext-ogg:before,
.token.treeview-part .entry-name.ext-wav:before,
.token.treeview-part .entry-name.ext-wma:before {
content: "\ea04";
}
.token.treeview-part .entry-name.ext-avi:before,
.token.treeview-part .entry-name.ext-flv:before,
.token.treeview-part .entry-name.ext-mkv:before,
.token.treeview-part .entry-name.ext-mov:before,
.token.treeview-part .entry-name.ext-mp4:before,
.token.treeview-part .entry-name.ext-mpeg:before,
.token.treeview-part .entry-name.ext-mpg:before,
.token.treeview-part .entry-name.ext-ogv:before,
.token.treeview-part .entry-name.ext-webm:before {
content: "\ea05";
}
.token.treeview-part .entry-name.ext-pdf:before {
content: "\ea09";
}
.token.treeview-part .entry-name.ext-xls:before,
.token.treeview-part .entry-name.ext-xlsx:before {
content: "\ea0a";
}
.token.treeview-part .entry-name.ext-doc:before,
.token.treeview-part .entry-name.ext-docm:before,
.token.treeview-part .entry-name.ext-docx:before {
content: "\ea0c";
}
.token.treeview-part .entry-name.ext-pps:before,
.token.treeview-part .entry-name.ext-ppt:before,
.token.treeview-part .entry-name.ext-pptx:before {
content: "\ea0b";
}

124
package-lock.json generated
View File

@ -8,6 +8,8 @@
"name": "@doc-utils/docs2website",
"version": "0.1.0",
"dependencies": {
"@doc-utils/color-themes": "^0.1.1",
"@doc-utils/jsonschema2markdown": "^0.1.0",
"@doc-utils/markdown2html": "^0.1.0",
"glob": "^10.2.2",
"luxon": "^3.3.0",
@ -26,10 +28,28 @@
"typescript": "^5.0.4"
}
},
"node_modules/@doc-utils/color-themes": {
"version": "0.1.14",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fcolor-themes/-/0.1.14/color-themes-0.1.14.tgz",
"integrity": "sha512-j0U8v8Y+9zAm9D7pbCheTQYGEKt9FSpKSZQNGsogxWl95S9Z7QMjtmJns6QPgdOsSDss7sjMLFS5Gm50GCMzNA=="
},
"node_modules/@doc-utils/jsonschema2markdown": {
"version": "0.1.1",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fjsonschema2markdown/-/0.1.1/jsonschema2markdown-0.1.1.tgz",
"integrity": "sha512-d3H5Jk7QXesu++3C/vaxnzXP6QkNHdOmMmbkSMywkInC5BC0RpUqtav5KheDZ7PzrnNO37YjdMODvdaMNUFYCw==",
"dependencies": {
"glob": "^10.2.2",
"json-schema": "^0.4.0",
"luxon": "^3.3.0",
"mustache": "^4.2.0",
"word-wrap": "^1.2.3",
"yaml": "^2.2.2"
}
},
"node_modules/@doc-utils/markdown2html": {
"version": "0.1.6",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fmarkdown2html/-/0.1.6/markdown2html-0.1.6.tgz",
"integrity": "sha512-lfb0vW0effsyKOXCXXF8d+xWjsKCF2rUuOq5F0GdOsw4PSJP3yCBW9oWZs4JdajwigGCBhWvXviyZeKInSdzgg==",
"version": "0.1.20",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fmarkdown2html/-/0.1.20/markdown2html-0.1.20.tgz",
"integrity": "sha512-kAkGITASEdT4jKPyeAAKZ/9QBmU1sOm0as3nHn9IolkZDydn02pmMIJCi4mrRWbj/3uj/WY5VtRa6T7sqYczNg==",
"dependencies": {
"bytefield-svg": "^1.6.1",
"dompurify": "^2.3.6",
@ -111,9 +131,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "18.16.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz",
"integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==",
"version": "18.16.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz",
"integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==",
"dev": true
},
"node_modules/@types/prismjs": {
@ -919,9 +939,9 @@
}
},
"node_modules/glob": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.2.2.tgz",
"integrity": "sha512-Xsa0BcxIC6th9UwNjZkhrMtNo/MnyRL8jGCP+uEwhA5oFOCY1f2s1/oNKY47xQ0Bg5nkjsfAEIej1VeH62bDDQ==",
"version": "10.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.2.3.tgz",
"integrity": "sha512-Kb4rfmBVE3eQTAimgmeqc2LwSnN0wIOkkUL6HmxEFxNJ4fHghYHVbFba/HcGcRjE6s9KoMNK3rSOwkL4PioZjg==",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^2.0.3",
@ -1086,6 +1106,11 @@
}
}
},
"node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"node_modules/katex": {
"version": "0.16.7",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.7.tgz",
@ -1211,9 +1236,9 @@
}
},
"node_modules/node-fetch": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@ -1341,11 +1366,11 @@
}
},
"node_modules/path-scurry": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz",
"integrity": "sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.8.0.tgz",
"integrity": "sha512-IjTrKseM404/UAWA8bBbL3Qp6O2wXkanuIE3seCxBH7ctRuvH1QRawy1N3nVDHGkdeZsjOsSe/8AQBL/VQCy2g==",
"dependencies": {
"lru-cache": "^9.0.0",
"lru-cache": "^9.1.1",
"minipass": "^5.0.0"
},
"engines": {
@ -1500,9 +1525,9 @@
}
},
"node_modules/signal-exit": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.1.tgz",
"integrity": "sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
"integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
"engines": {
"node": ">=14"
},
@ -2425,10 +2450,28 @@
}
},
"dependencies": {
"@doc-utils/color-themes": {
"version": "0.1.14",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fcolor-themes/-/0.1.14/color-themes-0.1.14.tgz",
"integrity": "sha512-j0U8v8Y+9zAm9D7pbCheTQYGEKt9FSpKSZQNGsogxWl95S9Z7QMjtmJns6QPgdOsSDss7sjMLFS5Gm50GCMzNA=="
},
"@doc-utils/jsonschema2markdown": {
"version": "0.1.1",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fjsonschema2markdown/-/0.1.1/jsonschema2markdown-0.1.1.tgz",
"integrity": "sha512-d3H5Jk7QXesu++3C/vaxnzXP6QkNHdOmMmbkSMywkInC5BC0RpUqtav5KheDZ7PzrnNO37YjdMODvdaMNUFYCw==",
"requires": {
"glob": "^10.2.2",
"json-schema": "^0.4.0",
"luxon": "^3.3.0",
"mustache": "^4.2.0",
"word-wrap": "^1.2.3",
"yaml": "^2.2.2"
}
},
"@doc-utils/markdown2html": {
"version": "0.1.6",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fmarkdown2html/-/0.1.6/markdown2html-0.1.6.tgz",
"integrity": "sha512-lfb0vW0effsyKOXCXXF8d+xWjsKCF2rUuOq5F0GdOsw4PSJP3yCBW9oWZs4JdajwigGCBhWvXviyZeKInSdzgg==",
"version": "0.1.20",
"resolved": "https://gitea.jbrumond.me/api/packages/doc-utils/npm/%40doc-utils%2Fmarkdown2html/-/0.1.20/markdown2html-0.1.20.tgz",
"integrity": "sha512-kAkGITASEdT4jKPyeAAKZ/9QBmU1sOm0as3nHn9IolkZDydn02pmMIJCi4mrRWbj/3uj/WY5VtRa6T7sqYczNg==",
"requires": {
"bytefield-svg": "^1.6.1",
"dompurify": "^2.3.6",
@ -2501,9 +2544,9 @@
"dev": true
},
"@types/node": {
"version": "18.16.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz",
"integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==",
"version": "18.16.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz",
"integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==",
"dev": true
},
"@types/prismjs": {
@ -3091,9 +3134,9 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"glob": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.2.2.tgz",
"integrity": "sha512-Xsa0BcxIC6th9UwNjZkhrMtNo/MnyRL8jGCP+uEwhA5oFOCY1f2s1/oNKY47xQ0Bg5nkjsfAEIej1VeH62bDDQ==",
"version": "10.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.2.3.tgz",
"integrity": "sha512-Kb4rfmBVE3eQTAimgmeqc2LwSnN0wIOkkUL6HmxEFxNJ4fHghYHVbFba/HcGcRjE6s9KoMNK3rSOwkL4PioZjg==",
"requires": {
"foreground-child": "^3.1.0",
"jackspeak": "^2.0.3",
@ -3209,6 +3252,11 @@
"xml-name-validator": "^4.0.0"
}
},
"json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"katex": {
"version": "0.16.7",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.7.tgz",
@ -3291,9 +3339,9 @@
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
},
"node-fetch": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"requires": {
"whatwg-url": "^5.0.0"
},
@ -3385,11 +3433,11 @@
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-scurry": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz",
"integrity": "sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.8.0.tgz",
"integrity": "sha512-IjTrKseM404/UAWA8bBbL3Qp6O2wXkanuIE3seCxBH7ctRuvH1QRawy1N3nVDHGkdeZsjOsSe/8AQBL/VQCy2g==",
"requires": {
"lru-cache": "^9.0.0",
"lru-cache": "^9.1.1",
"minipass": "^5.0.0"
}
},
@ -3504,9 +3552,9 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"signal-exit": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.1.tgz",
"integrity": "sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw=="
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
"integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q=="
},
"source-map": {
"version": "0.6.1",

View File

@ -6,12 +6,12 @@
},
"scripts": {
"tsc": "tsc",
"clean": "rm -rf ./build"
"clean": "rm -rf ./build ./www"
},
"bin": {
"docs2website": "./bin/docs2website"
},
"exports": "./build/index.js",
"main": "./build/index.js",
"devDependencies": {
"@types/jsdom": "^20.0.0",
"@types/luxon": "^3.1.0",
@ -21,6 +21,8 @@
"typescript": "^5.0.4"
},
"dependencies": {
"@doc-utils/color-themes": "^0.1.1",
"@doc-utils/jsonschema2markdown": "^0.1.0",
"@doc-utils/markdown2html": "^0.1.0",
"glob": "^10.2.2",
"luxon": "^3.3.0",

View File

@ -1,62 +0,0 @@
# Input Configuration (where your documents are)
input:
# The root directory for where to find input file. All other
# input paths are relative to this, and must be under this
root: ./docs
# Files identified in this section are copied over to the
# output directory unprocessed
raw:
- ./**/*.{png,jpg,jpeg,gif}
# Files in this section will be processed as mustache templates,
# but will receive no other processing
text:
- ./**/*.{css,html,js,txt}
# Files to be parsed as markdown (optionally with front matter)
# and rendered to HTML pages
markdown:
- ./**/*.md
# Files to be parsed as JSON Schema definitions and rendered
# to HTML documentation. Additionally, the original JSON / Yaml
# file will also be copied to the output directory, unaltered
schema+json:
- ./**/*.schema.json
schema+yaml:
- ./**/*.schema.{yaml,yml}
# Files to be parsed as OpenAPI V3 specifications and rendered
# to HTML documentation. Additionally, the original JSON / Yaml
# file will also be copied to the output directory, unaltered
openapi+json:
- ./**/*.openapi.json
openapi+yaml:
- ./**/*.openapi.{yaml,yml}
# Template Configuration (used by mustache to actually render pages)
templates:
# Root directory where layout files are stored
layouts: ./layouts
# Root directory where partial files are stored
partials: ./partials
# (Optional) whitelist of environment variables to be made accessible
# under `env` when processing templates
env:
- EXAMPLE_ENVIRONMENT_VARIABLE
- FOO_BAR_BAZ
# Output Configuration (where to put your website)
output:
# The root directory to output your website at. The path of an
# input file relative to $.input.root will match (aside from file
# extension) the path of the output file relative to $.output.root
root: ./www
# Markdown-to-HTML Configuration
markdown:
#

View File

@ -5,6 +5,6 @@ import { build_docs_project } from '../build';
main();
async function main() {
const conf = await read_config('./sample-config.yaml');
const conf = await read_config(process.argv[2]);
await build_docs_project(conf);
}

View File

@ -1,13 +1,20 @@
import { ColorTheme } from '@doc-utils/color-themes';
import { build_markdown_from_json_schema } from '@doc-utils/jsonschema2markdown';
import { render_markdown_to_html, render_markdown_to_html_inline_sync } from '@doc-utils/markdown2html';
import { glob } from 'glob';
import { Config } from './conf';
import { promises as fs } from 'fs';
import { dirname, join as path_join } from 'path';
import { build_env_scope } from './env';
import { process_frontmatter } from '@doc-utils/markdown2html';
import { load_layout, Context, render_template, load_partials } from './template';
import { load_layout, Context, render_template, load_partials, load_extras, FrontMatter } from './template';
import { DateTime } from 'luxon';
import assert = require('assert');
import { load_themes, render_theme_css_properties } from './themes';
import { icons } from './icons';
import { mkdirp, read_json, read_text, read_yaml, write_text } from './fs';
import { stringify as to_yaml } from 'yaml';
interface BuildState {
conf: Config;
@ -15,6 +22,9 @@ interface BuildState {
env: Record<string, string>;
partials?: Record<string, string>;
layouts: Record<string, string>;
themes: Record<string, ColorTheme>;
theme_groups: ThemeGroups;
extras: Record<string, string>;
made_directories: Set<string>;
build_time: {
iso: string;
@ -22,13 +32,42 @@ interface BuildState {
};
}
export interface ThemeGroups {
all: ColorTheme[];
light: ColorTheme[];
dark: ColorTheme[];
high_contrast: ColorTheme[];
low_contrast: ColorTheme[];
monochrome: ColorTheme[];
greyscale: ColorTheme[];
protanopia_safe: ColorTheme[];
deuteranopia_safe: ColorTheme[];
tritanopia_safe: ColorTheme[];
}
export async function build_docs_project(conf: Config) {
const now = DateTime.now();
const themes = await load_themes(conf);
const state: BuildState = {
conf,
seen_files: new Set<string>(),
env: build_env_scope(conf),
layouts: Object.create(null),
themes: themes,
theme_groups: {
// fixme: this is horribly inefficient
all: Object.values(themes),
light: Object.values(themes).filter((theme) => theme.labels.includes('light')),
dark: Object.values(themes).filter((theme) => theme.labels.includes('dark')),
high_contrast: Object.values(themes).filter((theme) => theme.labels.includes('high_contrast')),
low_contrast: Object.values(themes).filter((theme) => theme.labels.includes('low_contrast')),
monochrome: Object.values(themes).filter((theme) => theme.labels.includes('monochrome')),
greyscale: Object.values(themes).filter((theme) => theme.labels.includes('greyscale')),
protanopia_safe: Object.values(themes).filter((theme) => theme.labels.includes('protanopia_safe')),
deuteranopia_safe: Object.values(themes).filter((theme) => theme.labels.includes('deuteranopia_safe')),
tritanopia_safe: Object.values(themes).filter((theme) => theme.labels.includes('tritanopia_safe')),
},
extras: await load_extras(),
made_directories: new Set<string>(),
build_time: {
iso: now.toISO(),
@ -45,12 +84,20 @@ export async function build_docs_project(conf: Config) {
}
if (conf.input.markdown) {
//
await render_markdown_files(state);
}
if (conf.input['schema+json'] || conf.input['schema+yaml']) {
await render_json_schema_files(state);
}
// todo...
}
// ===== Raw File Copy =====
async function copy_raw_files(state: BuildState) {
const promises: Promise<any>[] = [ ];
const files = await glob(state.conf.input.raw, {
@ -68,13 +115,17 @@ async function copy_raw_files(state: BuildState) {
const out_file = map_input_file_to_output_file(state, in_file);
promises.push(
fs.copyFile(in_file, await out_file, 0o600)
fs.copyFile(in_file, await out_file)
);
}
await Promise.all(promises);
}
// ===== File Renderers =====
async function render_text_file_templates(state: BuildState) {
const promises: Promise<any>[] = [ ];
const files = await glob(state.conf.input.text, {
@ -83,7 +134,7 @@ async function render_text_file_templates(state: BuildState) {
});
if (! state.partials) {
state.partials = await load_partials(state.conf);
await build_partials(state);
}
for (const in_file of files) {
@ -103,7 +154,7 @@ async function render_text_file_templates(state: BuildState) {
async function render_text_file_template(state: BuildState, in_file: string) {
const out_file = map_input_file_to_output_file(state, in_file);
const { frontmatter, document } = process_frontmatter(await fs.readFile(in_file, 'utf8'));
const { frontmatter, text } = await read_text(in_file);
let layout: string;
const layout_file = frontmatter?.layout;
@ -116,16 +167,202 @@ async function render_text_file_template(state: BuildState, in_file: string) {
layout = state.layouts[layout_file];
}
const context: Context = {
env: state.env,
page: frontmatter,
build_time: state.build_time,
};
const rendered = render_template(document, context, layout, structuredClone(state.partials));
await fs.writeFile(await out_file, rendered, 'utf8');
const tags = state.conf.templates?.tags;
const context = mustache_context(state, frontmatter);
const rendered = render_template(text, context, layout, structuredClone(state.partials), tags);
await write_text(await out_file, rendered);
}
async function render_markdown_files(state: BuildState) {
const promises: Promise<any>[] = [ ];
const files = await glob(state.conf.input.markdown, {
absolute: true,
cwd: state.conf.input.root,
});
if (! state.partials) {
await build_partials(state);
}
for (const in_file of files) {
if (state.seen_files.has(in_file)) {
continue;
}
state.seen_files.add(in_file);
promises.push(
render_markdown_file(state, in_file)
);
}
await Promise.all(promises);
}
async function render_markdown_file(state: BuildState, in_file: string) {
const out_file = map_input_file_to_output_file(state, in_file, [ '.md', '.markdown' ], '.html');
const { frontmatter, text } = await read_text(in_file);
const html = render_markdown_to_html(text, state.conf.markdown);
let layout: string;
const layout_file = frontmatter?.layout;
if (layout_file) {
if (! state.layouts[layout_file]) {
state.layouts[layout_file] = await load_layout(state.conf, layout_file);
}
layout = state.layouts[layout_file];
}
const tags = state.conf.templates?.tags;
const context = mustache_context(state, frontmatter);
const rendered = render_template(await html, context, layout, structuredClone(state.partials), tags);
await write_text(await out_file, rendered);
}
async function render_json_schema_files(state: BuildState) {
const promises: Promise<any>[] = [ ];
const json_files = await glob(state.conf.input['schema+json'], {
absolute: true,
cwd: state.conf.input.root,
});
const yaml_files = await glob(state.conf.input['schema+yaml'], {
absolute: true,
cwd: state.conf.input.root,
});
if (! state.partials) {
await build_partials(state);
}
for (const in_file of json_files) {
if (state.seen_files.has(in_file)) {
continue;
}
state.seen_files.add(in_file);
promises.push(
handle_json_schema_json_file(state, in_file)
);
}
for (const in_file of yaml_files) {
if (state.seen_files.has(in_file)) {
continue;
}
state.seen_files.add(in_file);
promises.push(
handle_json_schema_yaml_file(state, in_file)
);
}
await Promise.all(promises);
}
async function handle_json_schema_json_file(state: BuildState, in_file: string) {
const promises: Promise<any>[] = [ ];
const out_file = map_input_file_to_output_file(state, in_file, [ '.json' ], '.html');
const { frontmatter, parsed, json } = await read_json(in_file, true);
promises.push(
render_json_schema(state, parsed, await out_file, frontmatter)
);
if (state.conf.output.include_inputs?.includes('schema+json')) {
const json_file = await map_input_file_to_output_file(state, in_file);
promises.push(
write_text(json_file, json)
);
if (state.conf.output.include_yaml_and_json) {
const yaml_file = await map_input_file_to_output_file(state, in_file, [ '.json' ], '.yaml');
promises.push(
write_text(yaml_file, to_yaml(parsed))
);
}
}
await Promise.all(promises);
}
async function handle_json_schema_yaml_file(state: BuildState, in_file: string) {
const promises: Promise<any>[] = [ ];
const out_file = map_input_file_to_output_file(state, in_file, [ '.yaml', '.yml' ], '.html');
const { frontmatter, parsed, yaml } = await read_yaml(in_file, true);
promises.push(
render_json_schema(state, parsed, await out_file, frontmatter)
);
if (state.conf.output.include_inputs?.includes('schema+yaml')) {
const yaml_file = await map_input_file_to_output_file(state, in_file);
promises.push(
write_text(yaml_file, yaml)
);
if (state.conf.output.include_yaml_and_json) {
const json_file = await map_input_file_to_output_file(state, in_file, [ '.yaml', '.yml' ], '.json');
promises.push(
write_text(json_file, JSON.stringify(parsed, null, ' '))
);
}
}
await Promise.all(promises);
}
async function render_json_schema(state: BuildState, schema: unknown, out_file: string, frontmatter?: any) {
const promises: Promise<any>[] = [ ];
const markdown = build_markdown_from_json_schema(schema);
if (state.conf.output.include_intermediate_markdown) {
promises.push(
map_input_file_to_output_file(state, out_file, [ '.html' ], '.md')
.then((md_file) => write_text(md_file, markdown))
);
}
const html = render_markdown_to_html(markdown, state.conf.markdown);
let layout: string;
const layout_file = frontmatter?.layout;
if (layout_file) {
if (! state.layouts[layout_file]) {
state.layouts[layout_file] = await load_layout(state.conf, layout_file);
}
layout = state.layouts[layout_file];
}
const tags = state.conf.templates?.tags;
const context = mustache_context(state, frontmatter);
const rendered = render_template(await html, context, layout, structuredClone(state.partials), tags);
promises.push(
write_text(await out_file, rendered)
);
await Promise.all(promises);
}
// ===== Helpers =====
async function map_input_file_to_output_file(state: BuildState, in_file: string, remove_exts?: string[], add_ext?: string) {
assert(in_file.startsWith(state.conf.input.root), 'input file expected to be inside input root');
let out_file = path_join(state.conf.output.root, in_file.slice(state.conf.input.root.length));
@ -147,11 +384,38 @@ async function map_input_file_to_output_file(state: BuildState, in_file: string,
if (! state.made_directories.has(dir)) {
state.made_directories.add(dir);
await fs.mkdir(dir, {
mode: 0o700,
recursive: true,
});
await mkdirp(dir);
}
return out_file;
}
async function build_partials(state: BuildState) {
state.partials = await load_partials(state.conf);
for (const [name, theme] of Object.entries(state.themes)) {
state.partials[`.themes/${name}`] = render_theme_css_properties(theme);
}
Object.assign(state.partials, state.extras);
}
function mustache_context(state: BuildState, frontmatter?: FrontMatter) : Context {
return {
env: state.env,
page: frontmatter,
build_time: state.build_time,
icons: icons,
themes: Object.values(state.themes),
theme_groups: structuredClone(state.theme_groups),
markdown: {
render_inline() {
return (text, render) => {
const md = render(text)
const html = render_markdown_to_html_inline_sync(md, state.conf.markdown);
return html;
};
},
}
};
}

View File

@ -2,12 +2,14 @@
import { promises as fs } from 'fs';
import { parse as parse_yaml } from 'yaml';
import { resolve as resolve_path, dirname } from 'path';
import { MarkdownOptions } from '@doc-utils/markdown2html';
export async function read_config(file: string) {
const path = resolve_path(process.cwd(), file);
const yaml = await fs.readFile(path, 'utf8');
const config = parse_yaml(yaml);
validate_config(config);
process_markdown_config(config);
resolve_paths(path, config);
return config;
}
@ -27,14 +29,17 @@ export interface Config {
templates?: {
layouts?: string;
partials?: string;
themes?: string;
tags?: [ string, string ];
env?: string[];
};
output: {
root: string;
include_inputs?: string[];
include_yaml_and_json?: boolean;
include_intermediate_markdown?: boolean;
};
markdown?: {
//
};
markdown?: MarkdownOptions;
schema?: {
//
};
@ -61,3 +66,19 @@ function resolve_paths(file_path: string, config: Config) {
config.templates.partials = resolve_path(base_path, config.templates.partials);
}
}
function process_markdown_config(config: any) {
if (config?.markdown?.custom_elements) {
if (config.markdown.custom_elements.tag_names) {
const tags = new Set<string>(config.markdown.custom_elements.tag_names);
config.markdown.custom_elements.tagNameCheck = (tag_name) => tags.has(tag_name);
delete config.markdown.custom_elements.tag_names;
}
if (config.markdown.custom_elements.attribute_names) {
const attrs = new Set<string>(config.markdown.custom_elements.attribute_names);
config.markdown.custom_elements.attributeNameCheck = (attr_name) => attrs.has(attr_name);
delete config.markdown.custom_elements.attribute_names;
}
}
}

70
src/fs.ts Normal file
View File

@ -0,0 +1,70 @@
import { process_frontmatter } from '@doc-utils/markdown2html';
import { promises as fs } from 'fs';
import { resolve as resolve_path } from 'path';
import { parse as parse_yaml, stringify as to_yaml } from 'yaml';
export async function load_from_dir(dir: string, file: string) {
if (! dir) {
return null;
}
const rel_path = resolve_path('/', file);
const abs_path = resolve_path(dir, '.' + rel_path);
return await fs.readFile(abs_path, 'utf8');
}
export function mkdirp(dir: string, mode = 0o700) {
return fs.mkdir(dir, { mode, recursive: true });
}
export async function read_text(file: string, check_for_frontmatter = true) {
const text = await fs.readFile(file, 'utf8');
if (check_for_frontmatter) {
const { frontmatter, document } = process_frontmatter(text);
return { frontmatter, text: document };
}
return { text, frontmatter: null };
}
export async function read_json(file: string, check_for_frontmatter = true) {
const json = await fs.readFile(file, 'utf8');
if (check_for_frontmatter) {
const { frontmatter, document } = process_frontmatter(json);
const parsed = JSON.parse(document);
return { frontmatter, json: document, parsed };
}
const parsed = JSON.parse(json);
return { json, parsed, frontmatter: null };
}
export async function read_yaml(file: string, check_for_frontmatter = true) {
const yaml = await fs.readFile(file, 'utf8');
if (check_for_frontmatter) {
const { frontmatter, document } = process_frontmatter(yaml);
const parsed = parse_yaml(document);
return { frontmatter, yaml: document, parsed };
}
const parsed = parse_yaml(yaml);
return { yaml, parsed, frontmatter: null };
}
export function write_text(file: string, text: string) {
return fs.writeFile(file, text, 'utf8');
}
export function write_json(file: string, obj: any, pretty = true) {
const json = JSON.stringify(obj, null, pretty ? ' ' : null);
return fs.writeFile(file, json, 'utf8');
}
export function write_yaml(file: string, obj: any) {
const yaml = to_yaml(obj);
return fs.writeFile(file, yaml, 'utf8');
}

23
src/icons.ts Normal file
View File

@ -0,0 +1,23 @@
export const icons: Record<string, string> = Object.create(null);
const whitespace = /[\s\t\n]+/g;
const feather_icons: Record<string, string> = require('../vendor/feather-icons/icons.json');
for (const [name, contents] of Object.entries(feather_icons)) {
icons[name] = `
<svg xmlns="http://www.w3.org/2000/svg"
class="icon ${name}"
aria-hidden="true"
style="width: var(--icon-size, 1rem); height: var(--icon-size, 1rem)"
viewBox="0 0 24 24"
fill="none"
stroke="currentcolor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>${contents}</svg>
`.replace(whitespace, ' ').trim();
}
Object.freeze(icons);

View File

@ -1,2 +1,3 @@
export { read_config, Config } from './conf';
export { build_docs_project, ThemeGroups } from './build';

View File

@ -4,35 +4,57 @@ import { render as mustache_render } from 'mustache';
import { promises as fs } from 'fs';
import { resolve as resolve_path } from 'path';
import { glob } from 'glob';
import { load_from_dir } from './fs';
import { ColorTheme } from '@doc-utils/color-themes';
import { ThemeGroups } from './build';
export interface Context {
env?: Record<string, string>;
page?: {
title?: string;
layout?: string;
[key: string]: string | number | boolean;
};
page?: FrontMatter;
icons: Record<string, string>;
themes: ColorTheme[];
theme_groups: ThemeGroups;
build_time: {
iso: string;
rfc2822: string;
};
markdown: {
render_inline(): MustacheRenderer;
}
}
export function render_template(template: string, context: Context, layout?: string, partials?: Record<string, string>) {
export interface FrontMatter {
title?: string;
layout?: string;
[key: string]: unknown;
}
export function render_template(template: string, context: Context, layout?: string, partials: Record<string, string> = { }, tags?: [ string, string ]) {
partials['.content'] = template;
return mustache_render(layout || template, context, partials);
return mustache_render(layout || template, context, partials, tags);
}
export async function load_extras() {
const extras: Record<string, string> = Object.create(null);
const extras_dir = resolve_path(__dirname, '../extras');
const extras_files = [
'components/color-scheme-toggle-button.js',
'components/outline-button.js',
'components/outline-inline.js',
'prism.css',
];
const promises = extras_files.map((file) => load_from_dir(extras_dir, file));
for (let i = 0; i < extras_files.length; i++) {
extras[`.extras/${extras_files[i]}`] = await promises[i];
}
return extras;
}
export async function load_layout(conf: Config, file: string) {
const path = conf.templates?.layouts;
if (! path) {
return null;
}
const rel_path = resolve_path('/', file);
const abs_path = resolve_path(path, '.' + rel_path);
return await fs.readFile(abs_path, 'utf8');
return load_from_dir(conf.templates?.layouts, file);
}
export async function load_partials(conf: Config) {
@ -55,3 +77,7 @@ export async function load_partials(conf: Config) {
return partials;
}
export interface MustacheRenderer {
(this: void, text: string, render: (text: string) => string): string;
}

64
src/themes.ts Normal file
View File

@ -0,0 +1,64 @@
import { glob } from 'glob';
import { Config } from './conf';
import { load_from_dir } from './fs';
import { ColorTheme, themes as builtin_themes, load_theme as load_builtin_theme, validate_theme } from '@doc-utils/color-themes';
export async function load_themes(conf: Config) {
const themes: Record<string, ColorTheme> = { };
for (const theme of builtin_themes) {
themes[theme] = load_builtin_theme(theme);
}
if (conf.templates?.themes) {
const local_themes = await glob(conf.templates.themes + '/**/theme.json');
for (const theme_path of local_themes) {
const segments = theme_path.split('/');
const theme = segments[segments.length - 2];
themes[theme] = await load_local_theme(conf, theme);
}
}
return themes;
}
export async function load_theme(conf: Config, name: string) {
if (name.includes('/')) {
return null;
}
const local_theme = await load_local_theme(conf, name);
if (local_theme) {
return local_theme;
}
return load_builtin_theme(name);
}
export async function load_local_theme(conf: Config, name: string) {
let json: string;
try {
json = await load_from_dir(conf.templates?.themes, `./${name}/theme.json`);
}
catch (error) {
return null;
}
const theme = JSON.parse(json);
validate_theme(theme);
return theme;
}
export function render_theme_css_properties(theme: ColorTheme) {
return Object
.entries(theme.colors)
.map(([ name, color ]) => {
return `--theme-${name.replace(/_/g, '-')}: ${color};`;
})
.join('\n') + '\n';
}

289
vendor/feather-icons/icons.json vendored Normal file
View File

@ -0,0 +1,289 @@
{
"activity": "<polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"></polyline>",
"airplay": "<path d=\"M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1\"></path><polygon points=\"12 15 17 21 7 21 12 15\"></polygon>",
"alert-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>",
"alert-octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>",
"alert-triangle": "<path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"></line><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>",
"align-center": "<line x1=\"18\" y1=\"10\" x2=\"6\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"18\" y1=\"18\" x2=\"6\" y2=\"18\"></line>",
"align-justify": "<line x1=\"21\" y1=\"10\" x2=\"3\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"></line>",
"align-left": "<line x1=\"17\" y1=\"10\" x2=\"3\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\"></line>",
"align-right": "<line x1=\"21\" y1=\"10\" x2=\"7\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\"></line>",
"anchor": "<circle cx=\"12\" cy=\"5\" r=\"3\"></circle><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"8\"></line><path d=\"M5 12H2a10 10 0 0 0 20 0h-3\"></path>",
"aperture": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"14.31\" y1=\"8\" x2=\"20.05\" y2=\"17.94\"></line><line x1=\"9.69\" y1=\"8\" x2=\"21.17\" y2=\"8\"></line><line x1=\"7.38\" y1=\"12\" x2=\"13.12\" y2=\"2.06\"></line><line x1=\"9.69\" y1=\"16\" x2=\"3.95\" y2=\"6.06\"></line><line x1=\"14.31\" y1=\"16\" x2=\"2.83\" y2=\"16\"></line><line x1=\"16.62\" y1=\"12\" x2=\"10.88\" y2=\"21.94\"></line>",
"archive": "<polyline points=\"21 8 21 21 3 21 3 8\"></polyline><rect x=\"1\" y=\"3\" width=\"22\" height=\"5\"></rect><line x1=\"10\" y1=\"12\" x2=\"14\" y2=\"12\"></line>",
"arrow-down-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"8 12 12 16 16 12\"></polyline><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line>",
"arrow-down-left": "<line x1=\"17\" y1=\"7\" x2=\"7\" y2=\"17\"></line><polyline points=\"17 17 7 17 7 7\"></polyline>",
"arrow-down-right": "<line x1=\"7\" y1=\"7\" x2=\"17\" y2=\"17\"></line><polyline points=\"17 7 17 17 7 17\"></polyline>",
"arrow-down": "<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><polyline points=\"19 12 12 19 5 12\"></polyline>",
"arrow-left-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 8 8 12 12 16\"></polyline><line x1=\"16\" y1=\"12\" x2=\"8\" y2=\"12\"></line>",
"arrow-left": "<line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line><polyline points=\"12 19 5 12 12 5\"></polyline>",
"arrow-right-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 16 16 12 12 8\"></polyline><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"arrow-right": "<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline>",
"arrow-up-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"16 12 12 8 8 12\"></polyline><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"8\"></line>",
"arrow-up-left": "<line x1=\"17\" y1=\"17\" x2=\"7\" y2=\"7\"></line><polyline points=\"7 17 7 7 17 7\"></polyline>",
"arrow-up-right": "<line x1=\"7\" y1=\"17\" x2=\"17\" y2=\"7\"></line><polyline points=\"7 7 17 7 17 17\"></polyline>",
"arrow-up": "<line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"5\"></line><polyline points=\"5 12 12 5 19 12\"></polyline>",
"at-sign": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94\"></path>",
"award": "<circle cx=\"12\" cy=\"8\" r=\"7\"></circle><polyline points=\"8.21 13.89 7 23 12 20 17 23 15.79 13.88\"></polyline>",
"bar-chart-2": "<line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"10\"></line><line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"4\"></line><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"14\"></line>",
"bar-chart": "<line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"10\"></line><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"4\"></line><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"16\"></line>",
"battery-charging": "<path d=\"M5 18H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3.19M15 6h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-3.19\"></path><line x1=\"23\" y1=\"13\" x2=\"23\" y2=\"11\"></line><polyline points=\"11 6 7 12 13 12 9 18\"></polyline>",
"battery": "<rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\"></rect><line x1=\"23\" y1=\"13\" x2=\"23\" y2=\"11\"></line>",
"bell-off": "<path d=\"M13.73 21a2 2 0 0 1-3.46 0\"></path><path d=\"M18.63 13A17.89 17.89 0 0 1 18 8\"></path><path d=\"M6.26 6.26A5.86 5.86 0 0 0 6 8c0 7-3 9-3 9h14\"></path><path d=\"M18 8a6 6 0 0 0-9.33-5\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"bell": "<path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"></path><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"></path>",
"bluetooth": "<polyline points=\"6.5 6.5 17.5 17.5 12 23 12 1 17.5 6.5 6.5 17.5\"></polyline>",
"bold": "<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"></path><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"></path>",
"book-open": "<path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\"></path><path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\"></path>",
"book": "<path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"></path><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"></path>",
"bookmark": "<path d=\"M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"></path>",
"box": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"briefcase": "<rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\"></path>",
"calendar": "<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line>",
"camera-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M21 21H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3m3-3h6l2 3h4a2 2 0 0 1 2 2v9.34m-7.72-2.06a4 4 0 1 1-5.56-5.56\"></path>",
"camera": "<path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\"></path><circle cx=\"12\" cy=\"13\" r=\"4\"></circle>",
"cast": "<path d=\"M2 16.1A5 5 0 0 1 5.9 20M2 12.05A9 9 0 0 1 9.95 20M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6\"></path><line x1=\"2\" y1=\"20\" x2=\"2.01\" y2=\"20\"></line>",
"check-circle": "<path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><polyline points=\"22 4 12 14.01 9 11.01\"></polyline>",
"check-square": "<polyline points=\"9 11 12 14 22 4\"></polyline><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"></path>",
"check": "<polyline points=\"20 6 9 17 4 12\"></polyline>",
"chevron-down": "<polyline points=\"6 9 12 15 18 9\"></polyline>",
"chevron-left": "<polyline points=\"15 18 9 12 15 6\"></polyline>",
"chevron-right": "<polyline points=\"9 18 15 12 9 6\"></polyline>",
"chevron-up": "<polyline points=\"18 15 12 9 6 15\"></polyline>",
"chevrons-down": "<polyline points=\"7 13 12 18 17 13\"></polyline><polyline points=\"7 6 12 11 17 6\"></polyline>",
"chevrons-left": "<polyline points=\"11 17 6 12 11 7\"></polyline><polyline points=\"18 17 13 12 18 7\"></polyline>",
"chevrons-right": "<polyline points=\"13 17 18 12 13 7\"></polyline><polyline points=\"6 17 11 12 6 7\"></polyline>",
"chevrons-up": "<polyline points=\"17 11 12 6 7 11\"></polyline><polyline points=\"17 18 12 13 7 18\"></polyline>",
"chrome": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"21.17\" y1=\"8\" x2=\"12\" y2=\"8\"></line><line x1=\"3.95\" y1=\"6.06\" x2=\"8.54\" y2=\"14\"></line><line x1=\"10.88\" y1=\"21.94\" x2=\"15.46\" y2=\"14\"></line>",
"circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle>",
"clipboard": "<path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"></path><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\" ry=\"1\"></rect>",
"clock": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 6 12 12 16 14\"></polyline>",
"cloud-drizzle": "<line x1=\"8\" y1=\"19\" x2=\"8\" y2=\"21\"></line><line x1=\"8\" y1=\"13\" x2=\"8\" y2=\"15\"></line><line x1=\"16\" y1=\"19\" x2=\"16\" y2=\"21\"></line><line x1=\"16\" y1=\"13\" x2=\"16\" y2=\"15\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"17\"></line><path d=\"M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25\"></path>",
"cloud-lightning": "<path d=\"M19 16.9A5 5 0 0 0 18 7h-1.26a8 8 0 1 0-11.62 9\"></path><polyline points=\"13 11 9 17 15 17 11 23\"></polyline>",
"cloud-off": "<path d=\"M22.61 16.95A5 5 0 0 0 18 10h-1.26a8 8 0 0 0-7.05-6M5 5a8 8 0 0 0 4 15h9a5 5 0 0 0 1.7-.3\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"cloud-rain": "<line x1=\"16\" y1=\"13\" x2=\"16\" y2=\"21\"></line><line x1=\"8\" y1=\"13\" x2=\"8\" y2=\"21\"></line><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"23\"></line><path d=\"M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25\"></path>",
"cloud-snow": "<path d=\"M20 17.58A5 5 0 0 0 18 8h-1.26A8 8 0 1 0 4 16.25\"></path><line x1=\"8\" y1=\"16\" x2=\"8.01\" y2=\"16\"></line><line x1=\"8\" y1=\"20\" x2=\"8.01\" y2=\"20\"></line><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line><line x1=\"12\" y1=\"22\" x2=\"12.01\" y2=\"22\"></line><line x1=\"16\" y1=\"16\" x2=\"16.01\" y2=\"16\"></line><line x1=\"16\" y1=\"20\" x2=\"16.01\" y2=\"20\"></line>",
"cloud": "<path d=\"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z\"></path>",
"code": "<polyline points=\"16 18 22 12 16 6\"></polyline><polyline points=\"8 6 2 12 8 18\"></polyline>",
"codepen": "<polygon points=\"12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2\"></polygon><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"15.5\"></line><polyline points=\"22 8.5 12 15.5 2 8.5\"></polyline><polyline points=\"2 15.5 12 8.5 22 15.5\"></polyline><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"8.5\"></line>",
"codesandbox": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"></polyline><polyline points=\"7.5 19.79 7.5 14.6 3 12\"></polyline><polyline points=\"21 12 16.5 14.6 16.5 19.79\"></polyline><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"coffee": "<path d=\"M18 8h1a4 4 0 0 1 0 8h-1\"></path><path d=\"M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z\"></path><line x1=\"6\" y1=\"1\" x2=\"6\" y2=\"4\"></line><line x1=\"10\" y1=\"1\" x2=\"10\" y2=\"4\"></line><line x1=\"14\" y1=\"1\" x2=\"14\" y2=\"4\"></line>",
"columns": "<path d=\"M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18\"></path>",
"command": "<path d=\"M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z\"></path>",
"compass": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polygon points=\"16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76\"></polygon>",
"copy": "<rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>",
"corner-down-left": "<polyline points=\"9 10 4 15 9 20\"></polyline><path d=\"M20 4v7a4 4 0 0 1-4 4H4\"></path>",
"corner-down-right": "<polyline points=\"15 10 20 15 15 20\"></polyline><path d=\"M4 4v7a4 4 0 0 0 4 4h12\"></path>",
"corner-left-down": "<polyline points=\"14 15 9 20 4 15\"></polyline><path d=\"M20 4h-7a4 4 0 0 0-4 4v12\"></path>",
"corner-left-up": "<polyline points=\"14 9 9 4 4 9\"></polyline><path d=\"M20 20h-7a4 4 0 0 1-4-4V4\"></path>",
"corner-right-down": "<polyline points=\"10 15 15 20 20 15\"></polyline><path d=\"M4 4h7a4 4 0 0 1 4 4v12\"></path>",
"corner-right-up": "<polyline points=\"10 9 15 4 20 9\"></polyline><path d=\"M4 20h7a4 4 0 0 0 4-4V4\"></path>",
"corner-up-left": "<polyline points=\"9 14 4 9 9 4\"></polyline><path d=\"M20 20v-7a4 4 0 0 0-4-4H4\"></path>",
"corner-up-right": "<polyline points=\"15 14 20 9 15 4\"></polyline><path d=\"M4 20v-7a4 4 0 0 1 4-4h12\"></path>",
"cpu": "<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" ry=\"2\"></rect><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"></rect><line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\"></line><line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\"></line><line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\"></line><line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\"></line><line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\"></line><line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\"></line><line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\"></line><line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\"></line>",
"credit-card": "<rect x=\"1\" y=\"4\" width=\"22\" height=\"16\" rx=\"2\" ry=\"2\"></rect><line x1=\"1\" y1=\"10\" x2=\"23\" y2=\"10\"></line>",
"crop": "<path d=\"M6.13 1L6 16a2 2 0 0 0 2 2h15\"></path><path d=\"M1 6.13L16 6a2 2 0 0 1 2 2v15\"></path>",
"crosshair": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"22\" y1=\"12\" x2=\"18\" y2=\"12\"></line><line x1=\"6\" y1=\"12\" x2=\"2\" y2=\"12\"></line><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"2\"></line><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"18\"></line>",
"database": "<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"></ellipse><path d=\"M21 12c0 1.66-4 3-9 3s-9-1.34-9-3\"></path><path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\"></path>",
"delete": "<path d=\"M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z\"></path><line x1=\"18\" y1=\"9\" x2=\"12\" y2=\"15\"></line><line x1=\"12\" y1=\"9\" x2=\"18\" y2=\"15\"></line>",
"disc": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>",
"divide-circle": "<line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"16\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"8\"></line><circle cx=\"12\" cy=\"12\" r=\"10\"></circle>",
"divide-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"16\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"8\"></line>",
"divide": "<circle cx=\"12\" cy=\"6\" r=\"2\"></circle><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><circle cx=\"12\" cy=\"18\" r=\"2\"></circle>",
"dollar-sign": "<line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"23\"></line><path d=\"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6\"></path>",
"download-cloud": "<polyline points=\"8 17 12 21 16 17\"></polyline><line x1=\"12\" y1=\"12\" x2=\"12\" y2=\"21\"></line><path d=\"M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29\"></path>",
"download": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path><polyline points=\"7 10 12 15 17 10\"></polyline><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>",
"dribbble": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M8.56 2.75c4.37 6.03 6.02 9.42 8.03 17.72m2.54-15.38c-3.72 4.35-8.94 5.66-16.88 5.85m19.5 1.9c-3.5-.93-6.63-.82-8.94 0-2.58.92-5.01 2.86-7.44 6.32\"></path>",
"droplet": "<path d=\"M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z\"></path>",
"edit-2": "<path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\"></path>",
"edit-3": "<path d=\"M12 20h9\"></path><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"></path>",
"edit": "<path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"></path>",
"external-link": "<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path><polyline points=\"15 3 21 3 21 9\"></polyline><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>",
"eye-off": "<path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"eye": "<path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>",
"facebook": "<path d=\"M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z\"></path>",
"fast-forward": "<polygon points=\"13 19 22 12 13 5 13 19\"></polygon><polygon points=\"2 19 11 12 2 5 2 19\"></polygon>",
"feather": "<path d=\"M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z\"></path><line x1=\"16\" y1=\"8\" x2=\"2\" y2=\"22\"></line><line x1=\"17.5\" y1=\"15\" x2=\"9\" y2=\"15\"></line>",
"figma": "<path d=\"M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z\"></path><path d=\"M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z\"></path><path d=\"M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z\"></path><path d=\"M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z\"></path><path d=\"M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z\"></path>",
"file-minus": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"9\" y1=\"15\" x2=\"15\" y2=\"15\"></line>",
"file-plus": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"12\"></line><line x1=\"9\" y1=\"15\" x2=\"15\" y2=\"15\"></line>",
"file-text": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"></line><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"></line><polyline points=\"10 9 9 9 8 9\"></polyline>",
"file": "<path d=\"M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\"></path><polyline points=\"13 2 13 9 20 9\"></polyline>",
"film": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2.18\" ry=\"2.18\"></rect><line x1=\"7\" y1=\"2\" x2=\"7\" y2=\"22\"></line><line x1=\"17\" y1=\"2\" x2=\"17\" y2=\"22\"></line><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"2\" y1=\"7\" x2=\"7\" y2=\"7\"></line><line x1=\"2\" y1=\"17\" x2=\"7\" y2=\"17\"></line><line x1=\"17\" y1=\"17\" x2=\"22\" y2=\"17\"></line><line x1=\"17\" y1=\"7\" x2=\"22\" y2=\"7\"></line>",
"filter": "<polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon>",
"flag": "<path d=\"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z\"></path><line x1=\"4\" y1=\"22\" x2=\"4\" y2=\"15\"></line>",
"folder-minus": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path><line x1=\"9\" y1=\"14\" x2=\"15\" y2=\"14\"></line>",
"folder-plus": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"17\"></line><line x1=\"9\" y1=\"14\" x2=\"15\" y2=\"14\"></line>",
"folder": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path>",
"framer": "<path d=\"M5 16V9h14V2H5l14 14h-7m-7 0l7 7v-7m-7 0h7\"></path>",
"frown": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M16 16s-1.5-2-4-2-4 2-4 2\"></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"gift": "<polyline points=\"20 12 20 22 4 22 4 12\"></polyline><rect x=\"2\" y=\"7\" width=\"20\" height=\"5\"></rect><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"7\"></line><path d=\"M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z\"></path><path d=\"M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z\"></path>",
"git-branch": "<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"></line><circle cx=\"18\" cy=\"6\" r=\"3\"></circle><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><path d=\"M18 9a9 9 0 0 1-9 9\"></path>",
"git-commit": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"1.05\" y1=\"12\" x2=\"7\" y2=\"12\"></line><line x1=\"17.01\" y1=\"12\" x2=\"22.96\" y2=\"12\"></line>",
"git-merge": "<circle cx=\"18\" cy=\"18\" r=\"3\"></circle><circle cx=\"6\" cy=\"6\" r=\"3\"></circle><path d=\"M6 21V9a9 9 0 0 0 9 9\"></path>",
"git-pull-request": "<circle cx=\"18\" cy=\"18\" r=\"3\"></circle><circle cx=\"6\" cy=\"6\" r=\"3\"></circle><path d=\"M13 6h3a2 2 0 0 1 2 2v7\"></path><line x1=\"6\" y1=\"9\" x2=\"6\" y2=\"21\"></line>",
"github": "<path d=\"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22\"></path>",
"gitlab": "<path d=\"M22.65 14.39L12 22.13 1.35 14.39a.84.84 0 0 1-.3-.94l1.22-3.78 2.44-7.51A.42.42 0 0 1 4.82 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.49h8.1l2.44-7.51A.42.42 0 0 1 18.6 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.51L23 13.45a.84.84 0 0 1-.35.94z\"></path>",
"globe": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"></path>",
"grid": "<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>",
"hard-drive": "<line x1=\"22\" y1=\"12\" x2=\"2\" y2=\"12\"></line><path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\"></path><line x1=\"6\" y1=\"16\" x2=\"6.01\" y2=\"16\"></line><line x1=\"10\" y1=\"16\" x2=\"10.01\" y2=\"16\"></line>",
"hash": "<line x1=\"4\" y1=\"9\" x2=\"20\" y2=\"9\"></line><line x1=\"4\" y1=\"15\" x2=\"20\" y2=\"15\"></line><line x1=\"10\" y1=\"3\" x2=\"8\" y2=\"21\"></line><line x1=\"16\" y1=\"3\" x2=\"14\" y2=\"21\"></line>",
"headphones": "<path d=\"M3 18v-6a9 9 0 0 1 18 0v6\"></path><path d=\"M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z\"></path>",
"heart": "<path d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"></path>",
"help-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>",
"hexagon": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path>",
"home": "<path d=\"M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"></path><polyline points=\"9 22 9 12 15 12 15 22\"></polyline>",
"image": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle><polyline points=\"21 15 16 10 5 21\"></polyline>",
"inbox": "<polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\"></polyline><path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\"></path>",
"info": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line>",
"instagram": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect><path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path><line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>",
"italic": "<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"></line><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"></line><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"></line>",
"key": "<path d=\"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4\"></path>",
"layers": "<polygon points=\"12 2 2 7 12 12 22 7 12 2\"></polygon><polyline points=\"2 17 12 22 22 17\"></polyline><polyline points=\"2 12 12 17 22 12\"></polyline>",
"layout": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"></line><line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\"></line>",
"life-buoy": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\"></line><line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\"></line><line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\"></line><line x1=\"14.83\" y1=\"9.17\" x2=\"18.36\" y2=\"5.64\"></line><line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\"></line>",
"link-2": "<path d=\"M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3\"></path><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"link": "<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"></path><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"></path>",
"linkedin": "<path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"></path><rect x=\"2\" y=\"9\" width=\"4\" height=\"12\"></rect><circle cx=\"4\" cy=\"4\" r=\"2\"></circle>",
"list": "<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"></line><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"></line><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"></line><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"></line><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"></line><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"></line>",
"loader": "<line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"6\"></line><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"></line><line x1=\"4.93\" y1=\"4.93\" x2=\"7.76\" y2=\"7.76\"></line><line x1=\"16.24\" y1=\"16.24\" x2=\"19.07\" y2=\"19.07\"></line><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\"></line><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"4.93\" y1=\"19.07\" x2=\"7.76\" y2=\"16.24\"></line><line x1=\"16.24\" y1=\"7.76\" x2=\"19.07\" y2=\"4.93\"></line>",
"lock": "<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>",
"log-in": "<path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"></path><polyline points=\"10 17 15 12 10 7\"></polyline><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"></line>",
"log-out": "<path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"></path><polyline points=\"16 17 21 12 16 7\"></polyline><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"></line>",
"mail": "<path d=\"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z\"></path><polyline points=\"22,6 12,13 2,6\"></polyline>",
"map-pin": "<path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"></path><circle cx=\"12\" cy=\"10\" r=\"3\"></circle>",
"map": "<polygon points=\"1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6\"></polygon><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"18\"></line><line x1=\"16\" y1=\"6\" x2=\"16\" y2=\"22\"></line>",
"maximize-2": "<polyline points=\"15 3 21 3 21 9\"></polyline><polyline points=\"9 21 3 21 3 15\"></polyline><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"></line><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"></line>",
"maximize": "<path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"></path>",
"meh": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"8\" y1=\"15\" x2=\"16\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"menu": "<line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>",
"message-circle": "<path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\"></path>",
"message-square": "<path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>",
"mic-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\"></path><path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\"></path><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>",
"mic": "<path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>",
"minimize-2": "<polyline points=\"4 14 10 14 10 20\"></polyline><polyline points=\"20 10 14 10 14 4\"></polyline><line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\"></line><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"></line>",
"minimize": "<path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\"></path>",
"minus-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"minus-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"minus": "<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>",
"monitor": "<rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line>",
"moon": "<path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"></path>",
"more-horizontal": "<circle cx=\"12\" cy=\"12\" r=\"1\"></circle><circle cx=\"19\" cy=\"12\" r=\"1\"></circle><circle cx=\"5\" cy=\"12\" r=\"1\"></circle>",
"more-vertical": "<circle cx=\"12\" cy=\"12\" r=\"1\"></circle><circle cx=\"12\" cy=\"5\" r=\"1\"></circle><circle cx=\"12\" cy=\"19\" r=\"1\"></circle>",
"mouse-pointer": "<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"></path><path d=\"M13 13l6 6\"></path>",
"move": "<polyline points=\"5 9 2 12 5 15\"></polyline><polyline points=\"9 5 12 2 15 5\"></polyline><polyline points=\"15 19 12 22 9 19\"></polyline><polyline points=\"19 9 22 12 19 15\"></polyline><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"22\"></line>",
"music": "<path d=\"M9 18V5l12-2v13\"></path><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><circle cx=\"18\" cy=\"16\" r=\"3\"></circle>",
"navigation-2": "<polygon points=\"12 2 19 21 12 17 5 21 12 2\"></polygon>",
"navigation": "<polygon points=\"3 11 22 2 13 21 11 13 3 11\"></polygon>",
"octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon>",
"package": "<line x1=\"16.5\" y1=\"9.4\" x2=\"7.5\" y2=\"4.21\"></line><path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"paperclip": "<path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"></path>",
"pause-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"10\" y1=\"15\" x2=\"10\" y2=\"9\"></line><line x1=\"14\" y1=\"15\" x2=\"14\" y2=\"9\"></line>",
"pause": "<rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect>",
"pen-tool": "<path d=\"M12 19l7-7 3 3-7 7-3-3z\"></path><path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\"></path><path d=\"M2 2l7.586 7.586\"></path><circle cx=\"11\" cy=\"11\" r=\"2\"></circle>",
"percent": "<line x1=\"19\" y1=\"5\" x2=\"5\" y2=\"19\"></line><circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\"></circle><circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\"></circle>",
"phone-call": "<path d=\"M15.05 5A5 5 0 0 1 19 8.95M15.05 1A9 9 0 0 1 23 8.94m-1 7.98v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-forwarded": "<polyline points=\"19 1 23 5 19 9\"></polyline><line x1=\"15\" y1=\"5\" x2=\"23\" y2=\"5\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-incoming": "<polyline points=\"16 2 16 8 22 8\"></polyline><line x1=\"23\" y1=\"1\" x2=\"16\" y2=\"8\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-missed": "<line x1=\"23\" y1=\"1\" x2=\"17\" y2=\"7\"></line><line x1=\"17\" y1=\"1\" x2=\"23\" y2=\"7\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-off": "<path d=\"M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7 2 2 0 0 1 1.72 2v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67m-2.67-3.34a19.79 19.79 0 0 1-3.07-8.63A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91\"></path><line x1=\"23\" y1=\"1\" x2=\"1\" y2=\"23\"></line>",
"phone-outgoing": "<polyline points=\"23 7 23 1 17 1\"></polyline><line x1=\"16\" y1=\"8\" x2=\"23\" y2=\"1\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone": "<path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"pie-chart": "<path d=\"M21.21 15.89A10 10 0 1 1 8 2.83\"></path><path d=\"M22 12A10 10 0 0 0 12 2v10z\"></path>",
"play-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polygon points=\"10 8 16 12 10 16 10 8\"></polygon>",
"play": "<polygon points=\"5 3 19 12 5 21 5 3\"></polygon>",
"plus-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"plus-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"plus": "<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>",
"pocket": "<path d=\"M4 3h16a2 2 0 0 1 2 2v6a10 10 0 0 1-10 10A10 10 0 0 1 2 11V5a2 2 0 0 1 2-2z\"></path><polyline points=\"8 10 12 14 16 10\"></polyline>",
"power": "<path d=\"M18.36 6.64a9 9 0 1 1-12.73 0\"></path><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"12\"></line>",
"printer": "<polyline points=\"6 9 6 2 18 2 18 9\"></polyline><path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"></path><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"></rect>",
"radio": "<circle cx=\"12\" cy=\"12\" r=\"2\"></circle><path d=\"M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14\"></path>",
"refresh-ccw": "<polyline points=\"1 4 1 10 7 10\"></polyline><polyline points=\"23 20 23 14 17 14\"></polyline><path d=\"M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15\"></path>",
"refresh-cw": "<polyline points=\"23 4 23 10 17 10\"></polyline><polyline points=\"1 20 1 14 7 14\"></polyline><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>",
"repeat": "<polyline points=\"17 1 21 5 17 9\"></polyline><path d=\"M3 11V9a4 4 0 0 1 4-4h14\"></path><polyline points=\"7 23 3 19 7 15\"></polyline><path d=\"M21 13v2a4 4 0 0 1-4 4H3\"></path>",
"rewind": "<polygon points=\"11 19 2 12 11 5 11 19\"></polygon><polygon points=\"22 19 13 12 22 5 22 19\"></polygon>",
"rotate-ccw": "<polyline points=\"1 4 1 10 7 10\"></polyline><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"></path>",
"rotate-cw": "<polyline points=\"23 4 23 10 17 10\"></polyline><path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\"></path>",
"rss": "<path d=\"M4 11a9 9 0 0 1 9 9\"></path><path d=\"M4 4a16 16 0 0 1 16 16\"></path><circle cx=\"5\" cy=\"19\" r=\"1\"></circle>",
"save": "<path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\"></path><polyline points=\"17 21 17 13 7 13 7 21\"></polyline><polyline points=\"7 3 7 8 15 8\"></polyline>",
"scissors": "<circle cx=\"6\" cy=\"6\" r=\"3\"></circle><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><line x1=\"20\" y1=\"4\" x2=\"8.12\" y2=\"15.88\"></line><line x1=\"14.47\" y1=\"14.48\" x2=\"20\" y2=\"20\"></line><line x1=\"8.12\" y1=\"8.12\" x2=\"12\" y2=\"12\"></line>",
"search": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>",
"send": "<line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line><polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>",
"server": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"></rect><rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"></rect><line x1=\"6\" y1=\"6\" x2=\"6.01\" y2=\"6\"></line><line x1=\"6\" y1=\"18\" x2=\"6.01\" y2=\"18\"></line>",
"settings": "<circle cx=\"12\" cy=\"12\" r=\"3\"></circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path>",
"share-2": "<circle cx=\"18\" cy=\"5\" r=\"3\"></circle><circle cx=\"6\" cy=\"12\" r=\"3\"></circle><circle cx=\"18\" cy=\"19\" r=\"3\"></circle><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\"></line><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\"></line>",
"share": "<path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\"></path><polyline points=\"16 6 12 2 8 6\"></polyline><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"15\"></line>",
"shield-off": "<path d=\"M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18\"></path><path d=\"M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"shield": "<path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"></path>",
"shopping-bag": "<path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z\"></path><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line><path d=\"M16 10a4 4 0 0 1-8 0\"></path>",
"shopping-cart": "<circle cx=\"9\" cy=\"21\" r=\"1\"></circle><circle cx=\"20\" cy=\"21\" r=\"1\"></circle><path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"></path>",
"shuffle": "<polyline points=\"16 3 21 3 21 8\"></polyline><line x1=\"4\" y1=\"20\" x2=\"21\" y2=\"3\"></line><polyline points=\"21 16 21 21 16 21\"></polyline><line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\"></line><line x1=\"4\" y1=\"4\" x2=\"9\" y2=\"9\"></line>",
"sidebar": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"></line>",
"skip-back": "<polygon points=\"19 20 9 12 19 4 19 20\"></polygon><line x1=\"5\" y1=\"19\" x2=\"5\" y2=\"5\"></line>",
"skip-forward": "<polygon points=\"5 4 15 12 5 20 5 4\"></polygon><line x1=\"19\" y1=\"5\" x2=\"19\" y2=\"19\"></line>",
"slack": "<path d=\"M14.5 10c-.83 0-1.5-.67-1.5-1.5v-5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5z\"></path><path d=\"M20.5 10H19V8.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path><path d=\"M9.5 14c.83 0 1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5S8 21.33 8 20.5v-5c0-.83.67-1.5 1.5-1.5z\"></path><path d=\"M3.5 14H5v1.5c0 .83-.67 1.5-1.5 1.5S2 16.33 2 15.5 2.67 14 3.5 14z\"></path><path d=\"M14 14.5c0-.83.67-1.5 1.5-1.5h5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-5c-.83 0-1.5-.67-1.5-1.5z\"></path><path d=\"M15.5 19H14v1.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z\"></path><path d=\"M10 9.5C10 8.67 9.33 8 8.5 8h-5C2.67 8 2 8.67 2 9.5S2.67 11 3.5 11h5c.83 0 1.5-.67 1.5-1.5z\"></path><path d=\"M8.5 5H10V3.5C10 2.67 9.33 2 8.5 2S7 2.67 7 3.5 7.67 5 8.5 5z\"></path>",
"slash": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"></line>",
"sliders": "<line x1=\"4\" y1=\"21\" x2=\"4\" y2=\"14\"></line><line x1=\"4\" y1=\"10\" x2=\"4\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"3\"></line><line x1=\"20\" y1=\"21\" x2=\"20\" y2=\"16\"></line><line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"3\"></line><line x1=\"1\" y1=\"14\" x2=\"7\" y2=\"14\"></line><line x1=\"9\" y1=\"8\" x2=\"15\" y2=\"8\"></line><line x1=\"17\" y1=\"16\" x2=\"23\" y2=\"16\"></line>",
"smartphone": "<rect x=\"5\" y=\"2\" width=\"14\" height=\"20\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line>",
"smile": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M8 14s1.5 2 4 2 4-2 4-2\"></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"speaker": "<rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"></rect><circle cx=\"12\" cy=\"14\" r=\"4\"></circle><line x1=\"12\" y1=\"6\" x2=\"12.01\" y2=\"6\"></line>",
"square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>",
"star": "<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"></polygon>",
"stop-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"></rect>",
"sun": "<circle cx=\"12\" cy=\"12\" r=\"5\"></circle><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>",
"sunrise": "<path d=\"M17 18a5 5 0 0 0-10 0\"></path><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"9\"></line><line x1=\"4.22\" y1=\"10.22\" x2=\"5.64\" y2=\"11.64\"></line><line x1=\"1\" y1=\"18\" x2=\"3\" y2=\"18\"></line><line x1=\"21\" y1=\"18\" x2=\"23\" y2=\"18\"></line><line x1=\"18.36\" y1=\"11.64\" x2=\"19.78\" y2=\"10.22\"></line><line x1=\"23\" y1=\"22\" x2=\"1\" y2=\"22\"></line><polyline points=\"8 6 12 2 16 6\"></polyline>",
"sunset": "<path d=\"M17 18a5 5 0 0 0-10 0\"></path><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"2\"></line><line x1=\"4.22\" y1=\"10.22\" x2=\"5.64\" y2=\"11.64\"></line><line x1=\"1\" y1=\"18\" x2=\"3\" y2=\"18\"></line><line x1=\"21\" y1=\"18\" x2=\"23\" y2=\"18\"></line><line x1=\"18.36\" y1=\"11.64\" x2=\"19.78\" y2=\"10.22\"></line><line x1=\"23\" y1=\"22\" x2=\"1\" y2=\"22\"></line><polyline points=\"16 5 12 9 8 5\"></polyline>",
"table": "<path d=\"M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18\"></path>",
"tablet": "<rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line>",
"tag": "<path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"></path><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"></line>",
"target": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"6\"></circle><circle cx=\"12\" cy=\"12\" r=\"2\"></circle>",
"terminal": "<polyline points=\"4 17 10 11 4 5\"></polyline><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"></line>",
"thermometer": "<path d=\"M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z\"></path>",
"thumbs-down": "<path d=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"></path>",
"thumbs-up": "<path d=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"></path>",
"toggle-left": "<rect x=\"1\" y=\"5\" width=\"22\" height=\"14\" rx=\"7\" ry=\"7\"></rect><circle cx=\"8\" cy=\"12\" r=\"3\"></circle>",
"toggle-right": "<rect x=\"1\" y=\"5\" width=\"22\" height=\"14\" rx=\"7\" ry=\"7\"></rect><circle cx=\"16\" cy=\"12\" r=\"3\"></circle>",
"tool": "<path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\"></path>",
"trash-2": "<polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"></line><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"></line>",
"trash": "<polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>",
"trello": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><rect x=\"7\" y=\"7\" width=\"3\" height=\"9\"></rect><rect x=\"14\" y=\"7\" width=\"3\" height=\"5\"></rect>",
"trending-down": "<polyline points=\"23 18 13.5 8.5 8.5 13.5 1 6\"></polyline><polyline points=\"17 18 23 18 23 12\"></polyline>",
"trending-up": "<polyline points=\"23 6 13.5 15.5 8.5 10.5 1 18\"></polyline><polyline points=\"17 6 23 6 23 12\"></polyline>",
"triangle": "<path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path>",
"truck": "<rect x=\"1\" y=\"3\" width=\"15\" height=\"13\"></rect><polygon points=\"16 8 20 8 23 11 23 16 16 16 16 8\"></polygon><circle cx=\"5.5\" cy=\"18.5\" r=\"2.5\"></circle><circle cx=\"18.5\" cy=\"18.5\" r=\"2.5\"></circle>",
"tv": "<rect x=\"2\" y=\"7\" width=\"20\" height=\"15\" rx=\"2\" ry=\"2\"></rect><polyline points=\"17 2 12 7 7 2\"></polyline>",
"twitch": "<path d=\"M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7\"></path>",
"twitter": "<path d=\"M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z\"></path>",
"type": "<polyline points=\"4 7 4 4 20 4 20 7\"></polyline><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"></line><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"></line>",
"umbrella": "<path d=\"M23 12a11.05 11.05 0 0 0-22 0zm-5 7a3 3 0 0 1-6 0v-7\"></path>",
"underline": "<path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"></path><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"></line>",
"unlock": "<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"></path>",
"upload-cloud": "<polyline points=\"16 16 12 12 8 16\"></polyline><line x1=\"12\" y1=\"12\" x2=\"12\" y2=\"21\"></line><path d=\"M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3\"></path><polyline points=\"16 16 12 12 8 16\"></polyline>",
"upload": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path><polyline points=\"17 8 12 3 7 8\"></polyline><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"></line>",
"user-check": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><polyline points=\"17 11 19 13 23 9\"></polyline>",
"user-minus": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\"></line>",
"user-plus": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\"></line><line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\"></line>",
"user-x": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"18\" y1=\"8\" x2=\"23\" y2=\"13\"></line><line x1=\"23\" y1=\"8\" x2=\"18\" y2=\"13\"></line>",
"user": "<path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"></path><circle cx=\"12\" cy=\"7\" r=\"4\"></circle>",
"users": "<path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"9\" cy=\"7\" r=\"4\"></circle><path d=\"M23 21v-2a4 4 0 0 0-3-3.87\"></path><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"></path>",
"video-off": "<path d=\"M16 16v1a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2m5.66 0H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"video": "<polygon points=\"23 7 16 12 23 17 23 7\"></polygon><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"></rect>",
"voicemail": "<circle cx=\"5.5\" cy=\"11.5\" r=\"4.5\"></circle><circle cx=\"18.5\" cy=\"11.5\" r=\"4.5\"></circle><line x1=\"5.5\" y1=\"16\" x2=\"18.5\" y2=\"16\"></line>",
"volume-1": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\"></path>",
"volume-2": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><path d=\"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\"></path>",
"volume-x": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\"></line><line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\"></line>",
"volume": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon>",
"watch": "<circle cx=\"12\" cy=\"12\" r=\"7\"></circle><polyline points=\"12 9 12 12 13.5 13.5\"></polyline><path d=\"M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83\"></path>",
"wifi-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\"></path><path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\"></path><path d=\"M10.71 5.05A16 16 0 0 1 22.58 9\"></path><path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\"></path><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\"></path><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\"></line>",
"wifi": "<path d=\"M5 12.55a11 11 0 0 1 14.08 0\"></path><path d=\"M1.42 9a16 16 0 0 1 21.16 0\"></path><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\"></path><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\"></line>",
"wind": "<path d=\"M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2\"></path>",
"x-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>",
"x-octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>",
"x-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line>",
"x": "<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>",
"youtube": "<path d=\"M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z\"></path><polygon points=\"9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02\"></polygon>",
"zap-off": "<polyline points=\"12.41 6.75 13 2 10.57 4.92\"></polyline><polyline points=\"18.57 12.91 21 10 15.66 10\"></polyline><polyline points=\"8 8 3 14 12 14 11 22 16 16\"></polyline><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"zap": "<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"></polygon>",
"zoom-in": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line><line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\"></line><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"></line>",
"zoom-out": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"></line>"
}

24
vendor/feather-icons/license vendored Normal file
View File

@ -0,0 +1,24 @@
https://github.com/feathericons/feather/blob/master/LICENSE
---
The MIT License (MIT)
Copyright (c) 2013-2017 Cole Bemis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

6
vendor/feather-icons/readme.md vendored Normal file
View File

@ -0,0 +1,6 @@
https://github.com/feathericons/feather
`icons.json` here is sourced from `dist/icons.json` from the bundle, version 4.29.0.
This is intentionally not installed from `npm install feather-icons` because that package includes all of `core-js` as a dependency (which this project gets zero benefit from and is very large, impacting container image size).