UNPKG

tether

Version:

A client-side library to make absolutely positioned elements attach to elements in the page efficiently.

1,538 lines (1,358 loc) 89.1 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>RollUp Visualizer</title> <style> :root { --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --background-color: #f7eedf; --text-color: #333; } @media (prefers-color-scheme: dark) { :root { --background-color: #2b2d42; --text-color: #edf2f4; } } html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } html { background-color: var(--background-color); color: var(--text-color); font-family: var(--font-family); } body { padding: 0; margin: 0; } html, body { height: 100%; width: 100%; overflow: hidden; } body { display: flex; flex-direction: column; } svg { vertical-align: middle; width: 100%; height: 100%; max-height: 100vh; } main { flex-grow: 1; height: 100vh; padding: 20px; } .tooltip { position: absolute; z-index: 1070; border: 2px solid; border-radius: 5px; padding: 5px; white-space: nowrap; font-size: 0.875rem; background-color: var(--background-color); color: var(--text-color); } .tooltip-hidden { visibility: hidden; opacity: 0; } .sidebar { position: fixed; top: 0; left: 0; right: 0; display: flex; flex-direction: row; font-size: 0.7rem; align-items: center; margin: 0 50px; height: 20px; } .size-selectors { display: flex; flex-direction: row; align-items: center; } .size-selector { display: flex; flex-direction: row; align-items: center; justify-content: center; margin-right: 1rem; } .size-selector input { margin: 0 0.3rem 0 0; } .filters { flex: 1; display: flex; flex-direction: row; align-items: center; } .filter { display: flex; flex-direction: row; align-items: center; justify-content: center; flex: 1; } .filter input { flex: 1; height: 1rem; padding: 0.1rem; font-size: 0.7rem; margin-left: 0.3rem; } .filter + .filter { margin-left: 0.5rem; } </style> </head> <body> <main></main> <script> /*<!--*/ var drawChart = (function () { 'use strict'; var n$1,u$1,i$1,t$2,r$1={},f$1=[],e$2=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s$1(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n$1.__v:o};return null!=n$1.vnode&&n$1.vnode(r),r}function y$1(n){return n.children}function p$1(n,l){this.props=n,this.context=l;}function d$1(n,l){if(null==l)return n.__?d$1(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?d$1(n):null}function _(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return _(n)}}function k$1(l){(!l.__d&&(l.__d=!0)&&u$1.push(l)&&!b$1.__r++||t$2!==n$1.debounceRendering)&&((t$2=n$1.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=u$1.length;)n=u$1.sort(function(n,l){return n.__v.__b-l.__v.__b}),u$1=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d$1(t):o,t.__h),T(u,t),t.__e!=o&&_(t)));});}function m$2(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y$1,{children:k},null,null,null):k.__b>0?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d$1(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d$1(i,h+1)),L(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C(n,o,l[o],u[o],i);}function P(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$2.test(l)?u:u+"px";}function C(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H:$,o):n.removeEventListener(l,o?H:$,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $(l){this.l[l.type+!1](n$1.event?n$1.event(l):l);}function H(l){this.l[l.type+!0](n$1.event?n$1.event(l):l);}function I(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n$1.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p$1(g,x),v.constructor=P,v.render=M),w&&w.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n$1.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y$1&&null==a.key?a.props.children:a,m$2(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$1(i.__e,u,i,t,o,r,f,s);(a=n$1.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n$1.__e(l,u,i);}}function T(l,u){n$1.__c&&n$1.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n$1.__e(l,u.__v);}});}function j$1(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m$2(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s$1(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n$1.__e(l,i);}}function L(l,u,i){var t,o,r;if(n$1.unmount&&n$1.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n$1.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L(t[r],u,i);null!=o&&s$1(o);}function M(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n$1.__&&n$1.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I(u,l=(!t&&i||u).__k=a$1(y$1,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T(e,l);}n$1={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p$1.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k$1(this));},p$1.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k$1(this));},p$1.prototype.render=y$1,u$1=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,b$1.__r=0,0; var n=function(t,s,r,e){var u;s[0]=0;for(var h=1;h<s.length;h++){var p=s[h++],a=s[h]?(s[0]|=p?1:2,r[s[h++]]):s[++h];3===p?e[0]=a:4===p?e[1]=Object.assign(e[1]||{},a):5===p?(e[1]=e[1]||{})[s[++h]]=a:6===p?e[1][s[++h]]+=a+"":p?(u=t.apply(a,n(t,a,r,["",null])),e.push(u),a[0]?s[0]|=2:(s[h-2]=0,s[h]=u)):e.push(a);}return e},t$1=new Map;function e$1(s){var r=t$1.get(this);return r||(r=new Map,t$1.set(this,r)),(r=n(this,r.get(s)||(r.set(s,r=function(n){for(var t,s,r=1,e="",u="",h=[0],p=function(n){1===r&&(n||(e=e.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?h.push(0,n,e):3===r&&(n||e)?(h.push(3,n,e),r=2):2===r&&"..."===e&&n?h.push(4,n,0):2===r&&e&&!n?h.push(5,0,!0,e):r>=5&&((e||!n&&5===r)&&(h.push(r,0,e,s),r=6),n&&(h.push(r,n,0,s),r=6)),e="";},a=0;a<n.length;a++){a&&(1===r&&p(),p(a));for(var l=0;l<n[a].length;l++)t=n[a][l],1===r?"<"===t?(p(),h=[h],r=3):e+=t:4===r?"--"===e&&">"===t?(r=1,e=""):e=t+e[0]:u?t===u?u="":e+=t:'"'===t||"'"===t?u=t:">"===t?(p(),r=1):r&&("="===t?(r=5,s=e,e=""):"/"===t&&(r<5||">"===n[a][l+1])?(p(),3===r&&(h=h[0]),r=h,(h=h[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(p(),r=2):e+=t),3===r&&"!--"===e&&(r=4,h=h[0]);}return p(),h}(s)),r),arguments,[])).length>1?r:r[0]} var m$1=e$1.bind(a$1); var t,u,r,o=0,i=[],c=n$1.__b,f=n$1.__r,e=n$1.diffed,a=n$1.__c,v=n$1.unmount;function m(t,r){n$1.__h&&n$1.__h(u,t,o||r),o=0;var i=u.__H||(u.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({}),i.__[t]}function l(n){return o=1,p(w,n)}function p(n,r,o){var i=m(t++,2);return i.t=n,i.__c||(i.__=[o?o(r):w(void 0,r),function(n){var t=i.t(i.__[0],n);i.__[0]!==t&&(i.__=[t,i.__[1]],i.__c.setState({}));}],i.__c=u),i.__}function y(r,o){var i=m(t++,3);!n$1.__s&&k(i.__H,o)&&(i.__=r,i.__H=o,u.__H.__h.push(i));}function s(n){return o=5,d(function(){return {current:n}},[])}function d(n,u){var r=m(t++,7);return k(r.__H,u)&&(r.__=n(),r.__H=u,r.__h=n),r.__}function x(){i.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j),t.__H.__h=[];}catch(u){t.__H.__h=[],n$1.__e(u,t.__v);}}),i=[];}n$1.__b=function(n){u=null,c&&c(n);},n$1.__r=function(n){f&&f(n),t=0;var r=(u=n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j),r.__h=[]);},n$1.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===n$1.requestAnimationFrame||((r=n$1.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x)),u=void 0;},n$1.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n$1.__e(r,t.__v);}}),a&&a(t,u);},n$1.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){n$1.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){var t=u;"function"==typeof n.__c&&n.__c(),u=t;}function j(n){var t=u;n.__c=n.__(),u=t;}function k(n,t){return !n||n.length!==t.length||t.some(function(t,u){return t!==n[u]})}function w(n,t){return "function"==typeof t?t(n):t} function count$1(node) { var sum = 0, children = node.children, i = children && children.length; if (!i) sum = 1; else while (--i >= 0) sum += children[i].value; node.value = sum; } function node_count() { return this.eachAfter(count$1); } function node_each(callback, that) { let index = -1; for (const node of this) { callback.call(that, node, ++index, this); } return this; } function node_eachBefore(callback, that) { var node = this, nodes = [node], children, i, index = -1; while (node = nodes.pop()) { callback.call(that, node, ++index, this); if (children = node.children) { for (i = children.length - 1; i >= 0; --i) { nodes.push(children[i]); } } } return this; } function node_eachAfter(callback, that) { var node = this, nodes = [node], next = [], children, i, n, index = -1; while (node = nodes.pop()) { next.push(node); if (children = node.children) { for (i = 0, n = children.length; i < n; ++i) { nodes.push(children[i]); } } } while (node = next.pop()) { callback.call(that, node, ++index, this); } return this; } function node_find(callback, that) { let index = -1; for (const node of this) { if (callback.call(that, node, ++index, this)) { return node; } } } function node_sum(value) { return this.eachAfter(function(node) { var sum = +value(node.data) || 0, children = node.children, i = children && children.length; while (--i >= 0) sum += children[i].value; node.value = sum; }); } function node_sort(compare) { return this.eachBefore(function(node) { if (node.children) { node.children.sort(compare); } }); } function node_path(end) { var start = this, ancestor = leastCommonAncestor(start, end), nodes = [start]; while (start !== ancestor) { start = start.parent; nodes.push(start); } var k = nodes.length; while (end !== ancestor) { nodes.splice(k, 0, end); end = end.parent; } return nodes; } function leastCommonAncestor(a, b) { if (a === b) return a; var aNodes = a.ancestors(), bNodes = b.ancestors(), c = null; a = aNodes.pop(); b = bNodes.pop(); while (a === b) { c = a; a = aNodes.pop(); b = bNodes.pop(); } return c; } function node_ancestors() { var node = this, nodes = [node]; while (node = node.parent) { nodes.push(node); } return nodes; } function node_descendants() { return Array.from(this); } function node_leaves() { var leaves = []; this.eachBefore(function(node) { if (!node.children) { leaves.push(node); } }); return leaves; } function node_links() { var root = this, links = []; root.each(function(node) { if (node !== root) { // Don’t include the root’s parent, if any. links.push({source: node.parent, target: node}); } }); return links; } function* node_iterator() { var node = this, current, next = [node], children, i, n; do { current = next.reverse(), next = []; while (node = current.pop()) { yield node; if (children = node.children) { for (i = 0, n = children.length; i < n; ++i) { next.push(children[i]); } } } } while (next.length); } function hierarchy(data, children) { if (data instanceof Map) { data = [undefined, data]; if (children === undefined) children = mapChildren; } else if (children === undefined) { children = objectChildren; } var root = new Node$1(data), node, nodes = [root], child, childs, i, n; while (node = nodes.pop()) { if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) { node.children = childs; for (i = n - 1; i >= 0; --i) { nodes.push(child = childs[i] = new Node$1(childs[i])); child.parent = node; child.depth = node.depth + 1; } } } return root.eachBefore(computeHeight); } function node_copy() { return hierarchy(this).eachBefore(copyData); } function objectChildren(d) { return d.children; } function mapChildren(d) { return Array.isArray(d) ? d[1] : null; } function copyData(node) { if (node.data.value !== undefined) node.value = node.data.value; node.data = node.data.data; } function computeHeight(node) { var height = 0; do node.height = height; while ((node = node.parent) && (node.height < ++height)); } function Node$1(data) { this.data = data; this.depth = this.height = 0; this.parent = null; } Node$1.prototype = hierarchy.prototype = { constructor: Node$1, count: node_count, each: node_each, eachAfter: node_eachAfter, eachBefore: node_eachBefore, find: node_find, sum: node_sum, sort: node_sort, path: node_path, ancestors: node_ancestors, descendants: node_descendants, leaves: node_leaves, links: node_links, copy: node_copy, [Symbol.iterator]: node_iterator }; function required(f) { if (typeof f !== "function") throw new Error; return f; } function constantZero() { return 0; } function constant$1(x) { return function() { return x; }; } function roundNode(node) { node.x0 = Math.round(node.x0); node.y0 = Math.round(node.y0); node.x1 = Math.round(node.x1); node.y1 = Math.round(node.y1); } function treemapDice(parent, x0, y0, x1, y1) { var nodes = parent.children, node, i = -1, n = nodes.length, k = parent.value && (x1 - x0) / parent.value; while (++i < n) { node = nodes[i], node.y0 = y0, node.y1 = y1; node.x0 = x0, node.x1 = x0 += node.value * k; } } function treemapSlice(parent, x0, y0, x1, y1) { var nodes = parent.children, node, i = -1, n = nodes.length, k = parent.value && (y1 - y0) / parent.value; while (++i < n) { node = nodes[i], node.x0 = x0, node.x1 = x1; node.y0 = y0, node.y1 = y0 += node.value * k; } } var phi = (1 + Math.sqrt(5)) / 2; function squarifyRatio(ratio, parent, x0, y0, x1, y1) { var rows = [], nodes = parent.children, row, nodeValue, i0 = 0, i1 = 0, n = nodes.length, dx, dy, value = parent.value, sumValue, minValue, maxValue, newRatio, minRatio, alpha, beta; while (i0 < n) { dx = x1 - x0, dy = y1 - y0; // Find the next non-empty node. do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); minValue = maxValue = sumValue; alpha = Math.max(dy / dx, dx / dy) / (value * ratio); beta = sumValue * sumValue * alpha; minRatio = Math.max(maxValue / beta, beta / minValue); // Keep adding nodes while the aspect ratio maintains or improves. for (; i1 < n; ++i1) { sumValue += nodeValue = nodes[i1].value; if (nodeValue < minValue) minValue = nodeValue; if (nodeValue > maxValue) maxValue = nodeValue; beta = sumValue * sumValue * alpha; newRatio = Math.max(maxValue / beta, beta / minValue); if (newRatio > minRatio) { sumValue -= nodeValue; break; } minRatio = newRatio; } // Position and record the row orientation. rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); value -= sumValue, i0 = i1; } return rows; } var squarify = (function custom(ratio) { function squarify(parent, x0, y0, x1, y1) { squarifyRatio(ratio, parent, x0, y0, x1, y1); } squarify.ratio = function(x) { return custom((x = +x) > 1 ? x : 1); }; return squarify; })(phi); function d3treemap() { var tile = squarify, round = false, dx = 1, dy = 1, paddingStack = [0], paddingInner = constantZero, paddingTop = constantZero, paddingRight = constantZero, paddingBottom = constantZero, paddingLeft = constantZero; function treemap(root) { root.x0 = root.y0 = 0; root.x1 = dx; root.y1 = dy; root.eachBefore(positionNode); paddingStack = [0]; if (round) root.eachBefore(roundNode); return root; } function positionNode(node) { var p = paddingStack[node.depth], x0 = node.x0 + p, y0 = node.y0 + p, x1 = node.x1 - p, y1 = node.y1 - p; if (x1 < x0) x0 = x1 = (x0 + x1) / 2; if (y1 < y0) y0 = y1 = (y0 + y1) / 2; node.x0 = x0; node.y0 = y0; node.x1 = x1; node.y1 = y1; if (node.children) { p = paddingStack[node.depth + 1] = paddingInner(node) / 2; x0 += paddingLeft(node) - p; y0 += paddingTop(node) - p; x1 -= paddingRight(node) - p; y1 -= paddingBottom(node) - p; if (x1 < x0) x0 = x1 = (x0 + x1) / 2; if (y1 < y0) y0 = y1 = (y0 + y1) / 2; tile(node, x0, y0, x1, y1); } } treemap.round = function(x) { return arguments.length ? (round = !!x, treemap) : round; }; treemap.size = function(x) { return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; }; treemap.tile = function(x) { return arguments.length ? (tile = required(x), treemap) : tile; }; treemap.padding = function(x) { return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); }; treemap.paddingInner = function(x) { return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$1(+x), treemap) : paddingInner; }; treemap.paddingOuter = function(x) { return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); }; treemap.paddingTop = function(x) { return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$1(+x), treemap) : paddingTop; }; treemap.paddingRight = function(x) { return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$1(+x), treemap) : paddingRight; }; treemap.paddingBottom = function(x) { return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$1(+x), treemap) : paddingBottom; }; treemap.paddingLeft = function(x) { return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$1(+x), treemap) : paddingLeft; }; return treemap; } var treemapResquarify = (function custom(ratio) { function resquarify(parent, x0, y0, x1, y1) { if ((rows = parent._squarify) && (rows.ratio === ratio)) { var rows, row, nodes, i, j = -1, n, m = rows.length, value = parent.value; while (++j < m) { row = rows[j], nodes = row.children; for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += (y1 - y0) * row.value / value : y1); else treemapSlice(row, x0, y0, value ? x0 += (x1 - x0) * row.value / value : x1, y1); value -= row.value; } } else { parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); rows.ratio = ratio; } } resquarify.ratio = function(x) { return custom((x = +x) > 1 ? x : 1); }; return resquarify; })(phi); const LABELS = { renderedLength: "Rendered", gzipLength: "Gzip", brotliLength: "Brotli", }; const getAvailableSizeOptions = (options = {}) => { const availableSizeProperties = ["renderedLength"]; if (options.gzip) { availableSizeProperties.push("gzipLength"); } if (options.brotli) { availableSizeProperties.push("brotliLength"); } return availableSizeProperties; }; const SideBar = ({ availableSizeProperties, sizeProperty, setSizeProperty, }) => { const handleChange = (sizeProp) => () => { if (sizeProp !== sizeProperty) { setSizeProperty(sizeProp); } }; return m$1` <aside class="sidebar"> <div class="size-selectors"> ${availableSizeProperties.length > 1 && availableSizeProperties.map((sizeProp) => { const id = `selector-${sizeProp}`; return m$1` <div class="size-selector"> <input type="radio" id=${id} checked=${sizeProp === sizeProperty} onChange=${handleChange(sizeProp)} /> <label for=${id}> ${LABELS[sizeProp]} </label> </div> `; })} </div> </aside> `; }; function ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } function bisector(f) { let delta = f; let compare = f; if (f.length === 1) { delta = (d, x) => f(d) - x; compare = ascendingComparator(f); } function left(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; } return lo; } function right(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; } return lo; } function center(a, x, lo, hi) { if (lo == null) lo = 0; if (hi == null) hi = a.length; const i = left(a, x, lo, hi - 1); return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; } return {left, center, right}; } function ascendingComparator(f) { return (d, x) => ascending(f(d), x); } function number$1(x) { return x === null ? NaN : +x; } const ascendingBisect = bisector(ascending); const bisectRight = ascendingBisect.right; bisector(number$1).center; class InternMap extends Map { constructor(entries, key = keyof) { super(); Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}}); if (entries != null) for (const [key, value] of entries) this.set(key, value); } get(key) { return super.get(intern_get(this, key)); } has(key) { return super.has(intern_get(this, key)); } set(key, value) { return super.set(intern_set(this, key), value); } delete(key) { return super.delete(intern_delete(this, key)); } } function intern_get({_intern, _key}, value) { const key = _key(value); return _intern.has(key) ? _intern.get(key) : value; } function intern_set({_intern, _key}, value) { const key = _key(value); if (_intern.has(key)) return _intern.get(key); _intern.set(key, value); return value; } function intern_delete({_intern, _key}, value) { const key = _key(value); if (_intern.has(key)) { value = _intern.get(value); _intern.delete(key); } return value; } function keyof(value) { return value !== null && typeof value === "object" ? value.valueOf() : value; } function identity$2(x) { return x; } function group(values, ...keys) { return nest(values, identity$2, identity$2, keys); } function nest(values, map, reduce, keys) { return (function regroup(values, i) { if (i >= keys.length) return reduce(values); const groups = new InternMap(); const keyof = keys[i++]; let index = -1; for (const value of values) { const key = keyof(value, ++index, values); const group = groups.get(key); if (group) group.push(value); else groups.set(key, [value]); } for (const [key, values] of groups) { groups.set(key, regroup(values, i)); } return map(groups); })(values, 0); } var e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2); function ticks(start, stop, count) { var reverse, i = -1, n, ticks, step; stop = +stop, start = +start, count = +count; if (start === stop && count > 0) return [start]; if (reverse = stop < start) n = start, start = stop, stop = n; if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; if (step > 0) { start = Math.ceil(start / step); stop = Math.floor(stop / step); ticks = new Array(n = Math.ceil(stop - start + 1)); while (++i < n) ticks[i] = (start + i) * step; } else { step = -step; start = Math.ceil(start * step); stop = Math.floor(stop * step); ticks = new Array(n = Math.ceil(stop - start + 1)); while (++i < n) ticks[i] = (start + i) / step; } if (reverse) ticks.reverse(); return ticks; } function tickIncrement(start, stop, count) { var step = (stop - start) / Math.max(0, count), power = Math.floor(Math.log(step) / Math.LN10), error = step / Math.pow(10, power); return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); } function tickStep(start, stop, count) { var step0 = Math.abs(stop - start) / Math.max(0, count), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), error = step0 / step1; if (error >= e10) step1 *= 10; else if (error >= e5) step1 *= 5; else if (error >= e2) step1 *= 2; return stop < start ? -step1 : step1; } /*! * bytes * Copyright(c) 2012-2014 TJ Holowaychuk * Copyright(c) 2015 Jed Watson * MIT Licensed */ var format_1 = format$1; /** * Module variables. * @private */ var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; var map$1 = { b: 1, kb: 1 << 10, mb: 1 << 20, gb: 1 << 30, tb: Math.pow(1024, 4), pb: Math.pow(1024, 5), }; /** * Format the given value in bytes into a string. * * If the value is negative, it is kept as such. If it is a float, * it is rounded. * * @param {number} value * @param {object} [options] * @param {number} [options.decimalPlaces=2] * @param {number} [options.fixedDecimals=false] * @param {string} [options.thousandsSeparator=] * @param {string} [options.unit=] * @param {string} [options.unitSeparator=] * * @returns {string|null} * @public */ function format$1(value, options) { if (!Number.isFinite(value)) { return null; } var mag = Math.abs(value); var thousandsSeparator = (options && options.thousandsSeparator) || ''; var unitSeparator = (options && options.unitSeparator) || ''; var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; var fixedDecimals = Boolean(options && options.fixedDecimals); var unit = (options && options.unit) || ''; if (!unit || !map$1[unit.toLowerCase()]) { if (mag >= map$1.pb) { unit = 'PB'; } else if (mag >= map$1.tb) { unit = 'TB'; } else if (mag >= map$1.gb) { unit = 'GB'; } else if (mag >= map$1.mb) { unit = 'MB'; } else if (mag >= map$1.kb) { unit = 'KB'; } else { unit = 'B'; } } var val = value / map$1[unit.toLowerCase()]; var str = val.toFixed(decimalPlaces); if (!fixedDecimals) { str = str.replace(formatDecimalsRegExp, '$1'); } if (thousandsSeparator) { str = str.replace(formatThousandsRegExp, thousandsSeparator); } return str + unitSeparator + unit; } const Node = ({ node, backgroundColor, fontColor, onClick, isSelected, onNodeHover, sizeProperty, }) => { const { nodeUid, x0, x1, y1, y0, clipUid, data, originalValue, children = null, } = node; const tspan1Props = {}; const tspan2Props = {}; if (children != null) { tspan1Props.dx = 3; tspan2Props.dx = 3; tspan1Props.y = 13; tspan2Props.y = 13; } else { tspan1Props.x = 3; tspan2Props.x = 3; tspan1Props.y = "1.1em"; tspan2Props.y = "2.3em"; } const handleClickSelection = (event) => { if (window.getSelection().toString() !== "") { event.stopPropagation(); } }; return m$1` <g class="node" transform="translate(${x0},${y0})" onClick=${onClick} onMouseOver=${(evt) => { evt.stopPropagation(); onNodeHover(node); }} > <rect id=${nodeUid.id} fill=${backgroundColor} rx=${2} ry=${2} width=${x1 - x0} height=${y1 - y0} stroke=${isSelected ? "#fff" : null} stroke-width=${isSelected ? 2 : null} > </rect> <clipPath id=${clipUid.id}> <use href=${nodeUid.href} /> </clipPath> <text clip-path=${clipUid} fill=${fontColor} onClick=${handleClickSelection} > <tspan ...${tspan1Props} font-size="0.7em">${data.name}</tspan> <tspan ...${tspan2Props} fill-opacity=${0.7} font-size="0.7em" >${format_1(originalValue[sizeProperty])}</tspan > </text> </g> `; }; const TreeMap = ({ root, layout, color, width, height, onNodeHover, sizeProperty, }) => { const [selectedNode, setSelectedNode] = l(null); const desiredValue = root.originalValue[sizeProperty] * 0.2; //handle zoom of selected node const selectedNodeMultiplier = selectedNode != null ? desiredValue > selectedNode.originalValue[sizeProperty] ? desiredValue / selectedNode.originalValue[sizeProperty] : 3 : 1; // i only need to increase value of leaf nodes // as folders will sum they up const nodesToIncrease = selectedNode != null ? selectedNode.children != null ? selectedNode.leaves() : [selectedNode] : []; const nodesToIncreaseSet = new Set(nodesToIncrease); // update value for nodes root = root.eachAfter((node) => { let sum = 0; const children = node.children; if (children != null) { let i = children.length; while (--i >= 0) sum += children[i].value; } else { sum = nodesToIncreaseSet.has(node) ? node.originalValue[sizeProperty] * selectedNodeMultiplier : node.originalValue[sizeProperty]; } node.value = sum; }); layout(root); // this will make groups by height const nestedDataMap = group(root.descendants(), (d) => d.height); const nestedData = Array.from(nestedDataMap, ([key, values]) => ({ key, values, })); nestedData.sort((a, b) => b.key - a.key); return m$1` <svg xmlns="http://www.w3.org/2000/svg" viewBox=${`0 0 ${width} ${height}`}> ${nestedData.map(({ key, values }) => { return m$1` <g class="layer" key=${key}> ${values.map((node) => { const { backgroundColor, fontColor } = color(node); return m$1` <${Node} node=${node} backgroundColor=${backgroundColor} fontColor=${fontColor} onClick=${() => setSelectedNode(selectedNode === node ? null : node)} isSelected=${selectedNode === node} onNodeHover=${onNodeHover} sizeProperty=${sizeProperty} /> `; })} </g> `; })} </svg> `; }; const Tooltip = ({ node, visible, root, sizeProperty, availableSizeProperties, importedByCache, }) => { const ref = s(); const [style, setStyle] = l({}); const content = d(() => { if (!node) return null; const mainSize = node.originalValue[sizeProperty]; const percentageNum = (100 * mainSize) / root.originalValue[sizeProperty]; const percentage = percentageNum.toFixed(2); const percentageString = percentage + "%"; const uid = node.data.uid; const path = node .ancestors() .reverse() .map((d) => d.data.name) .join("/"); return m$1` <div>${path}</div> ${availableSizeProperties.map((sizeProp) => { if (sizeProp === sizeProperty) { return m$1` <div> <b>${LABELS[sizeProp]}:${" "}${format_1(mainSize)}</b >${" "}(${percentageString}) </div> `; } else { return m$1` <div> ${LABELS[sizeProp]}:${" "} ${format_1(node.originalValue[sizeProp])} </div> `; } })} ${uid && importedByCache.has(uid) && m$1` <div> <div><b>Imported By</b>:</div> ${[...new Set(importedByCache.get(uid).map(({ id }) => id))].map( (id) => m$1` <div>${id}</div> ` )} </div> `} `; }, [node]); const updatePosition = (mouseCoords) => { const pos = { left: mouseCoords.x + Tooltip.marginX, top: mouseCoords.y + Tooltip.marginY, }; const boundingRect = ref.current.getBoundingClientRect(); if (pos.left + boundingRect.width > window.innerWidth) { // Shifting horizontally pos.left = window.innerWidth - boundingRect.width; } if (pos.top + boundingRect.height > window.innerHeight) { // Flipping vertically pos.top = mouseCoords.y - Tooltip.marginY - boundingRect.height; } setStyle(pos); }; const handleMouseMove = (event) => { updatePosition({ x: event.pageX, y: event.pageY, }); }; y(() => { document.addEventListener("mousemove", handleMouseMove, true); return () => { document.removeEventListener("mousemove", handleMouseMove, true); }; }, []); return m$1` <div class="tooltip ${visible ? "" : "tooltip-hidden"}" ref=${ref} style=${style} > ${content} </div> `; }; Tooltip.marginX = 10; Tooltip.marginY = 30; const Chart = ({ layout, root, color, width, height, sizeProperty, availableSizeProperties, importedCache, importedByCache, }) => { const [showTooltip, setShowTooltip] = l(false); const [tooltipNode, setTooltipNode] = l(null); const handleMouseOut = () => { setShowTooltip(false); }; y(() => { document.addEventListener("mouseover", handleMouseOut); return () => { document.removeEventListener("mouseover", handleMouseOut); }; }, []); return m$1` <${TreeMap} layout=${layout} root=${root} color=${color} width=${width} height=${height} sizeProperty=${sizeProperty} availableSizeProperties=${availableSizeProperties} onNodeHover=${(node) => { setTooltipNode(node); setShowTooltip(true); }} /> <${Tooltip} visible=${showTooltip} node=${tooltipNode} root=${root} sizeProperty=${sizeProperty} availableSizeProperties=${availableSizeProperties} importedByCache=${importedByCache} importedCache=${importedCache} /> `; }; let count = 0; class Id { constructor(id) { this._id = id; this._href = createUrl({ hash: id }).href; } get id() { return this._id; } get href() { return this._href; } toString() { return `url(${this.href})`; } } function uid (name) { count += 1; const id = ["O", name, count].filter(Boolean).join("-"); return new Id(id); } function createUrl(options = {}) { const url = new URL(window.location); return Object.assign(url, options); } function initRange(domain, range) { switch (arguments.length) { case 0: break; case 1: this.range(domain); break; default: this.range(range).domain(domain); break; } return this; } function initInterpolator(domain, interpolator) { switch (arguments.length) { case 0: break; case 1: { if (typeof domain === "function") this.interpolator(domain); else this.range(domain); break; } default: { this.domain(domain); if (typeof interpolator === "function") this.interpolator(interpolator); else this.range(interpolator); break; } } return this; } function define(constructor, factory, prototype) { constructor.prototype = factory.prototype = prototype; prototype.constructor = constructor; } function extend(parent, definition) { var prototype = Object.create(parent.prototype); for (var key in definition) prototype[key] = definition[key]; return prototype; } function Color() {} var darker = 0.7; var brighter = 1 / darker; var reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); var named = { aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4, azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000, blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a, burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e, coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c, cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b, darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b, darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc, darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b, darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3, deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969, dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22, fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700, goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f, grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c, indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa, lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6, lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3, lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a, lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899, lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32, linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa, mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371, mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585, midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5, navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000, olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6, palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093, papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb, plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399, red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513, salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee, sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd, slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f, steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8, tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3, white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32 }; define(Color, color, { copy: function(channels) { return Object.assign(new this.constructor, this, channels); }, displayable: function() { return this.rgb().displayable(); }, hex: color_formatHex, // Deprecated! Use color.formatHex. formatHex: color_formatHex, formatHsl: color_formatHsl, formatRgb: color_formatRgb, toString: color_formatRgb }); function color_formatHex() { return this.rgb().formatHex(); } function color_formatHsl() { return hslConvert(this).formatHsl(); } function color_formatRgb() { return this.rgb().formatRgb(); } function color(format) { var m, l; format = (format + "").trim().toLowerCase(); return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0x